pwn初識格式化字串漏洞

鈔sir發表於2018-12-02

格式化字串漏洞通常情況下是由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表中的地址然後找到函式的真實的地址,然後減去偏移獲得基地址;

具體的方法我們在另外一篇中,用一個具體的列子來講。。。。。

 

相關文章