格式化字符串漏洞
常见的字符串函数
- scanf:从stdin读入
- printf:输出到stdout
- fprintf:输出到指定FILE流
- vprintf:根据参数列表格式化输出到stdout
- vfprintf:根据参数列表格式化输出到指定FILE流
- sprintf:输出到字符串
- snprintf:输出指定字节数到字符串
- syslog:输出日志
格式化字符串格式
%[parameter][flags][field width][.precision][length]type
具体各参数可见ctfwiki
原理
问题出在格式化字符上,只给函数提供字符串,而不提供其他参数,程序依然会成功运行,函数会将字符串后面的内存当做参数进行输出。若能够写入格式化字符串或者其后的内存,则可泄露、修改相应的内存空间,完成攻击。
利用
- 程序崩溃:输入若干个%s即可,但这样仅能造成程序不可用而无法达到攻击的目的。
- 泄露内存:利用
%n$x
来获取栈中被视为第n+1个参数的值(或用%p);利用%n$s
来获取指定参数对应地址的内容 - 覆盖内存
小提示
可使用pwntools自带的FmtStr
以及fmtstr_payload
函数,示例代码如下:
1 | # -*- coding: utf-8 -*- |
以及payload = fmtstr_payload(autofmt.offset, {printf_got: system_add})
,其中第一个参数为offset偏移,第二个参数是一个字典,意义是往printf函数的地址,写入system的地址。