XCTF pwn新手區解題記錄
一、前言
閒來無事,刷刷ctf題
二、題目: level0
1、下載好題目後,拖入到kali中去,用file
和checksec
檢視一下,可以發現該程式是64位
,只開了NX
保護,如下圖所示:
2、拖入到IDA
中去,發現在main
函式中打印出資訊後就呼叫了vulnerable_function
函式,跟進vulnerable_function
函式,可以發現read
函式處為棧溢位漏洞,並且可以得知該buf
陣列距離ebp
為0x80
個位元組,如下圖所示:
3、通過IDA
,可以發現程式中存在一個名為callsystem
的函式,可以直接getshell
,有了這個加上上面的偏移量,就可以直接編寫exp
exp
執行結果如下圖所示:
三、題目: level2
1、下載好題目後,首先使用file
和chseksec
,可以發現程式是32
位並且開了NX
的,如下圖所示:
2、拖入到IDA
當中去,可以發現程式首先呼叫vulnerable_function
函式後就列印一串字串就結束了,跟進到vulnerable_function
中去,可以發現read
存在棧溢位,並且buf
距離ebp
為0x88
,如下圖所示:
3、上面我們找到了buf
距離返回地址
的偏移量(0x88+4),仔細觀察,我們可以發現存在_system
函式可以getshell
,跟進去該函式後,可以發現,需要傳入字串/bin/sh
getshell
,使用快捷鍵shift+F12
調出字串介面,發現了該字串,那麼我們的payload
應該為0x8C * b'A' + p32(_system函式地址) + p32(0) + p32(/bin/sh字串地址)
(PS:這裡之所以有一個p32(0)
,是因為我們正常呼叫一個函式時,棧從高到底的結構為:引數 返回地址 ebp,所以這裡我們需要提供一個虛假的返回地址以模擬正常的呼叫過程),最後exp
執行結果如下圖所示:
四、題目: string
1、下載好題目後,拖入到kali中去,用file
和checksec
檢視一下,可以發現該程式是64位
,如下圖所示:
2、將程式拖入到IDA
main
函式中,首先呼叫alarm
函式設定了0x3C
秒後關閉程式,然後給變數v4
申請了8個位元組
的空間,並且給v4[0]
賦值為68
、v4[1]
賦值為85
,之後就是呼叫puts
函式列印一些資訊,然後就呼叫sub_400D72
函式,並且將v4
陣列作為引數傳入,之後main
函式就結束退出了,如下圖所示:
3、跟進sub_400D72
中去,該函式首先要求輸入一個名字,如果長度小於等於0xC
,則建立一個角色,然後依次呼叫sub_400A7D
、sub_400BB9
、sub_400CA6
函式,否則就退出,如下圖所示:
4、跟進到sub_400A7D
中去,該函式只有輸入east
才能正常返回,如下圖所示:
5、接著跟進到sub_400BB9
中去,該函式首先要求我們輸入一個數字,如果輸入的數字為1
,則進入一個if
裡面去,在該if
塊裡面,首先要求輸入一個數字,然後要求輸入一串字串,緊接著該函式直接將該字串作為引數傳入到printf
函式中去了,很明顯的格式化字串漏洞,如下圖所示:
6、接著分析一下sub_400CA6
,該函式首先呼叫puts
函式列印一些資訊,然後判斷引數陣列a[0]
是否等於a[1]
,如果相等,則申請一片空間,然後通過read
函式獲取使用者輸入寫入到剛剛申請到的空間中,然後把該空間中的值作為一段程式碼執行,而這裡的引數陣列就是main
函式的v4
陣列,如下圖所示:
7、有了上面的分析,可以很明顯得出解題的方法,首先利用格式化字串漏洞,將v4[0]=v4[1]
,然後寫入shellcode
來getshell
,首先我們來尋找一下偏移量,執行程式,輸入名字之後,輸入east
,然後輸入1
,之後輸入payload
測試偏移量,從下圖可以看出,偏移量為8
,如下圖所示:
8、有了偏移量,就可以寫exp
了,但這裡有一個小坑,__isoc99_scanf
函式這裡前幾個位元組沒辦法直接作為地址寫入(PS:事後對比了其他師傅的wp,發現IDA
反編譯出來的內容都有點不同,不知道是不是這個原因),這裡使用程式碼中前面輸入那個地址,偏移量為7
,在上面的圖片中已標註,執行exp
,結果如下圖所示:
五、題目: guess_num
1、首先下載好題目,拖入kali中檢視一下基礎資訊,可以發現為64位
的程式,如下圖所示:
2、拖進IDA
中,發現程式首先生成了一個隨機種子,然後呼叫gets
函式獲取輸入,典型的棧溢位漏洞,但前面保護全開,也沒法直接覆蓋返回地址來rce
,往下接著看,要求使用者練著猜10次並且全部正確就可以得到flag
,前面存在一個棧溢位,雖然沒辦法來rce
,但可以用來覆蓋隨機化種子,有了種子,我們就可以直接提前計算出來隨機值,而gets
輸入距離種子偏移量為0x20
,如下圖所示:
3、直接使用c算出隨機值,然後nc
連線上去即可得到flag
(PS:不知道我的python指令碼為啥一直得不到flag,這裡就直接簡單粗暴的nc連線了),如下圖所示:
六、題目: get_shell
nc
連線即可,如下圖所示:
七、題目: int_overflow
1、還是首先拖入到kali
中檢視一下基礎資訊,可以發現是32
位的程式,如下圖所示:
2、執行一下程式,沒發現什麼有意思的東西,拖入到IDA
中去,根據執行時的字串,定位到了main
函式中去,分析一下main
函式,就是一個登入流程,沒什麼可疑的地方,如下圖所示:
3、跟進到login
函式中去,可以發現最多可以輸入0x199
大小的密碼,其餘地方也沒什麼可疑的,如下圖所示:
4、跟進到check_passwd
函式中去,首先可以發現當中的v3
變數大小是一位元組,然後程式將密碼字串的大小賦值給了v3
,之後判斷v3
是否小於3,大於8,如果是,就退出,否則就列印資訊並將密碼拷貝到dest
陣列中去,結合題目名的提醒,可以發現這裡存在整數溢位漏洞,可以繞過其對v3
的判斷,然後棧溢位覆蓋返回地址,如下圖所示:
5、那麼v3
等於多少時能繞過喃,這裡v3
只有一個位元組大小,所以我們只需要使我們輸入的密碼長度的最後一個位元組為4,5,6,7,8
之中的一個即可,這裡密碼最多可輸入0x199
位元組,寫一個判斷指令碼跑一下所有可能,如下圖所示:
6、這裡選擇第一個260
,接下來我們還需要偏移量,IDA
已經給出了,為0x14
到ebp
,那麼我們覆蓋0x18
位元組之後即可覆蓋返回地址,在該程式中,還存在一個直接獲取flag
的函式what_is_this
,我們直接將返回地址覆蓋為這個函式地址即可拿到flag
,exp
執行結果如下圖所示:
八、題目: cgpwn2
1、下載好題目之後,拖入kali
中簡單檢視一下程式資訊,可以發現該程式為32位
,並且開了NX
,如下圖所示:
2、將程式拖入到IDA
中,首先檢視main
函式,該函式沒什麼可疑的,如下圖所示:
3、跟進到hello
函式中去,可以發現在函式末尾呼叫了gets
函式,很明顯的棧溢位,並且從IDA
反編譯的結果我們可以知道陣列s
距離ebp
為0x26
,也就是說0x26 + 4
個位元組的偏移量後即可覆蓋到返回地址,如下圖所示:
4、因為題目開了NX
,沒辦法在棧上直接部署shellcode
來執行,仔細觀察,我們發現提供了system
函式,但是沒有提供/bin/sh
字串,我們只要想辦法制造一個/bin/sh
字串即可getshell
,在hello
函式中,程式還呼叫了fgets
函式獲取輸入儲存到name
變數中,檢視name
位置可以發現name
位於bss
段中,那麼exp
的思路就是首先在程式呼叫fgets
處輸入/bin/sh;
字串,然後再呼叫gets
函式處溢位覆蓋返回地址為system
函式地址,exp
執行結果如下圖所示:
九、題目: level3
1、下載好題目,拖入到kali
中去,檢視一下程式的基本資訊,可以發現程式為32位
的,並且開了NX
,如下圖所示:
2、將程式拖入到IDA
中去,首先看一下main
函式,main
函式首先呼叫了一個vulnerable_function
函式,然後就是呼叫了write
輸出資訊到控制檯中,沒什麼存在漏洞的地方,如下圖所示:
3、跟進到vulnerable_function
函式中去,可以發現該函式呼叫的read
函式存在棧溢位,並且IDA
已經計算出來buf
距離ebp
為0x88
,那麼覆蓋0x88 + 4 = 0x8C
個位元組之後即可覆蓋返回地址,如下圖所示:
4、仔細觀察該程式,可以發現沒有system
等現成的函式可以讓我們直接getshell
,但是存在libc
和已經呼叫過的write
函式,並且題目還給了libc.so
檔案,那麼思路就很明顯了,首先棧溢位呼叫write
函式輸出write
函式的地址,進而獲取到libc
的基地址,因為libc.so
中存在system
函式和/bin/sh
字串的偏移地址,加上基地址就可以得到對應的絕對地址,之後再棧溢位呼叫write
時將返回地址設定為vulnerable_function
函式的首地址,再次棧溢位覆蓋返回地址為前面計算出的system
的絕對地址即可getshell
,exp
執行結果如下圖所示:
十、題目: cgfsb
1、下載好題目,拖入到kali
中去,檢視一下程式的基本資訊,可以發現程式為32位
的,並且開了NX
,如下圖所示:
2、拖入到IDA
中去,可以發現程式首先要求我們輸入一個名字,然後輸入一串資訊,之後直接將資訊作為傳入到了printf
函式裡面去了,典型的格式化字串漏洞,之後則判斷pwnme
變數是否等於8
,如果等於8
,則輸出flag
,如下圖所示:
3、經過上面的分析,那麼解題的思路就很明顯了,利用格式化字串漏洞將pwnme
變數修改為8
即可。那麼現在需要確定兩個東西,一個是偏移量,另一個是pwnme
變數的地址,仔細觀察可發現,pwnme
變數不是函式區域性變數,而是bss
段的一個變數,雙擊變數名即可獲得地址,至於偏移量怎麼確定,這麼不過多敘述了,不明白的可以看我上一篇文章https://www.cnblogs.com/aWxvdmVseXc0/p/15734510.html,這裡計算出來偏移量為10
,如下圖所示:
4、最後exp
執行結果如下所示:
十一、題目: hellopwn
1、下載好題目,拖入到kali
中去,檢視一下程式的基本資訊,可以發現程式為64位
的,並且開了NX
,如下圖所示:
2、拖入到IDA
當中,進入到main
函式,會發現程式首先輸出一些資訊,然後呼叫read
函式獲取輸入,之後比較dword_60106C
變數是否等於0x6E756161
,如果相等,這呼叫sub_400686
函式,跟進sub_400686
函式,會發現該函式作用為輸出flag
,如下圖所示:
3、有了上面的分析,那麼解題的思路就很明顯了,利用read
函式溢位覆蓋dword_60106C
變數為0x6E756161
,仔細觀察一下,會發現unk_601068
變數增長4
個位元組到dword_60106C
,既偏移量為4
,最後exp
執行結果如下圖所示:
十二、相關連結
題目和exp
的github
連結: https://github.com/windy-purple/XCTF_PWN