x86-64位的格式化字符串漏洞
在 x64 體系中,多數調用慣例都是通過寄存器傳遞參數。在 Linux 上,前6個參數通過 RDI、RSI、RDX、RCX、R8 和 R9 傳遞。
簡介
還是前面的程序編譯成64位的
#include <stdio.h
int main()
{
int n_change = 1;
char str[200];
printf("before is : %d\n", n_change);
scanf("%s",str);
printf(str);
printf("\nafter is : %d\n", n_change);
return 0;
}
使用 AAAAAAAA%p.%p.%p.%p.%p.%p.%p.%p.%p.%p. 作為輸入


可以看到最后的輸出中,前面的輸出取自于寄存器,后面的才是取自于棧。雖然我們并沒有向相應寄存器中放入數據,但是程序依舊會按照格式化字符串的相應格式對其進行解析。
真題
鏈接: https://pan.baidu.com/s/1H4t7JEFyitMCOtIFTtBswA 密碼: do0d
2017 年的 UIUCTF 中 pwn200 GoodLuck
這個題目需要本地有flag.txt文件,所以我們自己新建一個就好。

開啟NX保護和部分RELRO保護。
IDA下F5,非常明顯的格式化字符串漏洞
gdb調試看看偏移位置,在第一個printf()即格式化字符串漏洞處下斷點。


看到偏移為4,并且fmt 字符串存儲在 RDI 寄存器中,所以 fmt 字符串對應的地址的偏移為 10。
所以我們只需要輸入 %9$s 即可得到 flag 的內容。
當然可以借助現有的工具,這里介紹一個https://github.com/scwuaptx/Pwngdb 中的 fmtarg來確定棧上的變量偏移,注意一個是Pwngdb一個是pwndbg。如何與pwndbg配置請看這一篇文章https://blog.csdn.net/weixin_43092232/article/details/105648769


參考