DDCTF 2019 逆向题writeup re1-3

 

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位

DDCTF 2019 逆向题writeup re1-3_第1张图片

sub_1000011D0:包含sub_100001F60、sub_100001F00

sub_100001F60:一个函数表,通过十六进制数F1-F8标识八个函数,实际只用到F0 F8 F2 F6 F7 F3。

DDCTF 2019 逆向题writeup re1-3_第2张图片

 

 

F0:10001DC5的jump需要读汇编,作用是F0后两位赋给a1(见后文函数表的绿框内数据),指针后移6

DDCTF 2019 逆向题writeup re1-3_第3张图片

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的函数表:(绿框表示字符校验值,黑框表示终止符,红框表示成功失败位)

DDCTF 2019 逆向题writeup re1-3_第4张图片

执行顺序是:(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,这次想用但是环境没搭好,搭环境调脚本到比赛结束。。。。

 

你可能感兴趣的:(CTF,write,up,逆向,python)