format string 0 题解
一、题目概况
format string 0是picoCTF 2024的Binary Exploitation题。公开writeup给出的题面提示是“Can you use your knowledge of format strings to make the customers happy?”,并提供二进制文件、源码和远程连接方式。[1]
二、漏洞直觉
格式化字符串漏洞的典型危险写法是把用户输入直接交给printf当作格式模板。安全写法通常是printf("%s", input),危险写法则是printf(input)。当input中包含%s、%x、%n等格式符时,程序会把它们解释为指令,而不是普通文本。
格式化字符串漏洞的触发逻辑
三、解题过程
题目第一轮给出三个汉堡选项:Breakf@st_Burger、Gr%114d_Cheese、Bac0n_D3luxe。只看格式化字符串特征,最可疑的是带有%的Gr%114d_Cheese。公开writeup显示,输入该选项后程序继续进入下一轮。
Please choose from the following burgers:
Breakf@st_Burger, Gr%114d_Cheese, Bac0n_D3luxe
Enter your recommendation: Gr%114d_Cheese
%114d的含义可以理解为“按十进制整数格式输出,并至少占114个字符宽度”。如果程序内部刚好把输入当格式模板,输出就会出现被填充后的奇怪结果。
第二轮选项中,Cla%sic_Che%s%steak比Pe%to_Portobello更值得关注,因为%s会让printf尝试把栈上的某个值当作字符串地址读取。公开writeup记录,输入Cla%sic_Che%s%steak后程序打印出flag。
Please choose from the following burgers:
Pe%to_Portobello, $outhwest_Burger, Cla%sic_Che%s%steak
Enter your recommendation: Cla%sic_Che%s%steak
输出中的异常片段并不是噪声,而是漏洞发生的证据:格式符影响了程序对内存和参数的解释方式。最终得到的flag为:
picoCTF{7h3_cu570m3r_15_n3v3r_SEGFAULT_f89c1405}
四、复盘
这道题把格式化字符串漏洞包装成菜单选择题,降低了二进制题的门槛。真正要记住的是:printf家族函数的第一个参数如果来自用户输入,就必须高度警惕。
要点:%d、%x常用于观察输出异常,%s可能触发非法地址读取或泄露字符串。
要点:真实程序中应固定格式模板,把用户内容作为后续参数传入。
要点:CTF中遇到菜单选项含%,优先考虑格式化字符串路径。