ROP的问题点
ROP需要一个较大的溢出缓冲区
因为只包含一些细分的小指令,要发送的数据不可避免的增加
如果在srack返回地址下没有较大的溢出,就会很糟糕
如果没有足够的溢出缓冲区该怎么办?
stack pivot
溢出量问题绕过 - stack pivot
stack pivot
使用ret2plt等将后续ROP加载到bss(适当区域)
通过pop ebp; ret来调整EBP寄存器
通过leave; ret来任意更改ESP
- leave是「mov esp, ebp; pop ebp」之类的值
bss作为stack继续ROP
stack pivot的注意事项
使用bss作为stack发动ROP,可能会失败
- 调用system()之前出现SIGSEGV
- 调用system()时也可能出现SIGSEGV
这是因为(后续ROP使用的GOT等)必要的变量被破坏,以及跳到stack等原因
- 因为read/write时,系统内的dl_fixup函数对stack做了很好的保护
pivot使用的stack,应该设置在.bss的中间,而不是靠近顶部
- 建议使用bss+0x800左右的区域
Off-by-one 栈溢出
栈溢出的椅子红,但只溢出一个字节
- 只可能覆盖Old-EBP的低位一个字节
这里也能使用stack pivot
因为可以更改Old-EBP,因此可以在这个函数返回后控制ebp
另外,当从那里返回时,可以更改stack伤的返回地址
- 只要函数使用leave或者等效的命令
由于stack地址根据环境而变化,因此很难完全预测一字节的溢出值
- 但总共可以使用256次
目前为止的技术总结
技术 | 推荐练习的问题 |
---|---|
nop-sled | CodeGate 2013 - pwn100 |
brute force | CodeGate 2013 - pwn100 |
ret2esp | CSAW CTF 2012 - pwn300 - 4842 |
stager | Hack.lu CTF 2012 - pwn300 - braincpy |
ret2plt | Plaid CTF 2013 - pwn200 - ropasaurusrex |
ret2pop | Plaid CTF 2013 - pwn200 - ropasaurusrex |
ret2libc | Plaid CTF 2013 - pwn200 - ropasaurusrex |
GOT overwrite | Plaid CTF 2013 - pwn200 - ropasaurusrex |
ROP | Hack.lu CTF 2012 - pwn300 – braincpy |
stack pivot | Hack.lu CTF 2012 - pwn300 – braincpy |