ROP的问题点

ROP需要一个较大的溢出缓冲区

  • 因为只包含一些细分的小指令,要发送的数据不可避免的增加

  • 如果在srack返回地址下没有较大的溢出,就会很糟糕

  • 如果没有足够的溢出缓冲区该怎么办?

  • stack pivot

    img

溢出量问题绕过 - stack pivot

  • stack pivot

    • 使用ret2plt等将后续ROP加载到bss(适当区域)

      img

    • 通过pop ebp; ret来调整EBP寄存器

      img

    • 通过leave; ret来任意更改ESP

      • leave是「mov esp, ebp; pop ebp」之类的值
    • bss作为stack继续ROP

      img

stack pivot的注意事项

  • 使用bss作为stack发动ROP,可能会失败

    • 调用system()之前出现SIGSEGV
    • 调用system()时也可能出现SIGSEGV
  • 这是因为(后续ROP使用的GOT等)必要的变量被破坏,以及跳到stack等原因

    • 因为read/write时,系统内的dl_fixup函数对stack做了很好的保护
  • pivot使用的stack,应该设置在.bss的中间,而不是靠近顶部

    • 建议使用bss+0x800左右的区域

    img

Off-by-one 栈溢出

  • 栈溢出的椅子红,但只溢出一个字节

    • 只可能覆盖Old-EBP的低位一个字节

    img

  • 这里也能使用stack pivot

    • 因为可以更改Old-EBP,因此可以在这个函数返回后控制ebp

      img

    • 另外,当从那里返回时,可以更改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