0. fd
- 原始碼
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- read(fd, *buf, size):
- fd(file descriptor)
- 0: stdin(standard input: 從鍵盤輸入)
- 1: stdout
- 2: stderr
- 目標: 讓fd = 0,讓read可以順利再讀取"LETMEWIN"到buf中
- 使argv爲0x1234即可,轉爲十進制是4660
- atoi = 字符轉為integer
- 在terminal輸入"./fd 4660"後可以再輸入一行(就是要放進buf的東西),輸入"LETMEWIN"並送出就可以獲得flag
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
1. Collision
- 原始碼
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- check_password(..20byte..): 會把20byte拆成5個int相加,只要等於hashcode(= 0x21DD09EC)就會噴flag
Note: python *-c* <command>: 表示輸入command執行後的結果
- 想法1: 0x0+0x0+0x0+0x0+0x21DD09EC
-
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- 想法2: 0x01010101 * 4 + 0x1dd90518
-
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- 想法1不成功的原因是因為0x00會被視為空字元,因此我們以為輸了20byte,其實只收到0x21DD09EC
- EX. 實際輸入22byte,但依然會成功(因為2個0x00被視為空字元)
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
2. bof
-
原始碼
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
只要讓key變成0xcafebabe即可:
-
開 gdb
- 斷點下在call gets的地方候用ni,並輸入aaa…,a的ascii是61,因此知道overflowme會從0xbffff4cc開始寫
- 且0xbffff500就是0xdeadbeef位置,也就是我們要overflow成0xcafebabe的目標
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
junk共有: 0xbffff500 - 0xbffff4cc = 0x34 == 52個byte
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Note: 'cat -'的作用是防止shell馬上被關掉,保持跟shell的連線
-
也可以用pwntool
3.flag
-
先執行一次
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
題目說了這是個reverse題,所以丟進ida
-
shift + f12先看字串
- 看到upx…?
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- hex裡面也可以看到這支程式被upx加殼惹
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
UPX是很簡單的殼,總之先脫殼(upx -d即可, -o可指定output file name)
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
脫殼之後的程式丟進ida就顯而易見了
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- sub_400320不確定是什麼就丟進gdb跑跑看(會jmp到某個offset)
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
- 但其實沒差,點ida上的flag就可以找到flag惹
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
4.passcode
-
先執行一次
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
總之先把檔案從遠端載下來(scp可以幫忙 -P port no:/remote_path /local_path)
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
原始碼
- 第9&14行的scanf沒有&(正常應該是類似scanf('%d', &a)),也就是說scanf其實完全無法寫入passcode,而是會把指到passcode的位址上的垃圾(之前stack的殘留物)當作passcode繼續執行
- 第17行: passcode1 = 338150 = 0x528e6
passcode2 = 13371337 = 0xcc07c9
- 第37&38行,先執行welcome在執行login,而且中間沒有多餘的操作,也就是說,這兩個function一開始執行的esp & ebp一樣
- welcome()執行前的esp & ebp

- login()執行前的esp & ebp

-
直覺想法是用welcome()寫入name的buffer來操控login的passcode值,gdb看一下會發現name會被寫在0xffffd3f8,而且可以寫100byte

- scanf('%d', passcode1):
ebp-0x10=0xffffd458中的值會被當作passcode1要被寫入的位址,以下圖的例子就是passcode1會被寫成0xf7e4636b(這個值純粹是stack上的垃圾,所以如果這個值是不可寫的地址就會crash)

- 也就是說,要想辦法在welcome()去把0xffffd458蓋成0x528e6
- 同理,也要把passcode2 = ebp-0xc = 0xffffd45c蓋成0xcc07c9
- 但welcome()的name只寫100byte(0x64),蓋到passcode1需要0x60+4byte沒問題,但無法蓋到passcode2(0x60+4+4)QQ
-
第一種想法行不通,但用welcome()去蓋passcode的想法應該是對的,這時check一下保護機制看有沒有啥靈感
- Partial RELRO表示Link map不可寫,但GOT可寫
- 有Canary, stack有開NX,表示stack無法執行shellcode
- 沒有開PIE,表示code段跟data段固定

- passcode1跟2最大的區別在於scanf passcode1之後做了一個fflush(),login()裡面直接執行system("/bin/cat flag"),因為沒有PIE,所以這個system("/bin/cat flag")的位址固定
- call library時,會跳到plt,再從plt跳到GOT table中對應的位置(以下圖為例就是0x804a004)

也可以用objdump -R passcode查看

- system("/bin/cat flag")的位址用objdump查看,0x80487af是"/bin/cat flag"字串的所在位址

- 目標是把fflush()在GOT的位址(0x804a004)hijack成system("/bin/cat flag")的位址(0x80485e3)
- scanf("%d", passcode1)時會把ebp-0x10上的值當作輸入寫入的地方,所以在這之前(welcome()階段)要把ebp-0x10覆寫成fflush()的GOT位址
- 執行scanf(.., passcode1)時輸入0x80485e3,這樣就完成GOT的hijack(但scanf("%d"),所以要記得轉成str去放)
- 最後執行到fflush()時,實際上是執行0x80485e3的指令
-
sol.py

