- 来源:Root-Me
- 题型:Cracking
- 题目:ELF - Fake Instructions
- 分数:15 Points
前言
【Cracking : ELF C++ - 0 protection】 的进阶篇。
开启挑战后下载了 ch4.zip
,解压后得到文件 crackme
。
题目已经提示了这是用 gcc 编译的 ELF 32-bit 文件,即使没提示,也可在 Linux 通过命令 file crackme
查看:
试错
把文件 crackme
上传到 Linux ,执行命令 chomd u+x crackme
赋予脚本执行权限。
然后执行命令 ./crackme
,提示使用方式为: (*) -Syntaxe: ./crackme [password]
根据提示再次执行命令 ./crackme www.exp-blog.com
(其中 www.exp-blog.com
是随意输入的密码)
此时会用法语提示密码错误:
Vérification de votre mot de passe..
le voie de la sagesse te guidera, tache de trouver le mot de passe petit padawaan
源码分析
有了这些提示,我们可以开始从源码缩小并定位密码判定语句的位置。
在 Windows 使用 IDA 工具反汇编此文件,通过 Search -> text… 查找密码错误的提示关键字 padawaan
,
在数据段找到变量名 aLeVoieDeLaSage
,右击,选择 Jump to xref to operand...
跳转到引用位置。
当前跳转到 RSA
函数,未发现的比较关键代码。
再次右击 RSA
函数,选择 Jump to xref to operand...
跳转到引用位置。
这次跳转到 WPA
模块的关键位置,在执行字符串比较语句 call _strcmp
之后:
test eax, eax
: 利用eax
寄存器的值对ZF
标志位置位jnz
: 当ZF == 0
时走blowfish
红色分支,当ZF != 0
时走RSA
绿色分支
而 RSA
绿色分支是我们前面利用密码错误的提示逆向找到的分支。
换言之 blowfish
红色分支才是密码正确时会走的分支,即我们的目标分支。
但是查看 blowfish
分支的源码并不能直接看出什么。
因此这里转换思路:尝试让脚本跑起来,再通过 debug 查看内存值,看看能否找到密码。
调试代码
在 Linux 通过 gdb
工具运行脚本,执行命令 gdb crackme
打开调试模式,
找到前面源码分析时的关键位置, 即 WPA
模块的 call _strcmp
方法:地址为 0x80486f5
。
执行命令 break *0x80486f5
在此处添加断点。
再执行命令 r www.exp-blog.com
开始调试代码,代码在断点位置中断。
由于此时正在调用 strcmp
函数,可以通过命令 x/12wx $esp
和 x/s 地址值
查看 esp 栈指针指向的函数内存值,借此检查真正的密码是否被传参到 strcmp
函数。
虽然可以找到其中的一个参数为输入的密码 www.exp-blog.com
,但是验证过另一个可疑的参数 _0cGjc5m_.5\r\nÇ8CJ0À9
并不是真正的密码,估计是经过某种加密处理的字符串。
修改内存
此时我们剩下的途径就是查看 blowfish
分支会执行什么。
但是由于我们掌握不到正确的密码,因此无法令代码通过正常的途径走到 blowfish
分支。
不过我们可以直接修改内存达到我们的目的。
首先执行 ni
命令使得代码单步执行到 test eax, eax
语句,然后通过命令 info reg
查看当前所有寄存器的值,发现 eax
寄存器的值为 0x1
。
因为 0x1 AND 0x1 = 0x1
,所以在执行 test eax, eax
后 ZF
标志位会被置 1 ,即通过 jnz
或 jne
语句判定后都不会跳转到 blowfish
分支。
为了使得代码走向 blowfish
分支,此时我们只需要改变 eax
寄存器的值为 0 即可:
执行命令 set $eax=0
,再次通过命令 info reg
查看当前所有寄存器的值,发现 eax
寄存器的值被置为 0x0
。
此时直接执行命令 c
使得代码执行到最后就可以执行 blowfish
分支了,发现其作用就是打印真正的密码。
验证获得的密码 liberté!
,挑战成功。
注:这个密码直接提交到挑战即可,输入到脚本是没用的,因为根据前面分析可以知道,无论输入什么到这个脚本,均是判定密码错误。
答案下载
flag 下载后的 flagzip 的文件需要手动更改后缀为
*.zip
,然后解压即可(为了避免直接刷答案)