pwn初识格式化字符串漏洞

格式化字符串漏洞通常情况下是由printf函数产生的;

正常情况下我们用printf函数输出字符串时是这样的:

char a[100]="fmtstr";
int b=12,c=666;
printf("%s %d %x",a,b,c);

但是有时是出于方便会直接输出字符串:

char str[12]="fmtstr";
printf(str);

这时,如果这个str是我们用户输入可控的,那么这就存在了一个格式化字符串漏洞,这时攻击者将有机会对任意内存地址进行读写操作;

printf的读写操作:

我们都知道printf函数可以打印出一段内容,比如:

printf("%d",a); //打印一个整型a
printf("%s",b); //打印一个字符串b
printf("%c",c); //打印一个字符c
printf("%x",d); //以十六进制数的格式打印d

但是printf里面还有一个%n的格式可以用来对一段地址写值;

#include<stdio.h>
int main()
{
        int a,b,c;
        printf("ABC%nEFG%n\n",a,b);
        printf("%123c%n\n",'a',c)
        printf("a=%d b=%d c=%d\n",a,b,c);
        return 0;
}

输出结果:a=3 b=6 c=123

我们并没有对a,b,c进行初始化和赋值,但我们通过%n来写入了一个值,这就是printf写的操作,具体的还可以往某一个字节写值(%hnn);

危害:

用一个简单的列子来说明:

#include<stdio.h>     
int main()            
{                     
        char str[100];  
        scanf("%s",str); //用户可控的字符串
        printf(str);    //格式化字符串漏洞
        printf("\n"); 
        return 0;     
}                     

如果我们将我们输入一些特殊的字符串比如%x会怎么样呢;

我们发现,它将栈中的数据打印出来了,而我们输入的第一个数据在第6个;

如果我们将我们输入是‘aaaa'换成某一个地址,然后找到它在栈中的位置,我们是不是就可以获得一些敏感信息了呢,

比如我们可以打印出开了canary的cookie,某一个函数在got表中的地址然后找到函数的真实的地址,然后减去偏移获得基地址;

具体的方法我们在另外一篇中,用一个具体的列子来讲。。。。。

猜你喜欢

转载自blog.csdn.net/qq_40827990/article/details/84712311