攻擊者將未經過濾的輸入直接傳遞給格式化函數(如 printf),從而讀取或修改程式內存。此漏洞最常見於 C 語言中,當程式開發者不小心將用戶輸入作為格式字串時,攻擊者便能通過插入特定的格式化符號來讀取敏感資料甚至覆寫記憶體。
如 printf()
這類函數使用格式化符號來決定輸出不同類型的數據。例如,%d
用來輸出整數,%x
用來輸出十六進位數字。等透過格式化符號來決定數據的輸出形式。如果未經適當過濾使用者輸入的字串,程式可能無意間將敏感資料暴露在攻擊者面前。
幾例來說,程式中輸入 buffer
內容直接被傳遞給 printf。如果攻擊者輸入格式化符號(如 %x%x%x),便可讀取記憶體堆疊中的內容。
#include <stdio.h>
int main() {
char buffer[100];
gets(buffer); // 獲取使用者輸入
printf(buffer); // 潛在格式化字串漏洞
return 0;
}
安全一點的做法,避免將使用者輸入直接作為格式化字串的一部分,嚴格限制可以被傳遞到格式化函數中的內容。讓使用者的輸入的值使用固定的格式字串,這樣即便使用者的輸入中含有格式化符號,也不會被程式解釋為格式符號。
printf(buffer); // 不安全
printf("%s", user_input); // 安全
今天將會練習兩題有關 format string 漏洞利用的 Lab
Lab_1 - format string 0
使用 nc
指令連線至題目後,題目說讓我們點餐,這邊有三種 burger,分別是 Breakf@st_Burger
, Gr%114d_Cheese
跟 Bac0n_D3luxe
,那剛剛提到說有 %s
有機會觸發漏洞
進到下一關的環節,一樣有三個漢堡,再次繼續選有 %s
的,拿到 flag 了
Lab_2 - format string 1
觀察題目附上的原始碼,第五行那邊一樣有可以利用的漏洞
printf("Give me your order and I'll read it back to you:\n");
fflush(stdout);
scanf("%1024s", buf);
printf("Here's your order: ");
printf(buf);
printf("\n");
fflush(stdout);
觀察程式碼後發現 flag 的範圍約在 14~21 的指標位置,6 + 64/8 + 64/8 = 22
。我們讓指標偏移印出我們要的內容,%14$p%15$p%16$p%17$p%18$p%19$p%20$p%21$p
拿到一串 16 進制,丟進這個 hex to string 的好用工具,發現跟我們要的 flag 長相很接近
{FTCocip5_14m1n44x4_31y705_g41f_}46c693
,將每八個字分成一組,接著各小組反轉後,即是我們的 flag。
練習就到這邊,以下是參考資料,請搭配服用:
格式化字串漏洞
Format Strings
format-string-0
內文如有錯誤,還請不吝指教~