【问题标题】:how to print register value using rop (return oriented programming)?如何使用 rop(面向返回的编程)打印寄存器值?
【发布时间】:2013-04-04 08:44:14
【问题描述】:

我有一个任务来构建调用 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 edx, ret(我不能只使用push edx,因为我认为它会导致无限循环(我是新手)但现在我被卡住了(很明显这不是办法)。

有什么想法吗?

【问题讨论】:

    标签: assembly x86 buffer-overflow


    【解决方案1】:

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

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

       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。我在附近找到了这样一对,偏移量2e6C1。显然call 不会返回到我们的代码,因此它会在完成打印后执行未定义的事情(它很可能会崩溃)。如果这让您感到困扰,您将不得不找到更合适的代码片段。不要忘记将 C 库的加载地址添加到找到的偏移量中。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-13
      • 2011-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多