[原创]Pwn学习笔记:printf格式化字符串漏洞原理与利用
基本介绍
Format String 介绍
在C语言中,我们常用的输出函数有printf、 fprintf、 vprintf、 vfprintf、 sprint等。对于这些输出函数,Format String是其第一个参数,我们一般称之为格式化字符串。
下面简单介绍格式化字符串如何在输出函数进行解析。
printf 接受变长的参数,其中第一个参数为格式化字符串,后面的参数在实际运行时将与格式化字符串中特定格式的子字符串进行对应,将格式化字符串中的特定子串,解析为相应的参数值。
举个例子来说:
printf("Team Name: %s\tPoints: %d\n", "Whitzard", 999);在上面这行语句中, "Team Name: %s\tPoints: %d\n"为格式化字符串,"Whitzard"、999分别为第二个和第三个参数。在格式化字符串解析时,格式化字符串中的 "%s" 对应到第二个参数 "Whitzard" ,而 "%d" 则对应到第三个参数999。(\t \n在此处不做讲解。)
于是实际输出为如下结果:
Team Name: Whitzard Points: 999
Format String符号说明
在格式化字符串中,"%s"、"%d" 等类型的符号叫符号说明,这些符号说明的基本格式为 %parameterfield width[length]type 。相信大家对于简单的符号说明并不陌生,但如果要利用格式化字符串漏洞,我们还需要用到几个比较冷门的符号说明,如:

调用约定
了解格式化字符串的解析方法后,我们还需要知道printf传参方式,以及格式化字符串的调用约定,才能实现对于格式化字符串的利用。
86
在x86(32-bit)系统中,printf的参数是按参数顺序依次存放在栈上的,我们举个栗子来演示printf的调用约定。
对于下面的程序,我们为printf传入一个格式化字符串和若干个参数。通过gdb调试将程序断点设在printf处可查看参数在栈上的分布。
1 #include <stdio.h>
2
3 int main(){
4
5 printf("Test : 1.%p\t 2.%p\t 3.%p\t 4.%p\t 5.%p\t 6.%p\t",
6 0x11111111, 0x22222222,
7 0x33333333, 0x44444444,
8 0x55555555, 0x66666666);
9 return 0;
10 }
注意:上传附件及图片大小不得大于30M。
⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。
