BugkuCTF-PWN题pwn3-read_note超详细讲解
知識點
puts()的特性 , puts()會一直輸出某地址的數據,直到遇到 \x00
Canary最低位為\x00(截斷符)
\x 和 0x 的區別:
區別不大,都是把數按16進制輸出。
1、0x 表示整型數值 (十六進制)
char c = 0x42; 表示的是一個數值(字母B的ASCII碼66),可以認為等價于: int c = 0x42;
2、\x42用于字符表達,或者字符串表達
char c = ‘\x42’; 亦等價于: char c = 0x42;
char* s = “\x41\x42”; //表示字符串:AB
程序編譯的時候入口并不是main函數,而是start代碼段。事實上,start代碼段還會調用__libc_start_main來做一些初始化工作,最后調用main函數并在main函數結束后做一些處理。
解題流程
先運行一下看看
一開始會讓你輸入一個路徑,不存在的話就會報錯退出,然后打印出文件內容,然后分別輸入note的長度和內容,輸入內容的長度取決于之前的note長度;如果實際輸入的長度不是624,則再輸入一遍
查看保護機制
發現除了RELRO,其他保護機制全開
此題難點:
第一要讀懂題目找出漏洞
第二是要繞過各類保護機制
第三是exp的編寫調試。
第一要讀懂題目找出漏洞
首先分析程序,重要部分如下所示。一開始會讓你輸入一個路徑,不存在的話就會報錯退出,然后打印出文件內容;以上均可以忽略,沒有任何用處。然后分別輸入note的長度和內容,輸入內容的長度取決于之前的note長度;如果實際輸入的長度不是624,則再輸入一遍,此時輸入內容的長度變為0x270(624)??梢园l現,v4的長度為0x258(600),而輸入的長度可以任意控制,因此存在棧溢出。
第二是要繞過各類保護機制
確定了漏洞所在,下一個問題就是如何繞過NX、Canary、PIE和ASLR等保護機制了,下面一個個來說。
1.NX很簡單,ROP即可。
2.Canary會很大程度上妨礙棧溢出,但結合本題的環境,輸入一次后緊接著一個puts函數將輸入內容打印出來,然后還有一次輸入的機會,因此可以在第一次輸入時,通過覆蓋Canary最低位的\x00為其他值(Canary最低位肯定為\x00,而puts()會一直輸出直到碰見\x00位置),讓puts()泄露出Canary的內容,第二次輸入時再將正確的Canary寫回去,就可以繞過Canary的保護了。
3.PIE會讓程序加載的基地址隨機化,但是隨機化并不完全,最低三位是不會改變的,可以利用這個特性,通過覆蓋最低的兩位來有限的修改程序控制流,然后再泄露出程序加載地址。
4.至于ASLR,利用ret2libc的方法,泄露出libc的版本,就可以算出system等函數的地址然后get shell了。
第三是exp的編寫調試
通過以上的分析,由于需要泄露三個內容,因此main函數需要執行四次,每次執行都會有兩次輸入,每次執行的工作分別如下:
第一次執行
需要在填滿v4的長度600后,再溢出兩個十六進制位(64位計算機一個地址是8個字節),覆蓋Canary的最低位,然后將Canary打印出來;再次輸入時,將正確的Canary放在原來的位置,然后溢出棧上返回地址的低兩位為\x20。為什么是\x20,是因為從ida里可以發現,vul函數最后retn的地址為0xd1f,main函數的起始地址是0xd20,前面的偏移都是相同的,因此可以通過這類方法繞過PIE再跳回main。
如圖D2E為main的返回地址
第二次執行
在填滿600的基礎上,需要再多溢出兩個地址位數(64位計算機一個地址是8個字節),也就是616。從棧分布可以看出,v4之后是Canary(0x7fffffffde88處),然后再填充一個地址位,就可以輸出main+14的真實地址,也就可以得到程序加載的地址。之后使用跟之前同樣的方法,再次回到main函數的起始位置。
第三次執行
要溢出的就是__libc_start_main的真實地址了,作為main函數的返回地址,從上圖可以看出,可以從棧上泄露__libc_start_main+240的地址,依次利用LibcSearcher算出libc版本,然后得到system地址和/bin/sh字符串的地址。此時已經具備了get shell的條件,但由于第二次輸入的長度所限,因此還要再跳回main函數,再次執行程序。
第四次執行
將payload拼接好,然后發給程序了。由于是64位,傳參需要rdi。通過ROPgadget搜索程序二進制,發現存在pop rdi;ret;的gadget,將其偏移再加上第二步得到的程序加載基地址,就可以得到gadget的真實地址,至此,payload拼接完成,可以拿到shell了。
exp:
運行結果
由于本題有bug,建立連接后直接輸入flag,出現flag
總結
以上是生活随笔為你收集整理的BugkuCTF-PWN题pwn3-read_note超详细讲解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 教你做前端表单文本框必填
- 下一篇: C语言 文件读写 EOF - C语言零基