1

我有一个任务来构建使用寄存器printf内的值调用的 rop 代码edx

我被困住了。我知道printf函数的地址,并且我有一个工具可以找到小工具。

我正在尝试构建一个看起来像这样的堆栈:

someROPCode、printf_address、ret_address、ropCodeThatWrite_EDX_Value(printf 参数)。

我试过:someROPCode = add esp 0xc,ret(跳过printf函数,这样我就可以edx在堆栈上写值)

ret_address=doesn't matter

ropCodeThatWrite_EDX_Value=我想到了类似的东西:push eax,,push edxret我不能使用只是push edx因为我认为它会导致无限循环(我是新手)但现在我被卡住了(很明显这不是办法)。

有任何想法吗?

4

1 回答 1

2

ROP 用于绕过不可执行的堆栈。为了成功利用,还需要绕过其他安全措施。对于本练习,让我们严格关注 ROP,并假设您有一个没有 ASLR 等的简单设置。特别是我们假设您可以轻松访问堆栈指针和函数地址。

我们想调用printf("%d\n", edx). 使用普通的 32 位 x86 cdecl 调用约定,我们需要堆栈中的这两个参数。格式化字符串很简单,但我们必须edx进入内存。由于我们无法编写任何代码,我们需要找到为我们执行此操作的现有指令。C 库是一个不错的选择。找出合适的代码是困难的部分。使用objdump我发现了以下有希望的片段:

   2e535:       89 54 24 04             mov    DWORD PTR [esp+0x4],edx
   2e539:       ff 55 14                call   DWORD PTR [ebp+0x14]

这会将edx堆栈放在正确的位置并通过函数指针调用函数。一定是我的幸运日,因为所说的指针是使用寻址ebp的,并且很容易设置它的值,因为标准函数结尾经常这样做pop ebp; ret。我在附近找到了这样一对,在 offset 2e6C1。显然call不会返回到我们的代码,因此它会在完成打印后做未定义的事情(它很可能会崩溃)。如果这让您感到困扰,您将不得不找到更合适的代码片段。不要忘记将 C 库的加载地址添加到您找到的偏移量中。

因此所需的堆栈布局如下所示:

  • esp+00h: 地址pop ebp; ret
  • esp+04h: (偏移esp+00h地址的地址)printf-0x14
  • esp+08h:edx入栈并调用函数指针的代码地址
  • esp+0Ch: esp+18h(格式字符串的地址)
  • esp+10h: 占位符edx
  • esp+14h: 地址printf
  • esp+18h: 格式字符串%d\n

我希望这能很好地说明这个想法,以便您可以提出适合您特定设置的解决方案。

于 2013-04-13T01:30:20.980 回答