Re1 windows reverse 1
Upx壳,用工具脱壳。静态分析:
主流程很简单,用户输入input经过sub_401000函数处理后与DDCTF{reverseME}进行比较。
Sub_401000:
看汇编,函数逻辑就是,根据用户输入的字符的ascii码,读取byte_402FF8对应下标的字符。
byte_402FF8是一个倒序的Ascii码可见字符表。00403018-00402FF8=32,32就是可见字符表的第一个字符的ascii码。
写出脚本:
a=[]
flag="DDCTF{reverseME}"
for i in range(32,127):
a.append(chr(i))
a.reverse()
for i in range(len(flag)):
for j in range(len(a)):
if a[j]==flag[i]:
print(chr(j+32),end="")
脱壳以后无法动调、无法运行,怀疑是需要修复什么的,还不太会,所以只用了静态分析。
Re2 windows reverse 2
Aspack壳,XVolk通用脱壳机可以完美脱,可调试、可运行。
IDA+F5静态分析:
sub_4011F0:输入合法性校验,长度为非零偶数,字符范围0-9、A-Z
sub_401240:将输入2位为一组,视为十六进制,转换为十进制数,传给sub_401000。
sub_401000:base64
最后跟reverse+比较
Py脚本:
import base64
a="reverse+"
byte=base64.b64decode(a.encode('utf-8'))
print(byte)
for i in range(len(byte)):
print(str(hex(byte[i])[-2:]).upper(),end="")
Re3 confused
IOS逆向,第一次逆IOS,解压confused.app\Contents\MacOS目录下有个xia0Crakeme,IDA打开。
checkCode:主校验函数,限制输入前缀”DDCTF{“,后缀”}”,中间18位
sub_1000011D0:包含sub_100001F60、sub_100001F00
sub_100001F60:一个函数表,通过十六进制数F1-F8标识八个函数,实际只用到F0 F8 F2 F6 F7 F3。
F0:10001DC5的jump需要读汇编,作用是F0后两位赋给a1(见后文函数表的绿框内数据),指针后移6
F8:字母向后偏移2位,其他字符不变,指针后移1
F2:校验输入,标志位*(a1+16)置1,指针后移1
F6:输入校验成功,标志位*(a1+16)置0,无事发生;输入校验失败,跳转到F7 00处,打印”失败”字样。指针后移2
F7:将后一位的值传给*(a1+176)并return,成功就是1,失败就是0,指针后移5
F3:终止符
sub_100001F00:逐位读取loc_100001984的函数表,遇到F3之前,循环执行sub_100001E50
sub_100001E50:根据当前取值字符F0-F8,执行相应函数,作用类似switch case语句。
loc_100001984的函数表:(绿框表示字符校验值,黑框表示终止符,红框表示成功失败位)
执行顺序是:(F0 -> F8 -> F2 -> F6) x18次 -> F7 -> F3
作用是:将绿框字母字符向后偏移两位,非字母不变,再与用户输入比较。
Python脚本:
a=[0x66,0x63,0x6A,0x6A,0x6D,0x57,0x6D,0x73,0x45,0x6D,0x72,0x52,0x66,0x63,0x44,0x6A,0x5F,0x65]
for i in range(len(a)):
print(chr(a[i]+2),end="")
Re4 obf
没做出来。看CFG图有点像ollvm混淆,之前研究的时候跑通了TSRC-bird的脚本Deflat.py,这次想用但是环境没搭好,搭环境调脚本到比赛结束。。。。