1. 程式人生 > 其它 >XCTF pwn新手區解題記錄

XCTF pwn新手區解題記錄

一、前言

    閒來無事,刷刷ctf題


二、題目: level0

    1、下載好題目後,拖入到kali中去,用filechecksec檢視一下,可以發現該程式是64位,只開了NX保護,如下圖所示:

    2、拖入到IDA中去,發現在main函式中打印出資訊後就呼叫了vulnerable_function函式,跟進vulnerable_function函式,可以發現read函式處為棧溢位漏洞,並且可以得知該buf陣列距離ebp0x80個位元組,如下圖所示:

    3、通過IDA,可以發現程式中存在一個名為callsystem的函式,可以直接getshell,有了這個加上上面的偏移量,就可以直接編寫exp

exp執行結果如下圖所示:


三、題目: level2

    1、下載好題目後,首先使用filechseksec,可以發現程式是32位並且開了NX的,如下圖所示:

    2、拖入到IDA當中去,可以發現程式首先呼叫vulnerable_function函式後就列印一串字串就結束了,跟進到vulnerable_function中去,可以發現read存在棧溢位,並且buf距離ebp0x88,如下圖所示:

    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中去,用filechecksec檢視一下,可以發現該程式是64位,如下圖所示:

    2、將程式拖入到IDA

中去,在main函式中,首先呼叫alarm函式設定了0x3C秒後關閉程式,然後給變數v4申請了8個位元組的空間,並且給v4[0]賦值為68v4[1]賦值為85,之後就是呼叫puts函式列印一些資訊,然後就呼叫sub_400D72函式,並且將v4陣列作為引數傳入,之後main函式就結束退出了,如下圖所示:

    3、跟進sub_400D72中去,該函式首先要求輸入一個名字,如果長度小於等於0xC,則建立一個角色,然後依次呼叫sub_400A7Dsub_400BB9sub_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],然後寫入shellcodegetshell,首先我們來尋找一下偏移量,執行程式,輸入名字之後,輸入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已經給出了,為0x14ebp,那麼我們覆蓋0x18位元組之後即可覆蓋返回地址,在該程式中,還存在一個直接獲取flag的函式what_is_this,我們直接將返回地址覆蓋為這個函式地址即可拿到flagexp執行結果如下圖所示:


八、題目: cgpwn2

    1、下載好題目之後,拖入kali中簡單檢視一下程式資訊,可以發現該程式為32位,並且開了NX,如下圖所示:

    2、將程式拖入到IDA中,首先檢視main函式,該函式沒什麼可疑的,如下圖所示:

    3、跟進到hello函式中去,可以發現在函式末尾呼叫了gets函式,很明顯的棧溢位,並且從IDA反編譯的結果我們可以知道陣列s距離ebp0x26,也就是說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距離ebp0x88,那麼覆蓋0x88 + 4 = 0x8C個位元組之後即可覆蓋返回地址,如下圖所示:

    4、仔細觀察該程式,可以發現沒有system等現成的函式可以讓我們直接getshell,但是存在libc和已經呼叫過的write函式,並且題目還給了libc.so檔案,那麼思路就很明顯了,首先棧溢位呼叫write函式輸出write函式的地址,進而獲取到libc的基地址,因為libc.so中存在system函式和/bin/sh字串的偏移地址,加上基地址就可以得到對應的絕對地址,之後再棧溢位呼叫write時將返回地址設定為vulnerable_function函式的首地址,再次棧溢位覆蓋返回地址為前面計算出的system的絕對地址即可getshellexp執行結果如下圖所示:


十、題目: 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執行結果如下圖所示:


十二、相關連結

    題目和expgithub連結: https://github.com/windy-purple/XCTF_PWN