格式化字符串漏洞
格式化字符串常见语法
%d 打印signed int
%u 打印unsigned int
%x 打印hex形式整数
%p 打印指针(地址),void*
%s 打印参数地址处的字符串
常见于以下函数

常见利用方式
%<正整数n> 打印宽度为n的字符串(打印长度为n)
%n 将当前已打印字符的个数(4字节)写入参数地址处
%hn 写入2字节
%hhn 写入1字节 【h short】
eg.
printf(“%10c%n”, 0x41, 0x41414141);
打印9个空格加上1个A ,所以会往地址0x41414141处写入10(4字节)【10是对应的n前的字符个数】printf(“%1337c%hhn”, 0x41, 0x804a000);
1337=0x59, 又%hhn, 所以往地址0x804a000处写入1字节0x39
【一个字节存储0~225】【因为1字节等于8bit,2^8-1】
%<正整数n>$
eg.printf(“0x2$x:0x%1$x\n”, 0xdeadbeef, 0xcafebabe);
打印结果为 0xcafebabe:0xdeadbeef
如果printf参数不足
eg.printf(“%p:%p:%p:%p\n”);
会假设参数存在,并在对应的栈/寄存器上找到这些参数,并做相应处理
对应x86下32位程序,参数都在栈上,因此pinrtf会把栈上的值一次打印出了
参数不足的情况下
32位:函数调用时参数在栈 格式化字符可控可以泄露站上数据
64位:函数调用使用寄存器+栈 格式化字符可控可以泄露特定寄存器和栈上的值
利用fmtstr_payload
可以生成相应的字符串
fmtstr_payload有两个参数
第一个参数是int,用于表示取参数的偏移个数
第二个参数是字典,字典的意义是往key的地址,写入value的值fmtstr_payload(offset,{address1:value1})