5. random
- 想法:
-
把rand()得到的值跟輸入的key做xor等於0xdeadbeef就可以得到flag
-
漏洞在於rand()如果沒有先用srand()傳入seed(就相當於每次都是用srand(1))
每次執行的結果其隨機數列順序會相同

-
所以只要先執行一次看rand()的回傳值(rax)就可以知道random的值
再把random ^ 0xdeadbeef就是key!!
- random = 0x6b8b4567 (即上面第一個產生的1804289383)
- 0x6b8b4567 ^ 0xdeadbeef = 0xB526FB88 = (int)3039230856

-
stage1
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
argv
- 通過條件
- arg數量(argc)為100
- argv[65] = argv['A'] = '\x00'
- argv[66] = argv['B'] = '\x20\x0a\x0d'
- 解法
- 執行結果
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
stage2
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
stdio
- 通過條件
- stdin(0)裡面前4byte為\x00\x0a\x00\xff
- stderr(2)裡面前4byte為\x00\x0a\x02\xff
- 解法
- 執行結果
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
stage3 :right_arrow: env
- 通過條件
- 存在名為'\xde\xad\xbe\xef'的環境變數且值為'\xca\xfe\xba\xbe'
- 解法
- 執行結果
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
stage4
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
file
- 通過條件
- 有個叫'\x0a'的檔案,前4byte為\x00\x00\x00\x00
- 解法
- 遇到的問題
'\x0a'在本地端無論怎麼試都無法創造這樣檔名的檔案
於是嘗試直接在input2@pwnable.kr直接試
但因為/home/input2這個資料夾被設定為不可寫…
最後只好把'\x0a'放在/tmp/test底下
也只能整個sol都改成在/tmp/test底下執行
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
stage5
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
network
-
通過條件:
- 開啟一個tcp監聽port(port號由argv['c']傳入)
- 向這個port發送"\xde\xad\xbe\ef"
-
解法
-
但因為/tmp/test
下沒有flag
, 因此使用軟連結將/home/input2/flag
連結到此目錄下
ln -s /home/input2/flag flag
-
最後結果
Image Not Showing
Possible Reasons
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
Learn More →
7. leg
7. mistake
8. shellshock
-
Linux process的UID
- ruid (real uid) : 創建該process的user id
- euid (effective uid) : 該process的存取權限(通常=ruid)
- suid (saved set-user-ID) : 用來保存process之前的euid,以便於改變權限之後恢復
!=
文件的SUID (set user id) : 該檔案開放的存取權限
如果執行檔設置了suid,則所有user都可以透過執行這個檔案獲得root權限
- eg:
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
- 如果執行Process的euid為root(=0),可以設置成任何id
- 如果執行Process的euid不是root,只能將id設置為(ruid, euid, suid其中之一)
eg: 假設ruid=100, euid=300, suid=200
執行setresuid(200, 300, 100)
–> ruid=200, euid=300, suid=100
執行setresuid(200, 300, 400)
–> 不成功, 維持ruid=100, euid=300, suid=200 (因為400不是其中一個id)

-
Shellshock漏洞: bash中的漏洞,可以透過bash初始化環境變數執行任意命令
-
bash允許通過環境變數傳遞函數定義, 但並未檢查函數結束之後有無額外的指令
-
eg.
其中()
表示函數開始, {:;}
是一個空操作的函數定義
- 第二行
bash -c
會fork出一個child process, 會繼承Parent process的環境變數
- 因此當初始化環境變數時,child process會識別到
myEnv
是一個函數並嘗試解析其內容,而漏洞影響一併執行後續的惡意指令
-
shellshock的修復方式: 檢查函數定義結束後是否還有額外代碼,如果有就reject其執行
-
題目分析
-
這些檔案的權限如下,並且可以知道使用者是shellshock這個group, 不可以讀flag(因為其他人無權限)
- 但同群組權限為可讀 –> 可以透過shellshock開啟

-
shellshock.c
告訴我們當shellshock被執行時,其所有id及gid會被修改成shellshock_pwn
(原本應該是shellshock
)
-
解法:
- 由shellshock權限的user定義一個函數塞進環境變數, 此環境變數定義的函數功能要包含讀取flag(
cat ./flag
)
- 當
./shellshock
時
- shellshock的euid被設置成
shellshock_pwn
- 環境變數x被解析,執行後面的
/bin/cat ./flag
- note: 必須指定
cat
檔案位置不然會找不到執行檔

9. coin1
-
nc
連接之後是一個遊戲:
- 有N枚硬幣,其中一個是假幣,要在C次秤重內找到假幣的index, 共有100輪, 需要在60秒內完成

-
使用binary search


10. blackjack
-
是一個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
-
解法1: 第一次輸入正的不合法的bet,第二次直接打1百萬,並贏得遊戲

-
解法2: 第一次輸入負一百萬,並直接輸掉比賽

11. lotto
- 看原始碼, 沒有考慮使用者是否輸入重複數字,因此在兌獎環節的時候,如果輸入byte全部一樣,只要有對中其中一個就可以全中
- 解法: 輸入全部一樣byte(需再1-45之間),運氣好的話幾次就中了
