DEVCORE-Wargame-2023
first-flag(有點忘記,應該是叫這名子沒錯)
隨便輸入一串 user,登入後會要你輸入 flag,超過 5 分會給你這一題的 flag
(搞笑的是我一開始以為 flag 是 FLAG{this_is_the_first_flag}
,拿去輸入想說怎麼是錯的)
看 session,感覺有點東西,於是 base64 decode,嗯?感覺 exp 可以用。
1 | 0 point |
於是試著改 session 中的 exp,發現 seesion 會直接失效,推測是有驗 hmac。但我稍微試了一下,實在摸不出 hmac 怎麼算的。
於是我想說這題太難了吧,而且大家第一題都解這個,根本不是交了 5 個 flag 的樣子 = =。
前前後後試了快 3 hr,突然靈機一動想到我是不是可以登這些解過的人的帳號,看他們的 flag,還真的有些可以登,結果這些人的帳號也都是 1 分 2 分,三小,那他們跟誰拿 flag 的?
我想到了,admin
嗚嗚嗚終於,順便看了一下 session,感覺 exp 好像真的有用到。
1 | 0 point |
redpill
題目給了一個沒任何說明的檔案 redpill
依據經驗,我猜這是一個逆向題(??),先收集一下資訊
1 | # wsl ubuntu |
依據 file
strings
和把 8cc8 8ed8
餵狗的資訊,推測這確實是 MBR 的磁區,開頭是 boot loader 的初始化。
並且從 strings
看不出任何 flag 的資訊。嘗試進行更深入的資訊收集
- 靜態分析
- 把這個 MBR 檔案執行起來,動態分析
靜態分析 1
在這邊我使用 radare2 做逆向
為啥不用 IDA Pro?因為手邊剛好只有 IDA free…,開不了 PE 以外的東西🥹。
我的做人,我的作法,沒錢的人,沒錢的做法。爬了一下文,感覺 radare2 可以試試就拿來上了,
順便學一下別的 decompiler 怎麼用。(而且感覺拿 IDA Pro 會瞬間做完很多事,這題可能會秒殺,會很無聊)
可以看到,斷在 0xffffffff8966e402 不知道這什麼地方。(其實這邊我 decompiler 的設定有誤,後面會說明)
動態分析 - 載入 MBR
爬了超久,關於怎麼載入、debug MBR 的資訊,因為一開始不知道要下哪些關鍵字,找到的內容都很瑣碎,重複嘗試了三個晚上。
最後主要是透過下面這幾篇的說明,我才搞懂要怎麼使用模擬器載入一個 MBR。
- Debugging MBR - IDA + Bochs Emulator (CTF example)
- How to make a simple disk image - Bochs User Manual
- Create flat image
- Set
bochsrc
file (Search order for the bochs config file)
- 《操作系统真xiang还原》阅读实践问题记录 bochs [HD ] ata0-0: could not open hard drive image file ‘hd60M.img
個人載入的步驟如下,使用了 bochs 這套模擬器 (qemu emulator 似乎也行,但我沒研究)
- 使用 bochs 的
bximage.exe
建立一個 10MB flat image,叫redpill.img
- 生個 bochs 設定檔,這裡叫
bochsrc.bxrc
,看是要用 bochs GUI 還是自己寫一份都行,我是用 GUI。1
2
3
4
5
6
7megs: 512
romimage: file="C:\Program Files\Bochs-2.7\BIOS-bochs-latest"
vgaromimage: file="C:\Program Files\Bochs-2.7\VGABIOS-lgpl-latest"
boot: cdrom, disk
ata0-master: type=disk, path="redpill.img", mode=flat
mouse: enabled=0
cpu: ips=90000000 - 將 redpill 的內容覆寫到
redpill.img
的開頭1
2
3
4with open('redpill', 'rb') as f:
mbr = f.read()
with open('redpill.img', 'r+b') as f:
f.write(mbr) - 開始 debug image 的載入
bochsdbg.exe -f bochsrc.bxrc
靜態分析 2
參考Solving the Disobey 2020 puzzle bootloader using Unicorn and Ghidra
觀察 bochs dbg diasm 後的內容,確認了 “靜態分析 - 1” 中幾件我搞錯的事
- radare2 的 cpu 模式要設成 16 bits 才對,boot 的時候 CPU 是 real mode
- 最後 jmp 是跳躍到 0x6000
重新設定 r2 disam 後再從頭分析一次,可以知道 0x6000~0x6600 應該是 call 0x60 時做了某些操作後產生的 code。
來看看 0x60 做了甚麼事,原來其是將對應 LBA sector 的內容拷貝到對應的記憶體上。
回到 0x00 的 asm,0x6000 ~ 0x6600 應為 image 的 sector 1 ~ 4 的內容,每一 sector 大小為 0x200,對應 image offset 0x200 ~ 0x800。
參考資料
- 自己動手從零寫桌面作業系統GrapeOS系列教學——21.組合語言寫硬碟實戰
- 0x1f0 ~ 0x1f7 是
- Master boot record - Wiki、计算机是如何启动的?、- [筆記] 為什麼在 x86,MBR 會被載入到 0x7C00?(完全版)
- MBR:大小為 0x200 Bytes,offset 0x1FE 為 0x55 0xAA
- MBR 會被載入至 memory address 0x7C00 執行
- LBA and sector size - Superuser
- 1 sector = 0x200 Bytes
- 硬盤訪問概述
- 延伸閱讀 - 硬碟心得 - CHS、LBA
- 延伸閱讀 - 邏輯區塊位址
- 分段架構: Segment Selectors 和分段暫存器
靜態分析 3
接下來進行 0x200 的分析,並嘗試快速定位 flag 的判斷位置。
當 flag 輸入錯誤時,會顯示 ACCESS DENY 的文字。而 ACCESS DENY 在 file offset 0x745 (應對應 memory 0x6545)。
翻翻看哪個指令使用了這個字串,可以推測重點的判斷邏輯就在附近。
快速瀏覽一遍 0x200 後,可以發現用了大量的中斷,查了後這些中斷都蠻好懂的,能很大的幫助理解邏輯。
例如 0x237 - 0x278 這邊的迴圈是通過 int 0x16
取得鍵盤輸入,並呼叫 int 0x10
將其輸出到螢幕上,以及將輸入記錄到 buf 中。
那我們就可以很直接的知道這邊是處理我們輸入 flag 的互動實作。
最後追到使用 ACCESS DENY
的 0x307,前面的 asm 則是使用 0x6585
、0x65af
做了某種處理及比對。
先檢查一下這兩個 buf 執行前的內容
動態 + 靜態分析 4
為了確認 0x6585
、0x65af
這兩個 buf 在 runtime 進行處理、比對時的內容,直接在進入比對前的 0x6097
下斷點。
檢查這時的 buf 內容,可見 0x6585
為使用者的輸入內容,0x65af
為 secret,跟靜態分析時的內容相同。
確定了輸入是與 secret 進行某種操作比對後,直接針對這邊的實作進行逆向,得到邏輯大概是長這樣
1 | secret[i] = input[i]*3 - input[i+1]*2 |
原來是要解個二元一次方程式阿…開始寫腳本
1 | def decode(v1, v2): |
得到 flag DEVCORE{4r3_w3_al1_liv1ng_in_th3_ma7ri><?}
(最後面那個 word 到底是甚麼我想了很久,想到題目是 redpill,借助 google 的協助才知道是 matrix…)
其他題
沒解到就關了,88