点击蓝字 关注我们
日期: 2024-07-15
作者: Mr-hello
介绍: 迷失在知识的海洋里。
0x00 前言
实在不知道文章写什么内容了,刚好之前的某天,有人在群里发了一道逆向题目,当时就做了出来,然后简单整理了一下思路,刚好趁着这次写公众号文章,再重新整理一下当时的做题思路吧。
0x01 题目分析
拿到题目之后,使用反编译工具打开,发现只能看到部分 LOAD
段代码,怀疑是使用了加壳技术,后面使用 winhex
打开后确认是使用 UPX
进行了加壳。
后面还由于自己电脑上的 upx
版本过于老旧,脱壳失败了,刚好更新了一下自己的工具,使用最新版成功脱壳。
然后再次使用反编译工具,打开分析。
可以从关键代码处发现,该程序会对 flag
分为四个部分进行校验,最后进行了一次比较,先对比较算法进行分析,可得出结论是 MD5
算法。
梳理一下该题目逻辑,先对我们的四部分输入做某种判断,然后再对该四部分合并之后,进行 MD5
加密,并且对比。那么本题目的解题方式,就必须分别研究四部分的运算逻辑。后面在分别研究时发现,第二、三、四部分的运算,均为基础运算,可通过 Z3
求解器进行爆破得到正确输入。
在分析第一部分运算时,发现无法进行正确的伪代码查看,于是修改一下函数的起始地址,然后调一下堆栈平衡即可成功反编译,发现该部分运算只是进行了一次简单的减法运算。
最后使用 Z3
写脚本进行解决即可,写脚本时注意定义约束变量时,不要设置为64
。
from z3 import *
s = Solver()
a1 = BitVec('part1',32)
s.add(a1 + 1380855784 == 907301700)
a2 = BitVec('part2',32)
s.add((a2 | 0x8E03BEC3) - 3 * (a2 & 0x71FC413C) + a2 == -1876131848)
a3 = BitVec('part3',32)
s.add(a3 <= 0x10000000,4 * ((~a3 & 0xA8453437) + 2 * ~(~a3 | 0xA8453437)) + -3 * (~a3 | 0xA8453437) + 3 * ~(a3 | 0xA8453437) - (-10 * (a3 & 0xA8453437) + (a3 ^ 0xA8453437)) == 551387557)
a4 = BitVec('part4',32)
s.add(a4 <= 0x10000000,11 * ~(a4 ^ 0xE33B67BD) + 4 * ~(~a4 | 0xE33B67BD) - (6 * (a4 & 0xE33B67BD) + 12 * ~(a4 | 0xE33B67BD)) + 3 * (a4 & 0xD2C7FC0C) + -5 * a4 - 2 * ~(a4 | 0xD2C7FC0C) + ~(a4 | 0x2D3803F3) + 4 * (a4 & 0x2D3803F3) - -2 * (a4 | 0x2D3803F3) == -837785892)
if s.check() == sat:
print(s.model())
最终分别输入四个部分,即可得到 flag
输出。
0x02 结束语
虽然对于本题目来说,实现逻辑较为简单,但是利用该题目也算是成功的让作者再次运用了 Z3
求解器,于是便随手记下来,要想知识不被丢掉,唯有不断运用罢了。
点此亲启
原文始发于微信公众号(宸极实验室):『CTF』最近遇到的一道逆向题目
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论