Minhal's Blog

Back

2020 scuctf 如期举行,比赛也相当激烈。正好要写官方wp,顺便更新到博客吧。

真正的签到#

出题思路#

本身作为签到题就没必要太刁难人,主要考察脱压缩壳(re选手基础技能),正好在4月的脱壳分享会也说了要出一道这种题。脱完壳后就打算搞个简单的加减乘除,但是还是出题时候考虑不周,出现了多解的情况。(按照正常思路一般都是一个解。)

问题主要出在当时做了一个除法的操作,因为C语言中5/2 与4/2都为2。

解题方法#

法1#

  • 第一步,查壳,发现为upx。

    1

  • 直接可以用脱壳软件脱壳也可esp定律等手动脱壳。

  • 脱壳后分析代码。

    2

  • 直接写脚本

    #include<stdio.h>
    #include<string.h>
    int main(){
      	char fstr[17] = "pbm`KkL`dKQ2KeJLd";
      	char theflag[17];
    	char flag[17] = "scu_ctf_f4k3_f14g";	
    	int i = 0;       
        for(i = 0; i < 17; i++)
        theflag[i] = fstr[i]*2-flag[i]; 
        for(i = 0; i < 17; i++)
        printf("%c",theflag[i]);      
      }
    c

法2#

  • 前面步骤一直,后面直接angr梭哈
import angr
p = angr.Project('sign.exe', auto_load_libs=False)
st = p.factory.call_state(addr=0x401520, add_options=angr.options.unicorn)
sim = p.factory.simgr(st)
sim.explore(find=0x40155e, avoid=0x40156c)
print(sim.one_found.posix.dumps(0))
python

这个地方就可以看出,有多解情况了。

太空大战#

出题思路#

这题是由God sun出的,大概主要考察一个.net,加之让比赛变的更有趣一点,放了个小游戏上去。只要打完180个灰机(一个不落)控制台就会输出flag

(180个飞机,无需逆向,轻轻松松就可以打败。

解题方法#

  • 关键代码在assets/bin/Date/Managed/Assembly-CSharp.dll
  • ⽤.NET Reflector打开分析

3

  • 经过分析可以得知,每击落一架分级,调用一次这个关键方法。由代码可以看到总共需要摧毁了180个。(其实总共也就180个)

  • 写解题脚本

    import hashlib
    mask =[49552,26516,15988,29987,52902,33151,8086,39920,3604,21497,19862,12268,50822,26111,35391,20661,6370,14029,26707,42890,19391,13836,61102,38705,45159,12927,47794,39183,20776,44532,18925,4854,60596,11941,28994,11166,57586,48918,13199,42006,62781,31480,50464,53893,21233,61456,55842,46591,10574,45253,50991,44866,45945,17105,27273,18925,41001,64310,51846,46279,14977,61079,26330,1192,61190,38989,36161,17001,38576,49567,55929,31759,54550,12759,13756,60929,36365,27308,57132,42483,42263,57086,55839,13568,37191,18388,34592,4189,65492,24673,27016,6941,33229,	4180,35454,64874,36708,22948]
    l = len(mask)
    secret = "jFEQ6xFkUxKGzUbn"
    
    for i in range(1,181):
        secret = hashlib.md5((secret+str(mask[i%l])).encode()).hexdigest()
        if '6a37460f25c719a4' in secret:
            print (secret[0:16])
    python
  • 注意这里很多选手以为只调用一次,所以直接拿180%98 去处理,算出来的是错的。

PY 交易#

出题思路#

这个题目出题主要想考察一下python的逆向,校内打校外比赛的不多,见得题目相对较少。所以本着拓宽学习的目的,出了这道还原字节码的题目。相对来说这道题不是太难,通过相关博客搜索,然后一步步分析还原,还原后dis检验。

解题方法#

  • 首先直接还原python代码就好了,还原结果如下

  • 接着就是逆向分析,写解题脚本

法1#

法2#

  • 题目前两位和第八位无法解除,题目中已经提示具体字符

ONIbase64#

出题思路#

本道题主要就是考察一个ollvm平坦化。也没想到这么惨烈。

解题方法#

  • 文件拉到最后就可以看到编译器地址,直接把它pull下来,编译.s文件得到可执行文件。

  • 拖入IDA分析,是个标准的平坦化。

    6

  • 参考<https://github.com/pcy190/deflat >去除平坦化

  • 然后直接F5写解密脚本

easy_re&easy_base#

出题思路#

既然要搞花样,当然少不当今最火的iot。采用腾讯TencentOS tiny 官方定制IoT开发板EVB_LX(暂时是限量的)编译环境: https://github.com/Tencent/TencentOS-tiny两个题目,都是考察找到被替换的base64密码表,由于考虑到直接上base有点难,所以出了一个easy_re过渡。

两个题目替换都涉及四段字符如下(把初始密码表拆分为四段):

“ABCDEFGHIJKLMNOPQRSTUVWXYZ” “abcdefghijklmnopqrstuvwxyz” “0123456789” ”+/”

easy_re是改变了这四段字符压栈顺序。没想到ida太过于智能化,显示结果即是正确压栈顺序。

easy_base考察偏难了,主要是对这四段字符进行了一些变换,如果逆向分析的话需要学习risc-v指令集。

当然,这两个题最简单的方法是把程序放入对应开发板里,他相应的串口也会输出字母表。

做题过程中也发现一些选手拿到题目直接猜测arm架构,拿着ida 当arm分析,还原的内容是错的,无从下手。如果拿到文件后File一下也会知道是risc-v架构。不至于走偏。

解题方法#

  • 首先,ida默认不支持risc-v,所以需要下载相关插件。https://github.com/lcq2/riscv-ida

  • 然后,ida打开分析,直接就有正确的字母表压栈顺序,(原本是想让选手分析简单指令来确定或者爆破)

    4

  • 得到 字母表就很容易解出来了

import base64
str1 = "PalXPrhnOrLZT6PVQJ1oNr9dSqDVTbo=="
string1 =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+/abcdefghijklmnopqrstuvwxyz"
string2 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print(base64.b64decode(str1.translate(str.maketrans(string1, string2))))
python
  • easy_base 的话就需要分析指令得出具体操作或者直接开发板跑一下得到输出

  • 看到大多数人解题无果,比赛最后放出了一个risc-v 64位的附件(代码一样),通过docker跑即可得到table。

    5

  • 然后直接解密得到flag

import base64
str1 = "UoH+U/DJV/YlQdUOU94JPYxJgdHMUWK="
string1 =
"a0b1c2d3e4f5g6h7i8j9ZYXWVUTSRQPON+klmnopqrABCDEFGHIJKLM/stuvwxyz"
string2 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print(base64.b64decode(str1.translate(str.maketrans(string1, string2))))
python
  • 如果对题目感兴趣的,可以之后再研究。我附上题目主文件源代码

小结#

由于是普通校赛,题目也没出过分难,个人感觉难以把握还算可以。这次题目主要也本着打破传统scuctf 常规题目,一丢丢小小的创新。 .NET,risc-v,ollvm,apk,python等。即使这些可能在全国ctf中是常见题目,但是感觉校内还是几乎没出的。比赛过程中也发生了很多趣味东西,比如第一题一题多解,flag设置时候多加了空格导致选手提交报错等好多问题。

总之希望scuctf越来越有趣,参与人数越来越多吧!

2020 geekgame(scuctf) Reverse出题思路&writeup
https://minhal.me/blog/geekgamescuctf
Author Minhal
Published at 2020年5月23日
Comment seems to stuck. Try to refresh?✨