• 如果您想对本站表示支持,请随手点击一下广告即可~
  • 本站致力于提供原创、优秀的技术文章~
  • 有任何疑问或建议 均可以在站点右侧栏处 通过各种方式联系站长哦~
  • CTF – RootMe解题报告 [Cracking : ELF – Ptrace]

    渗透测试 EXP 77阅读 0评论

    挑战入口:Root-Me(https://www.root-me.org/en/Challenges/Cracking/ELF-Ptrace)
      分类目录:Link to …(http://exp-blog.com/2019/01/02/pid-2597/4/)

    前言

    题目叫 Ptrace ,这个单词是 process 和 trace 的简写,直译为进程跟踪,但是这个翻译跟解题没半毛钱关系。。。

    其实这题和【Cracking : PE – 0 protection】如出一辙,区别在于:

    • 加了个壳
    • 平台从 Windows 变成了 Linux

    试错

    开启挑战后下载了文件 ch3.bin ,在 Linux 直接运行,随便输入一个密码,提示错误。

    尝试使用 gdb 工具进行调试,执行命令 gdb ch3.bin 进入调试模式。

    执行命令 layout asm 打印汇编源码,再执行命令 r 开始调试,但是程序并未按正常流程执行,而是直接报错:

    Debugger detecté ... Exit (检测到调试器,退出程序)

    很明显这程序被加壳了,看来要先找到加壳位置绕过去。

    源码分析

    在 Windows 使用 IDA 打开文件 ch3.bin ,在 main 函数的入口附近发现这样的一块代码:

    不难发现 jns 的其中一个跳转分支是正常的代码执行模块,换言之另一个分支就是检测调试器的模块,亦即这就是加壳位置的入口。

    那么要绕过也不难,在调试代码的时候,即时修改寄存器 eax 的内存值,改变 SF 符号位,从而诱导 jns 跳转到正常执行分支即可。


    继续使用 IDA 分析其他部分的代码,通过 Search -> text … 搜索前面运行代码时得到的关键字 Wrong password

    直接就找到了判断输入密码是否正确的模块。

    不难发现,这里做了 4 次连续比较,每次都是比较两个变量的值,只要其中一次 al != dl 则跳转到 Wrong password 分支。

    由此可以推测:

    • 程序是逐字符比较密码的
    • 密码只有 4 个字符

    那么只要在这 4 个位置做断点,就能把密码字符逐个找出来了。

    代码调试

    回到 Linux 的 gdb 调试器,找到加壳位置 ptrace ,先加一个断点:break *0x8048418

    在找到 4 个比较密码字符的位置,加 4 个断点:

    • break *0x80484a3
    • break *0x80484b2
    • break *0x80484bf
    • break *0x80484ce

    执行命令 r 开始调试,程序在第一个断点位置 test eax, eax 中断了。

    输入命令 info reg 查看此时所有寄存器的值,发现 eax = -1

    按照前面试错的流程,若继续向下执行, test eax, eax 会令符号位 SF = 1 ,从而使得代码流转到 Debugger detecté ... Exit 的分支。

    为了绕过它,此时可以直接执行命令 set $eax=0 修改寄存器的值,

    这样执行 test eax, eax 语句之后就可以使得符号位 SF = 0 ,从而流转到正常的代码分支了。

    修改 eax 寄存器的值后,输入命令 c 继续执行代码,提示输入密码,说明我们成功绕过了加壳。

    这里随便输入一个密码 exp-blog.com ,代码流转到下一个断点,即比较第一个密码字符的地方 cmp %al, %dl

    不妨查看一下 aldl 变量的值:

    输入命令 p/c $al 查得 al 为字符 e ,输入命令 p/c $dl 查得 dl 也为字符 e

    说明我的运气还是很好的,第一个密码字符蒙对了。

    p/c 命令解析:p 表示打印变量值,c 表示按字符格式输出。

    输入命令 c 继续执行代码,代码流转到下一个断点,即比较第二个密码字符的地方 cmp %al, %dl

    输入命令 p/c $al 查得 al 为字符 a ,输入命令 p/c $dl 查得 dl 为字符 x

    这次运气就没那么好了,不过此时已经可以知道 al 存储的就是真正的密码,而 dl 存储的是我们输入的密码。

    至此我们已经知道真正密码的前两个字符为 ea ,因此我们可以通过逐字符构造密码,重复前面的步骤,让程序不断流转到到下一个判断分支,从而获得完整的密码。

    最终试出来的密码是 easy ,完成挑战。


    转载请注明:EXP 技术分享博客 » CTF – RootMe解题报告 [Cracking : ELF – Ptrace]

    喜欢 (0) 分享 (0)
    发表我的评论
    取消评论

    表情

    Hi,您需要填写昵称和邮箱!

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址