格式化字符串原理,浅显理解
-
格式化字符串漏洞通常是 printf函数未指明输出格式 例如:
char buf[20]; scanf("%s",buf); printf(buf);
这时候可以输入格式化字符 %d,%p等控制函数的输出。
如果程序指明输出的格式,则无法利用格式化字符串漏洞 例如:
char buf[20]; scanf("%s",buf); printf("%s",buf);
-
简单解释格式化字符串原理
-
这是两段程序的源码:
-
1️⃣
#include <stdio.h> void main() { char buf[20]; scanf("%s",buf); printf("%s",buf); }
-
2️⃣
#include <stdio.h> void main() { char buf[20]; scanf("%s",buf); printf("%s",buf); }
-
-
对应的汇编代码:
-
1️⃣
-
2️⃣ 可以看到两段汇编代码唯一不同的地方在于:
1️⃣程序的printf有两个参数 是 %s 和 buf,在汇编代码中可以看到 buf 的地址 rbp-0x20被传给了rsi寄存器,那%s这个参数是怎么处理的呢,可以猜测是通过lea rdi,[rip+0xe7c] 传给了rdi寄存器。(rip+0xe7c)这个地址存的值就是 %s)这个探索过程可以通过 gdb 实现,这里就不多赘述。
2️⃣程序存在格式化字符串漏洞 它的printf 函数只有一个参数 buf,通过汇编代码可以知道 buf 的地址被直接传给了rdi寄存器,如果我们在输入的时候将 buf 的值设为 %x,rdi 所指向的地址的值就为 %x ,这个传参过程类似1️⃣的汇编代码现实的过程,但是这样就缺少了要显示的参数的地址,实际上程序运行时会把后面的栈空间的值显示出来。这个过程若是深入理解需要很多底层的知识,由于我的水平有限,只能先这样简单记忆了。
-
-
\