我有一个用于构建rop代码的赋值,该代码使用printf
寄存器中的值调用edx
。
我被困住了。我知道printf
功能的地址,我有工具可以查找小工具。
我正在尝试构建一个类似于:
的堆栈someROPCode,printf_address,ret_address,ropCodeThatWrite_EDX_Value(printf argument)。
我试过:someROPCode = add esp 0xc,re
t(跳过printf
func,这样我就可以在堆栈上写edx
个值了
ret_address=doesn't matter
ropCodeThatWrite_EDX_Value
=我想过类似:push eax
,push edx
,ret
(我不能仅使用push edx
,因为我认为这会导致无限循环(我是新来的)但现在我被卡住了(很明显这不是那种方式)。
有什么想法吗?
答案 0 :(得分: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
。我在附近发现了一对这样的一对,偏移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
我希望这足以说明这个想法,以便您能够找到适合您特定设置的解决方案。