pwnable.krToddlr’s Bottle題解2

0x04flag
在這裏插入圖片描述
看題目描述似乎是一個和脫殼相關的逆向題目
按照給出的地址先下載過來
在這裏插入圖片描述
file看看
在這裏插入圖片描述
是個可執行文件
執行之
在這裏插入圖片描述
emm什麼都看不出來,又沒有源碼
那載入gdb吧
在這裏插入圖片描述
emmm,沒有符號表,無法反彙編
哦,對了,根據題目的提示這是加了殼的,所以先脫殼
這是什麼殼呢?
Strings看看
在這裏插入圖片描述
upx的
這裏簡單介紹下upx:
UPX是一個著名的壓縮殼,主要功能是壓縮PE文件(比如exe,dll等文件),有時候也可能被病毒用於免殺.殼upx是一種保護程序。一般是EXE文件的一種外保護措施,主要用途 :
1、讓正規文件被保護起來,不容易被修改和破解。
2、使文件壓縮變小。
3、保護殺毒軟件安裝程序,使之不受病毒侵害。
4、木馬,病毒的保護外殼,使之難以爲攻破
和很多殼比起來upx的手動脫殼也比較簡單,但是本文主要學習pwn而不是脫殼,如果有對upx手動脫殼有興趣的話這裏推薦一篇文章:https://blog.csdn.net/fawdlstty/article/details/8332227
[新增部分]我們這裏直接自動脫殼就可以了
在這裏插入圖片描述
接下來再載入gdb
在這裏插入圖片描述
反彙編main後看到了一個地址
打印出來
在這裏插入圖片描述
這就是flag了

0x05passcode
在這裏插入圖片描述
看題目描述,編譯時沒有報error,那是不是會報warning呢
連上機器後先看看源碼
在這裏插入圖片描述
從源碼中可以看到
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試試
在這裏插入圖片描述在這裏插入圖片描述

圖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地址
在這裏插入圖片描述
在圖x中可以看到調用system的地址爲080485ea,不過在此之前還有傳參的操作,所以實際上,地址應該爲0x080485e3,十進制爲134514147
從而構造出exp
在這裏插入圖片描述
總結一下,這裏用到的技術叫做GOT覆寫,就本題而言,是這樣子的:
我們通過控制nane的最後四個字節,將passcode1的值改爲fflush的地址,而在程序中,scanf後會調用fflush,而我們已經把system(“bin/cat flag”)的地址寫到fflush中,覆蓋了fflush在GOT表中的內容,所以當scanf調用時,會直接執行system打印flag,繞過了後面比較passcode1,passcode2的邏輯。

0x06random[標題]
在這裏插入圖片描述
看描述,是和隨機數有關係
在這裏插入圖片描述
由源碼可知,當滿足key與random異或得0xdeadbeef時纔打印flag
而random的值由rand函數產生,key的值由我們輸入
那麼本題的關鍵就是找到random的值是多少
我們知道,rand函數產生的實際是僞隨機數,所以我們可以寫個程序,先由rand生成一個數,將其與0xdeadbeef相異或,得到的值就是我們輸入的key
這是一種思路
或者我們也可以用gdb調試,在程序判斷if條件是否成立的地方下斷點,觀察內存佈局,也是可以得到random的值的
在這裏插入圖片描述
下了斷點後輸入2,然後命中
在這裏插入圖片描述
可以看到,2是我們的輸入,而0x6b8b4567則是random
那麼我們將該值與random異或即可得到輸入的key
在這裏插入圖片描述

0x07leg
在這裏插入圖片描述
看題目這題是和arm、彙編相關的
把源程序下過來看看
在這裏插入圖片描述
看到main中需要滿足key1()+key2()+key3()=key纔可打印出flag
key是我們需要輸入的
key1()等表示的相關函數的返回值
那麼本題就是要求出相關函數的返回值並相加
而c源碼中這三個函數都是內聯彙編的形式
還是直接用gdb看看吧
題目和我們說了這是arm
通常情況下,arm以r0寄存器存返回值,對應在x86中就是eax
這一點從彙編中也可以看出
在這裏插入圖片描述
那麼在每個函數中r0的值是多少呢
一一看過來
先看key1
在這裏插入圖片描述
可以看到,pc->r3->r0,也就是說r0的值爲pc寄存器的值
這裏有個知識點
ARM屬於RISC,精簡指令及,分三段流水,取指、譯碼、執行
當mov r3,pc執行時,此時的pc爲當前指令地址+0x8,及0x8cdc+0x8

再看key2
在這裏插入圖片描述
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
在這裏插入圖片描述
執行紅框中的兩條指令後,r0的值等於lr的值
lr即r14,存放是函數返回地址
具體的值在main中可以看到,爲0x8d80

綜上,得key值爲108400
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章