CTF
Note: python *-c* <command>: 表示輸入command執行後的結果
原始碼
只要讓key變成0xcafebabe即可:
開 gdb
junk共有: 0xbffff500 - 0xbffff4cc = 0x34 == 52個byte
Note: 'cat -'的作用是防止shell馬上被關掉,保持跟shell的連線
也可以用pwntool
先執行一次
題目說了這是個reverse題,所以丟進ida
shift + f12先看字串
UPX是很簡單的殼,總之先脫殼(upx -d即可, -o可指定output file name)
脫殼之後的程式丟進ida就顯而易見了
先執行一次
總之先把檔案從遠端載下來(scp可以幫忙 -P port no:/remote_path /local_path)
原始碼
直覺想法是用welcome()寫入name的buffer來操控login的passcode值,gdb看一下會發現name會被寫在0xffffd3f8,而且可以寫100byte
第一種想法行不通,但用welcome()去蓋passcode的想法應該是對的,這時check一下保護機制看有沒有啥靈感
把rand()得到的值跟輸入的key做xor等於0xdeadbeef就可以得到flag
漏洞在於rand()如果沒有先用srand()傳入seed(就相當於每次都是用srand(1))
每次執行的結果其隨機數列順序會相同
所以只要先執行一次看rand()的回傳值(rax)就可以知道random的值
再把random ^ 0xdeadbeef就是key!!
stage1 :arrow_right: argv
stage2 :arrow_right: stdio
stage3 :right_arrow: env
stage4 :arrow_right: file
stage5 :arrow_right: network
通過條件:
解法
但因為/tmp/test
下沒有flag
, 因此使用軟連結將/home/input2/flag
連結到此目錄下
ln -s /home/input2/flag flag
最後結果
ARM指令集&THUMB指令集切換
bx
(Branch and Exchange)指令可以執行跳轉, 如果跳轉位址LSB(least significant bit)
blx
也可以執行跳轉,與上面不同的是, blx
會保存return address到LR
(Link Register)暫存器bx
或blx
執行跳轉之後,會設置T位
ARM指令集calling convention (AAPCS)
r0-3
傳遞,後面的用stackr0
r13
r14
ARM的pipeline
因為ARM指令地址為4byte對齊,可以用Pipeline提高執行效率
分成多個pipe (以4個pipe為例fetch
–> decode
–> execute
–> write
)
\時間 | t5 | t4 | t3 | t2 | t1 |
---|---|---|---|---|---|
指令3 (x+8) | fetch | decode | execute | ||
指令2 (x+4) | fetch | decode | execute | ||
指令1(x) | fetch | decode | execute |
pc指向fetch階段的指令.因此,當指令1正在execute階段時, 此時pc應該為指令3的位址 (即實際正在的指令1的位址+8)
分析
通過條件為 key1()+key2()+key3() == key
, 其中key
為輸入值
key1()
的asm –> key1 = 0x8ce4
key2()
–> key2
= 0x8d0c
key3()
–> key3
= 0x8d80
因此key應該為0x8ce4+0x8d0c+0x8d80 = 0x1A770 = 108400
提示為: Operator Priority
main程式碼中這一段, 因為"<"的執行優先於"=",因此會先執行 open("/home/mistake/password",O_RDONLY,0400) < 0
的判斷,
而只要檔案存在, fd必定>0,因此判斷結果為false(即0)
故後續=
行為中fd
被賦值為0
而fd=0
代表為標準輸入,即由標準輸入中讀取10byte –> 因此password可控
分析: 後續由xor()
程式碼分析可知為所有byte對1做xor
Linux process的UID
!=
文件的SUID (set user id) : 該檔案開放的存取權限passwd
指令設置了suid (x位被設置成s), 因此當user以普通user權限執行passwd
時, shell fork出一個subprocess, 而因為/usr/bin/passwd
設置了suid, 因此subprocess會獲得root權限,因此可以修改/etc/shadow
這個原本只能由root修改的檔案setresuid()
: 在process執行過程中動態的改變process的ruid, euid, suid
setresuid(200, 300, 100)
–> ruid=200, euid=300, suid=100setresuid(200, 300, 400)
–> 不成功, 維持ruid=100, euid=300, suid=200 (因為400不是其中一個id)Shellshock漏洞: bash中的漏洞,可以透過bash初始化環境變數執行任意命令
bash允許通過環境變數傳遞函數定義, 但並未檢查函數結束之後有無額外的指令
eg.
其中()
表示函數開始, {:;}
是一個空操作的函數定義
bash -c
會fork出一個child process, 會繼承Parent process的環境變數myEnv
是一個函數並嘗試解析其內容,而漏洞影響一併執行後續的惡意指令shellshock的修復方式: 檢查函數定義結束後是否還有額外代碼,如果有就reject其執行
題目分析
這些檔案的權限如下,並且可以知道使用者是shellshock這個group, 不可以讀flag(因為其他人無權限)
shellshock.c
告訴我們當shellshock被執行時,其所有id及gid會被修改成shellshock_pwn
(原本應該是shellshock
)
解法:
cat ./flag
)./shellshock
時
shellshock_pwn
/bin/cat ./flag
cat
檔案位置不然會找不到執行檔
nc
連接之後是一個遊戲:
使用binary search
是一個blackjack遊戲, 原始碼在這
進入遊戲隨便玩一下會發現dealer同一局的total增加值經常相同
看原始碼發現其中產生隨機牌的clubcard()
function中使用srand(time(null))
來產生隨機數
time(null)
返回的是當前時間距離POSIX 時間(Unix Epoch)的秒數。POSIX 時間的起始點是1970 年 1 月 1 日 00:00:00(UTC),並且其時間解析度只有一秒(表示最小單位是一秒)time(null)
值相同,srand()
在種子相同時會產生相同的結果,造成一秒內產生的隨機數會相同問題是在玩遊戲過程中還是無法掌握正確的隨機數…而且選擇需要時間
題目提示: 要一百萬才可以獲得flag
betting
函數中解法1: 第一次輸入正的不合法的bet,第二次直接打1百萬,並贏得遊戲
解法2: 第一次輸入負一百萬,並直接輸掉比賽