【Root-Me】 ELF - Fake Instructions
source link: https://exp-blog.com/safe/ctf/rootme/cracking/elf-fake-instructions/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Fake Instructions
【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
,然后解压即可(为了避免直接刷答案)
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK