這是我接觸 ctf 後第一次正式的比賽 > <。AIS3 pre-exam 是跟 My First CTF 一起舉辦的,很可惜的是今年因為疫情所以改為線上舉行 QQ。
這次線上要掛 vpn,用的是 wireguard。然後我在賽中才發現忘記在 VM 裝,花了一小時還是裝不起來,最後只好跑去裝 Windows 版的 netcat。
因為窩弱所以這個 write up 題目應該會很少吧 QQ
Welcome
開賽前助教就已經在 discord 傳了 flag。而且題目敘述還是 discord ++。笑爛wwww
Crypto
SC
題目給的資料夾裡面有加密用的 python 檔、加密過的 flag 、加密過的加密 python 檔(?
而 code 下面則是一串關於替換式密碼的維基百科
所以直接比較兩邊的字母,建立替換表,最後把加密過的 flag 逆回去就好了。
1 | plain = 那一大串明文 |
Flag:
1 | AIS3{s0lving_sub5t1tuti0n_ciph3r_wi7h_kn0wn_p14int3xt_4ttack} |
Fast Cipher
在給的加密程式中有一段 encrypt()
函數
1 | def encrypt(pt, key): |
可以看到會一個個將明文對 key 進行 xor
透過 flag 第一個字一定是 A 可以得到 key 是 0x2D
接下來反著做回去就好了
1 | cipher = "6c0ec840f88d4cd7fcc6d5c6d1dafcc1cad7d0fcc2d1c6fcd6d0c6c7fccfcccfde" |
Flag:
1 | AIS3{not_every_bits_are_used_lol} |
Misc
Excel
下載檔案後查看巨集,單步執行然後查看評估值,就得到答案了
Flag:
1 | AIS3{XLM_iS_to0_o1d_but_co0o0o00olll!!} |
哭挖然後這題那時候卡在 flag 最後是 l 而不是 1 和 |
Gift in the dream
用 strings 可以看到這個 gif 裡面有一堆的 why is the animation lagging? why is the duration so weird? is this just a dream?
通靈了一下然後跑去用工具查看了這張圖裡面各個幀之間的間隔,發現都在 ascii 可視字元的範圍內
所以寫了以下來解碼
1 | delay = [65, 73, 83, 51, 123, 53, 84, 51, 103, 52\ |
Flag:
1 | AIS3{5T3g4n0gR4pHy_c4N_b3_fUn_s0m37iMe} |
Pwn
SAAS - Crash
本來看 source code 沒看出什麼東西,試著構造可以 overflow 的字串也被擋了下來,不過後來在這系統裡面玩了一下,不知道是因為我的奇怪操作還是因為其他原因,他就自己噴 flag 出來了 www。
Flag:
1 | AIS3{congrats_on_crashing_my_editor!_but_can_you_get_shell_from_it?} |
Bof2Win
看 source code 發現可以 bof ,並且有一個函數 get_the_flag()
沒有被調用到,看起來是要覆蓋 return address 到這個函數就可以到 flag。
首先丟進 gdb 看看 get_the_flag
的位置在哪裡
先丟一串東西進去看看 offset
1 | AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSS |
0x47 是 G,0x48 是 H
所以可以知道 rip 存在 G 跟 H 的位置
把剛剛拿到的 get_the_flag() 位置替換進去 (注意 little endian)
可以得到要注入的字串:
1 | "AAAABBBBCCCCDDDDEEEEFFFF\x16\x12\x40\x00\x00\x00\x00\x00" |
用 pwntools 送過去就可以得到 flag 了:D
1 | from pwn import * |
Flag:
1 | AIS3{Re@1_B0F_m4st3r!!} |
Reverse
Time Management
丟進 Ghidra 後看到以下的東西
14 行有一個 sleep 會讓程式執行很久
一開始我本來想要用一個在 picoCTF 的 writeup 看到的方法
就是自己寫一個假的 sleep()
然後把他編譯成 object 檔並且用 LD_PRELOAD 讓這個假的 sleep()
跟著程式一起執行。但是有 fflush()
所以讓 flag 的文字沒有出來 QQ
所以只好用 gdb 來一步一步做,遇到 sleep 就跳過去。
設下兩個 break point,135 是 sleep,157 是 printf。兩個的位置是從前面的 disassemble main 指令得到的
然後只要每次到 sleep 那邊就下 set $pc = *main+140
來跳到下個指令
接下來 c
來繼續
因為這邊 printf() 有兩個參數:%c
和 local_14
,local_14 是我們想要的,而且根據 calling convention 可以知道這個會放在 rsi 裡面
printf() 會拿最後一個位元組來輸出,而 0x41 正好就是 A,0x49 是 I。
只要一直重複 c
和 set $pc = *main+140
就可以拿到 各個字元了 > <
1 | cipher = ["41", "49", "53", "33", "7b", "59", "6f", "75", "5f", "61", "72", "65"\ |
Flag:
1 | AIS3{You_are_the_master_of_time_management!!!!!} |
Web
Poking Bear
觀察網頁可以看到每隻熊是透過 /
後面的數字來定位的,不過前往 secret bear 的頁面的按鈕沒辦法點..
所以用爬蟲一個一個戳,看看還有哪些是開的
1 | import bs4 |
可以發現 499 有熊在那邊,去那邊也發現的確是 secret bear。
不過跟他要 flag 他說要是 bear poker
才可以拿…
打開 f12 後發現 cookie 裡面有一個叫做 human 的 cookie
把他的 value 改成 bear poker
後就拿到 flag 了:D
Flag:
1 | AIS3{y0u_P0l<3_7h3_Bear_H@rdLy><} |
Simple File Uploader
網站是簡單檔案上傳者
那大家上傳的 code 算不算簡單檔案上傳終結者:thinking_face:
看看 source code 發現他沒有檢查副檔名的大小寫,所以上傳 .pHp
發現 server 給過而且還會執行。
1 | //First approach |
因為 server 會擋含有 dirscan()
的東西上傳,不過沒擋到 glob()
:D
所以用 glob()
掃根目錄有什麼
1 | // Second approach |
發現有一個非~常可疑的檔案 /rUn_M3_t0_9et_fL4g
不過有擋 exec()
和 eval()
查了一下發現 backtick 也可以執行指令:DDD
1 |
|
然後就得到 flag 啦 ٩(ˊᗜˋ*)و
Flag:
1 | AIS3{H3yyyyyyyy_U_g0t_mi٩(ˊᗜˋ*)و} |
心得(?
1 | Final Rank: 96 |
這是我第一次參加這種活動,但沒上真的很可惜QQ
希望甄選有機會上囉:D
中間卡了好幾題,像是 reverse 的殼
和 misc 的 knock
,knock
更是卡了我整整一天,看著越來越多人解出來,而那題的分數越來越下降真的很讓人挫折…
殼
沒有解出來真的很遺憾,這還讓我想到 picoCTF 上面有一題超爛的 rockstar,解 rockstar 的時候真的是折騰了好久,不過最後沒有解出殼
是遺憾之一。
然後我真的一直把 knock
當 web 題,nmap 掃 port 後看到 139 和 445 有開,而且 nmap 也說那邊有 smb 服務,就一直往 smb 去解…結果是用 wireshark 錄封包…
但是那種拿到 flag 的開心感最令我難以忘記,尤其是 bof2win
,因為這是我第一次實作覆蓋 return address (之前只有聽 liveoverflow 講過),真的很令人開心 ٩(ˊᗜˋ*)و
本文章同步發布於 HackMD