Pinguw
Articles10
Tags3
Categories2

Categories

Archive

去OLLVM平坦化([SUCTF2019]hardCPP)

去OLLVM平坦化([SUCTF2019]hardCPP)

去OLLVM平坦化([SUCTF2019]hardCPP)

用ida打开是这样

Untitled _2_.png

Untitled _3_.png

十分有十二分的平坦化痕迹,

上次强网杯遇到过,但是因为当时没装好环境,deflat.py跑不出来,遗憾放弃。

这次又碰见不想再回避,打开这个网址把脚本装下来,https://github.com/Pure-T/deflat,看readme,要先装一个angr库(这个库在做VM虚拟机类题,写解析器脚本的时候也会很有用,以后可能再写

1
pip install angr

Untitled _4_.png

下载时间可能会有点长,

Untitled _5_.png

官方说的是用8.19.4.5版本,实际较新版本依然可用,

装好后用以下指令去平坦化:

1
2
python deflat.py hardCpp 0x4007E0   
#python + deflat.py + 文件名 + 起始地址(基本就是main函数的地址)

然而出错:

Untitled _7_.png

回看readme,

Untitled _6_.png

下载那个graph.py然后改名为am_graph.py ,将其与deflat.py放在同一目录下,

Untitled _8_.png

再次运行相同命令:

1
2
python deflat.py hardCpp 0x4007E0   
#python + deflat.py + 文件名 + 起始地址(基本就是main函数的地址)

期间可能会出现大量类似警告:

Untitled _9_.png

不要害怕,只要最后是这样就好:

Untitled _10_.png

将recovered的文件再放进ida里面看:

Untitled _11_.png

Untitled _12_.png

成功!


下面就是逆向环节了

也有部分去平坦化操作

Untitled _13_.png

首先排除上面这两个循环有用,

Untitled _14_.png

看到这一坨函数不要怕,其实就是c++里面的奇奇怪怪的东西(好像叫lambda表达式),来看看他们到底是干嘛的,

在对各函数分析的过程中发现在0x401310、0x4014E0和0x4016C0依然有平坦化,再跑脚本去一下,

1
python deflat.py hardCpp_recovered 0x401310

0x401310:

Untitled _15_.png

再跑一遍

1
python deflat.py hardCpp_recovered_recovered 0x4016C0

0x4016C0:

Untitled _16_.png

再跑一遍:

1
python deflat.py hardCpp_recovered_recovered_recovered 0x4014E0

0x4014E0:

Untitled _17_.png

得到hardCPP_recovered_recovered_recovered_recovered 这次再放进ida并改名:

接下来就是搞清func1、func2、func3的功能:

其中两个就是是return第二个数据,另一个是add,

把这几个函数简化成表达式:

Untitled _18_.png

是不是已经非常清晰了!

整理一下:

1
v18 = (3 * (18 ^ input[i - 1 + v21]) + 2) ^ ((v21 ^ input[i]) + (input[i - 1 + v21] % 7))

从前面看出:v21大概是0 (真的是大概,当时我也不太确定)

然后等式左边的v18就是enc[i]那么这个算法显然可逆:

把函数开头的md5解密一下:

Untitled _19_.png

Untitled _20_.png

那么flag(input)的第一位是‘#’

好了可以写解密代码了:

1
2
3
4
5
6
7
8
9
10
enc = [0xF3, 0x2E, 0x18, 0x36, 0xE1, 0x4C, 0x22, 0xD1, 0xF9, 0x8C, 0x40, 0x76, 0xF4, 0x0E, 0x00, 0x05, 0xA3, 0x90, 0x0E, 0xA5]

input = '#'

k = len(input)

for j in range(len(enc)):
input += chr(((enc[j] ^ ((ord(input[j]) ^ 18) * 3 + 2)) - (ord(input[j]) % 7)) & 0xff)

print(input)

flag:

Untitled _21_.png

flag{mY-CurR1ed_Fns}

Author:Pinguw
Link:https://pinguw.github.io/2024/03/26/Reverse/LLVM/
看完了吗,再去看看博主的其他文章叭:)