5

【Root-Me】 ELF - Fake Instructions

 2 years ago
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.
neoserver,ios ssh client

Fake Instructions



Cracking : ELF C++ - 0 protection】 的进阶篇。

开启挑战后下载了 ch4.zip ,解压后得到文件 crackme

题目已经提示了这是用 gcc 编译的 ELF 32-bit 文件,即使没提示,也可在 Linux 通过命令 file crackme 查看:

01.png

把文件 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... 跳转到引用位置。

02.png

当前跳转到 RSA 函数,未发现的比较关键代码。

再次右击 RSA 函数,选择 Jump to xref to operand... 跳转到引用位置。

03.png

这次跳转到 WPA 模块的关键位置,在执行字符串比较语句 call _strcmp 之后:

  • test eax, eax : 利用 eax 寄存器的值对 ZF 标志位置位
  • jnz : 当 ZF == 0 时走 blowfish 红色分支,当 ZF != 0 时走 RSA 绿色分支
04.png

RSA 绿色分支是我们前面利用密码错误的提示逆向找到的分支。

换言之 blowfish 红色分支才是密码正确时会走的分支,即我们的目标分支。

但是查看 blowfish 分支的源码并不能直接看出什么。

因此这里转换思路:尝试让脚本跑起来,再通过 debug 查看内存值,看看能否找到密码。

05.png

在 Linux 通过 gdb 工具运行脚本,执行命令 gdb crackme 打开调试模式,

找到前面源码分析时的关键位置, 即 WPA 模块的 call _strcmp 方法:地址为 0x80486f5

执行命令 break *0x80486f5 在此处添加断点。

06.png

再执行命令 r www.exp-blog.com 开始调试代码,代码在断点位置中断。

由于此时正在调用 strcmp 函数,可以通过命令 x/12wx $espx/s 地址值 查看 esp 栈指针指向的函数内存值,借此检查真正的密码是否被传参到 strcmp 函数。

虽然可以找到其中的一个参数为输入的密码 www.exp-blog.com ,但是验证过另一个可疑的参数 _0cGjc5m_.5\r\nÇ8CJ0À9 并不是真正的密码,估计是经过某种加密处理的字符串。

07.png

此时我们剩下的途径就是查看 blowfish 分支会执行什么。

但是由于我们掌握不到正确的密码,因此无法令代码通过正常的途径走到 blowfish 分支。

不过我们可以直接修改内存达到我们的目的。

首先执行 ni 命令使得代码单步执行到 test eax, eax 语句,然后通过命令 info reg 查看当前所有寄存器的值,发现 eax 寄存器的值为 0x1

因为 0x1 AND 0x1 = 0x1 ,所以在执行 test eax, eaxZF 标志位会被置 1 ,即通过 jnzjne 语句判定后都不会跳转到 blowfish 分支。

08.png

为了使得代码走向 blowfish 分支,此时我们只需要改变 eax 寄存器的值为 0 即可:

执行命令 set $eax=0 ,再次通过命令 info reg 查看当前所有寄存器的值,发现 eax 寄存器的值被置为 0x0

09.png

此时直接执行命令 c 使得代码执行到最后就可以执行 blowfish 分支了,发现其作用就是打印真正的密码。

10.png

验证获得的密码 liberté! ,挑战成功。

注:这个密码直接提交到挑战即可,输入到脚本是没用的,因为根据前面分析可以知道,无论输入什么到这个脚本,均是判定密码错误。


flag 下载后的 flagzip 的文件需要手动更改后缀为 *.zip,然后解压即可(为了避免直接刷答案)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK