萌新帶你開車上p站(二)

前情提要:https://www.toutiao.com/i6800255609745703427/

0x04flag

萌新帶你開車上p站(二)

看題目描述似乎是一個和脫殼相關的逆向題目

按照給出的地址先下載過來

萌新帶你開車上p站(二)


file看看

萌新帶你開車上p站(二)

是個可執行文件

執行之

萌新帶你開車上p站(二)

emm什麼都看不出來,又沒有源碼

那載入gdb吧

萌新帶你開車上p站(二)


emmm,沒有符號表,無法反彙編

哦,對了,根據題目的提示這是加了殼的,所以先脫殼

這是什麼殼呢?

Strings看看

萌新帶你開車上p站(二)

upx的

這裡簡單介紹下upx:

UPX是一個著名的壓縮殼,主要功能是壓縮PE文件(比如exe,dll等文件),有時候也可能被病毒用於免殺.殼upx是一種保護程序。一般是EXE文件的一種外保護措施,主要用途 :

1、讓正規文件被保護起來,不容易被修改和破解。

2、使文件壓縮變小。

3、保護殺毒軟件安裝程序,使之不受病毒侵害。

4、木馬,病毒的保護外殼,使之難以為攻破

和很多殼比起來upx的手動脫殼也比較簡單,但是本文主要學習pwn而不是脫殼,如果有對upx手動脫殼有興趣的話這裡推薦一篇文章:https://blog.csdn.net/fawdlstty/article/details/8332227

我們這裡直接自動脫殼就可以了

萌新帶你開車上p站(二)

接下來再載入gdb

萌新帶你開車上p站(二)

反彙編main後看到了一個地址

打印出來

萌新帶你開車上p站(二)

這就是flag了

加殼與脫殼技術:

http://www.hetianlab.com/cour.do?w=1&c=CCIDe9a2-7038-4d4f-951e-c5b068d31798

複製上方鏈接做實驗哦。

0x05passcode

萌新帶你開車上p站(二)

看題目描述,編譯時沒有報error,那是不是會報warning呢

連上機器後先看看源碼

萌新帶你開車上p站(二)


從源碼中可以看到

1.程序功能是先輸入name,然後輸入passcode1,passcode2,相當於輸入一個用戶名,兩個密碼

2,main中接連執行welcome,login,中間沒有push,pop,二者ebp相同

3,login()中scanf接收輸入的時候,passcode1,passcode2沒有加上&取地址,又由於passcode1,passcode2沒有被初始化,所以我們scanf輸入數據時,數據被保存到哪兒是未知的,只是知道數據被保存到passcode1,passcode2的值指向的地址中去了。

考慮2和3,我們猜想是否可以通過控制name的內容進而控制passcode1,passcode2呢?畢竟name取100字節,三者的ebp又是相同的

不過具體是否可行,我們上gdb試試

萌新帶你開車上p站(二)


萌新帶你開車上p站(二)

圖x

可以看到name地址為%ebp-0x70,passcode1地址為ebp-0x10,二者差0x70-0x10=96個字節。Passcode2地址為%ebp-0xc,.name和passcode2從差0x70-0xc=100個字節,我們只能通過寫name控制passcode1,但是不能控制passcode2

既然可以控制passcode1,那麼思路就清楚了。

由源碼邏輯可知,printf,scanf,fflush

我們控制passcode1的地址(name的最後4字節)為ffliush地址,在隨後scanf(“%d”,passcode1)接收輸入時我們輸入system(“/bin/cat flag)的地址

這樣當執行fflush時,將會執行system,從而讀到flag

通過GOT表獲取flush地址

萌新帶你開車上p站(二)


在圖x中可以看到調用system的地址為080485ea,不過在此之前還有傳參的操作,所以實際上,地址應該為0x080485e3,十進制為134514147

從而構造出exp

萌新帶你開車上p站(二)


總結一下,這裡用到的技術叫做GOT覆寫,就本題而言,是這樣子的:

我們通過控制nane的最後四個字節,將passcode1的值改為fflush的地址,而在程序中,scanf後會調用fflush,而我們已經把system(“bin/cat flag”)的地址寫到fflush中,覆蓋了fflush在GOT表中的內容,所以當scanf調用時,會直接執行system打印flag,繞過了後面比較passcode1,passcode2的邏輯。

0x06random

萌新帶你開車上p站(二)

看描述,是和隨機數有關係

萌新帶你開車上p站(二)

由源碼可知,當滿足key與random異或得0xdeadbeef時才打印flag

而random的值由rand函數產生,key的值由我們輸入

那麼本題的關鍵就是找到random的值是多少

我們知道,rand函數產生的實際是偽隨機數,所以我們可以寫個程序,先由rand生成一個數,將其與0xdeadbeef相異或,得到的值就是我們輸入的key

這是一種思路

或者我們也可以用gdb調試,在程序判斷if條件是否成立的地方下斷點,觀察內存佈局,也是可以得到random的值的

萌新帶你開車上p站(二)

下了斷點後輸入2,然後命中

萌新帶你開車上p站(二)


可以看到,2是我們的輸入,而0x6b8b4567則是random

那麼我們將該值與random異或即可得到輸入的key

萌新帶你開車上p站(二)

0x07leg

萌新帶你開車上p站(二)


看題目這題是和arm、彙編相關的

把源程序下過來看看

萌新帶你開車上p站(二)


看到main中需要滿足key1()+key2()+key3()=key才可打印出flag

key是我們需要輸入的

key1()等表示的相關函數的返回值

那麼本題就是要求出相關函數的返回值並相加

而c源碼中這三個函數都是內聯彙編的形式

還是直接用gdb看看吧

題目和我們說了這是arm

通常情況下,arm以r0寄存器存返回值,對應在x86中就是eax

這一點從彙編中也可以看出

萌新帶你開車上p站(二)


那麼在每個函數中r0的值是多少呢

一一看過來

先看key1

萌新帶你開車上p站(二)


可以看到,pc->r3->r0,也就是說r0的值為pc寄存器的值

這裡有個知識點

ARM屬於RISC,精簡指令及,分三段流水,取指、譯碼、執行

當mov r3,pc執行時,此時的pc為當前指令地址+0x8,及0x8cdc+0x8

再看key2

萌新帶你開車上p站(二)


add r6,pc,#1的意思是r6=pc+1,由key1的知識知,r6=0x8cfc+8+1,該值最低位為1

為什麼要強調最低位

因為後面一條指令bx r6

bx指令用於切換處理器狀態模式,最低位為1時,切換到Thumb指令執行,為0時,解釋為ARM指令執行

所以執行該指令後就切換到了thumb模式下

而thumb模式下pc值為當前指令地址+4

所以執行r3,pc時,r3的值為0x8d04+4

再執行adds,r3,#4後r3的值Wie0x8d04+4+4

執行mov r0,r3後,r0的值也同r3

再看看key3

萌新帶你開車上p站(二)


執行紅框中的兩條指令後,r0的值等於lr的值

lr即r14,存放是函數返回地址

具體的值在main中可以看到,為0x8d80

綜上,得key值為108400

萌新帶你開車上p站(二)


欲知後續,請留意每日文章推送!

聲明:筆者初衷用於分享與普及網絡知識,若讀者因此作出任何危害網絡安全行為後果自負,與合天智匯及原作者無關!


分享到:


相關文章: