網路安全技能競賽 - 分區賽紀錄
緣起#
一切是從上學期第二堂高等資安攻防演練講師:前國手 Mico 大力宣傳,種下了技能競賽的種子,某種程度上這也算是一個資安屆的殿堂,就算沒坐在高位,曾經進到裡面也一定有收穫
第二次接觸是去年 (2024) 看到的大消息:海豹成為第 47 屆網路安全國際技能競賽銅牌得主,再一次接觸到技能競賽的名詞
第三次就是參加 2024 HITCON CTF 暨菁英人才交流活動,又遇到 Mico 給他安麗了一下
第四次就是看到報名消息,毅然決然決定組隊報名,於是展開了一段我獨自升級的旅程(啊不過是兩個人)
0327 Day1 淘汰賽#
規定是說北區超過 18 組就要進行淘汰賽,北區這次有 22 組選手報名,所以會在第一天就先進行淘汰賽篩選掉來體驗的 4 組選手
淘汰賽採紙本進行,40 道單選題,一題 2.5 分,答錯倒扣 0.5,同分以先繳交者獲勝,賽前我們很認真地計算過了,假設題目超級難,那每題答對的機率是 1/4,在每題都寫的情況下得分期望值為 2.5 * 10 + (-0.5) * 30 = 10 分,成績 range 就是 -20(來亂的) 到 100
淘汰賽考什麼?滿出乎意料的是範圍很雜,原本以為主辦方會想從淘汰賽測試選手的資訊概論能力,包含網路概念:TCP/IP Model、protocols 或硬體層面的作業系統、記憶體等等,實際上面相滿廣的,簡單的比如說「有人正在學習程式設計,迴圈的關鍵字可能是下面哪一個?」(答案為 for
)、或是「在 Linux 中如果想查看網路設備,應該用什麼指令」(答案為 ip
),這些都能一眼寫出答案,中等的比如說「在 Linux 中想查看某支 process 的記憶體 dump,應該去哪裡找」(答案為 /proc/[PID]/mem
)、或是「下列哪個不是 Windows Active Directory 工具之一」,這種可能就沒有那麼常見,甚至沒用過,但多少猜得出來,再難一點就是一些 Windows 的資安工具,比如說在 Windows 中檢索操作 Windows 作業系統中身分驗證訊息的 mimikatz、提權工具 juicy potato 等等
可以分享一個滿蠢的情境,題目問「如果我想要列出某個程式連結的動態函式庫,要用哪一個 Linux 指令」,選項大概就是 dll
, ddl
, ldd
, lld
,第一個刪掉的是 dll
啦!畢竟那是 Windows 動態連結函式庫名稱 (dynamic link library),ddl
也不可能,至少沒什麼看過她出現在 command 裡面(回來查之後才發現是 data definition language,跟資料庫有關),ldd
和 lld
就真的卡很久,怎麼唸感覺都很順,不過靠接觸 Linux 三四年的直覺還是猜對了,答案是 ldd
,全名為 list dynamic dependencies,如果考試時間再長一點,給我繼續唸我可能會覺得 lld
是對的,什麼 linked library dynamic 好像很合理
很幸運的我們有從淘汰賽中存活,倒也不是不相信我們會活著,只是很怕就這樣止步真的沒辦法跟 Neokent 交代就是了
0328 Day2 分區正式賽#
分區賽跟往年差不多,早上三小時的安全強化 20 分、數位鑑識(將近) 40 分,下午 CTF 40 分,主要 focus 在 pwn, reverse 和 web,不過鑑識那邊多了一個遊戲是 code review,是往年不曾見過的
安全強化#
這是最初我覺得要全拿的部分,但寫完歷屆覺得現場應該只能完成六七成左右
進到正式賽就先來一個不可思議,題目設計了一個平台,四題 Windows 四題 Linux,可以透過測試知道目前安全性問題,如果 patch 掉就能拿到 flag,目標就是拿到八個 flag 賺這 20 分
Windows 第一題是密碼長度最小值設定,按照過往經驗就是 WIN+R 輸入 gpedit.msc
打開群組政策編輯器,找到安全性原則改一改就好,但很嚴重的問題是這是本機端啊!題目要改的是域密碼策略,也就是從 AD 去改,現場找了很多 AD 的設定,似乎有找到,但不知道怎麼編輯,於是這題的 flag 就留在平台裡了。不過這邊還是放上解答,可以參考Microsoft 的教學文件:為 Active Directory Domain Services 設定更細緻的密碼原則
第二題是域控制器使用了 SMB 1.0,有安全性風險,想要我們處理,解法很直覺就是找到設定 SMB 1.0 的設定看要移除還是調高版本就可以,但這題一樣因為找不到設定的地方所以 flag 也留在平台裡。一樣留個官方解答:在 Windows 中偵測、啟用和停用 SMBv1、SMBv2 和 SMBv3
第三題是有一位 testuser 不符合安全性策略,滿好笑的是 Ray 從 domain administrator 中找到他移除就結束了,安全強化 += 2.5
第四題則是防火牆,要求遠端桌面只能存取特定 IP range 的連線,那就打開防火牆輸入規則中用戶遠端桌面連線的規則設定這一條就可以了,安全強化 += 2.5
接下來是 Linux,出乎意料的是 Linux 考題出在 WSL 上面
第一題屬實有嚇到我,先考了 ssh 的問題,倒不是不知道 ssh,只是覺得在沒有任何資源的情況下不確定能否解出來,這題是說 ssh 允許了 root 連線,題目覺得這應該禁止掉,不外乎就是從 ssh 的設定檔調整,在 /etc/ssh/ssh_config 裡面找到 PermitRootLogin yes
改成 PermitRootLogin no
就拿到 flag 了,安全強化 += 2.5
第二題是 ssh 用戶中有人不符合密碼原則,想要我把他抓出來,解法應該也是找到他 remove 掉就行,但滿可惜的是我不知道哪裡可以找到 ssh users,所以這題的 flag 就還給平台了
第三題忘記了
最後一題說 Linux 中有一個重要的檔案違反最小權限原則,想要我們把它的權限改為 000
,其實這題比較麻煩的是不知道所謂重要的檔案是誰,在 Linux 中第一個想到的多半就 /etc/passwd 和 /etc/shadow,但 000
是不是太低是我當時在猶豫的,不過嘗試總會帶出答案,在改完 /etc/passwd 後,flag 也跟著出來,安全強化 += 2.5
就安全強化的題目來看,跟往年的歷屆不是很雷同,但也都圍繞在很基本很重要的觀念,對於有在接觸 Windows AD 或真的處理過 Linux 設定的選手絕對不是問題
數位鑑識#
數位鑑識分成兩部分,一是 memory dump 的分析,另一個則是網路流量封包分析。沒有特別的分組,但主要來說 Ray 負責 memory,我開 wireshark 看封包
記憶體鑑識#
記憶體的部分,一樣問作業系統當作送分題、其他則是電腦名稱與當下使用者名稱、記憶體檔的惡意連線 IP、藏起來的特徵值等等
基本上起手式已經練到一拿到記憶體檔就 python2 vol.py --file=\PATH\TO\MEM\FILE imageinfo
開下去掃(這是在本機這樣做,但比賽當下 volatility 裝在 Windows,所以是跑到解題工具那邊下 volatility.exe ...
),沒意外都是 Win7,果真不出意外意外就來了,這次跑出 Win10,不太一樣沒關係,第一題作業系統 get!
起初是覺得就版本新一點,而且 Win10 我們更熟悉,還滿開心的,尷尬的是後面題目就解不太出來,起手式第二步通常是 pslist
、psscan
、filescan
、console
、cmdscan
這些開下去跑完再作分析,據 Ray 所述 filescan
是空的、console
沒什麼有意義的東西,再去看看題目說這次主要跟連線有關,換個 connscan
、connections
、sockets
、sockscan
等卻都沒有成功,這就是之前沒碰過的地方,volatility 噴一個「不支援 Win10 的 connection scan」,直接阻擋了我們針對連線作分析的手段,也因為這樣記憶體件事其實卡了超級久
柳暗花明又一村的契機是我看到題目要找 user name,想到之前解用戶密碼都是 hashdump
,至少可以看到哪些用戶,所以執行了一下列出可能解,Ray 在後面想到有時候裝函式庫需要自己設定環境變數,所以賭賭看有沒有檔案寫在環境變數,就可以透過檔案路徑發現 username,這個方法確實有效,能夠看到某些檔案路徑就寫著從 website 出發,可以先猜測 username 就是 website,更幸運的事其實 Windows 的環境變數裡就有紀錄 username 和 computer name 分別是什麼,成為更有利的證據。沒錯,記憶體鑑識再加一題!
個人認為有一個很酷的是今年考了特徵,有點像是找 flag,題目說記憶體中有一個 ws54{...}
的字串,想要我們找出來,剛好翻 volatility 的 help message 時最後一個叫 yarascan,可以指名 yararule 或字串進行搜尋,才想到這或許可以拿來利用一下,滿可惜的是嫂出來包含 ws54
的字串有三組,但都沒有後續 {...}
或像 flag 的長相,這題還是以失敗告吹
網路封包流量鑑識#
熟悉的 wireshark 最對味,有種夢回 112-2 去台大修計網的感覺
這個題組要我們看出這段封包在幹嘛,攻擊者 IP、受害者 domain name、攻擊者利用什麼漏洞取得主機控制權以及漏洞 URL,不要問為什麼我記這麼清楚,啊就我寫的咩!而且看封包看了好一陣子
簡單來說,我所看到的故事是有一個攻擊者很可疑的一直戳各種可能存在的檔案,受害者機器一直回 404 Not Found,看前幾個封包可以簡單看出誰是好人誰是壞人,也可以猜到接下來攻擊者會幸運猜中一個存在的位置做接下來的攻擊,入侵、取得控制權、躍權 blablabla 的
後續就沒有那麼明朗,有注意到眾多 404 Not Found 裡面成功的是攻擊者發送 POST request 到 photo.php,檔名看起來就很後門,答題的時候是猜攻擊者透過任意檔案上傳的漏洞上傳了一個 reverse shell 來取得主機控制權,如果是這樣那只要找到合理有利的證據就可以把封包鑑識全壘打,但同時也在懷疑這個 POST request 會不會只是在這個 php 上像是送表單的行為,所以是送出 malicious request,而 photo.php 只是受害者網站本身就存有的後門
Code review#
Code review 佔兩題,一題 3 分,這種題目不是沒寫過,高等資安攻防的時候 YinMuo 的作業就是從 Neokent 程設作業 example code 中找漏洞,當時還要寫 report,至少有寫過簡單的 PoC,這次只要簡單敘述,倒沒這麼難,只要能看出洞在哪就好
第一題是很良心的 SQL injection,短短幾行有出現 SQL 語句基本上八九不離十,加上沒有任何 filter、prepared statement,答案就很明確了
第二題是更良心的 buffer overflow,buffer overflow 的題目已經變成掃 pattern 了,看到 strcpy
和 gets
都會反射皺一下眉頭,因為都沒有針對長度進行過濾
看到 buffer overflow 的時候有再想會不會想考深層一點的 format string,但這次可能是第一年出,所以沒有多繞幾個彎,大膽預測明年後年 format string 可能會列入考題
CTF#
下午的 CTF 只有三個面向:pwn, rev 以及 web
Pwn 有兩題,基本上是超簡單的 buffer overflow
第一題搭配 command injection,題目會先問名字 (name
),問完之後問你想說什麼 (msg
),接著把 name
結合到指令 cmd
中,透過 system()
執行 echo
印出 “Hello, {name}!” 並再透過 printf()
將 msg
印出來,很明顯因為是 system
,我有很好的媒介可以拼湊指令得到 shell 的存取權。這題難在哪裡,因為指令要塞在 name
中,可能會想輸入 ';/bin/sh
這種名字,但在輸入完名字之後題目很討厭的去檢查 name 的輸入,如果遇到非小寫英文字母就說偵測到壞壞的字元結束程式,所以不能從 name 下手做壞事,那下一個媒介就是 msg
了,想要從 msg
寫到 name
就勢必得靠 buffer overflow,但接下來就是兩個碰過的問題,一是想要塞 argument 會需要空白字元(比如說 ' && cat flag
),但 scanf()
遇到空白字元會停止接收輸入,後面的東西就讀不到了;但這可以解決,比如前面提及的 ';/bin/sh
直接抓一個 shell 就好,不過那就是第二個問題,會遇到說 termination character 而出錯,這題就卡在這邊看很久沒下文
第二題是更經典的 buffer overflow,題目一樣 scanf("%s", buf)
給我輸入,但目標是要跳到一個同份檔案存在的 win()
函式,簡單來說我要把 scanf()
的 return address 改成 win()
的位置就可以解出這題,阿為什麼沒解出來?好啦!下禮拜開始回去資安攻防演練重上一次課
Rev 有四題,環境提供 ida free 和 ghidra 可以玩
第一題是 flag checker,但我用 strings
跑下去 flag 就出來了,那就這樣吧!不過還是仔細說一下這題,我沒有特別去逆這題的邏輯,但因為 strings
有東西,表示裡面邏輯應該是 if(input == flag)
,總之 CTF += 3
第二題是加密,需要我們逆向邏輯去解 flag,第三題沒特別看,但這兩題都沒去解
來到第四題,這次是 html 不是執行檔耶!題目叫做 magic number,提供了一個很像計算機的東西,要我輸入六位數字 (000000
到 999999
),如果猜對會把 flag 告訴我,嗯… Web 這種的應該 F12 下去看原始碼就好,裡面 script 說到會把 user 輸入的六位數字字串丟去 sha1 跑出 hash 值,hash 後的結果比對相符就會往下解出 flag,程式碼有了,邏輯都有了,寫個腳本去跑就好,那問題是什麼?我寫了一個 javascript 腳本從 000000
跑到 999999
,一個一個去試有沒有 match 到的 hash value,如果有我讓他停下來 alert()
跟我說,阿沒錯就是 brute force 解,我覺得 區區 10^6 一百萬種可能性,對眼前這台兩年前教育部整體發展獎補助的 ASUS ProArt PD500TC Intel Core i7 RTX 3060(再鞭會被萬能的萬能科大抓去約談)怎麼可能是問題,嗯結果 VM 被我玩壞了讓我重開一次,可能主辦方沒開很高的資源給 VM?其實測試的時候我很怕技術顧問海豹在我後面突然出現說「這位選手你再這樣破壞競賽環境就剔除資格喔」,這題剛好也在滿後期才解的,還是以失敗告終。其實如果回到 terminal 拿 python 出來寫,說不定可以寫很快,但我競賽當下不太確定 python 要跑這些邏輯確切的語法怎麼寫,比如說 python 裡面的 sha1 是不是需要 Crypt 函式庫,要的話環境有沒有允許,或是用 shell script 跑,但一樣 sha1 怎麼跑?
Web 有三題,一樣不是什麼難題,經典的 php injection、資料庫注入和 MD5 decrypt
第一題是留言板,檢視原始碼發現讀取留言板內文的邏輯是透過 PHP 語句渲染 HTML,表示我可以從中寫入壞壞的 PHP 取得 flag,好一個 PHP 我還不會
第二題要先輸入帳號密碼,很明顯就資料庫的洞,為什麼不說 SQL injection,因為測試後發現應該不是拿 SQL 寫的,CTF 賽結束後聽旁邊選手交流似乎是 NoSQL,好吧!那我認了
最後一題一樣要先輸入一個 secret 登入後,可以存取一個上傳文件的頁面,所以應該是複合式題目,後面還要做一個 reverse shell 上傳,後話就不談了,先來說 secret 怎麼得到,題目給一個 hint 說 MD5 後的值,ㄟ MD5?那就是弱密碼 john 一下囉?我記得 rockyou 是海豹比的那一年最後讓他們獲勝的一個小關鍵,如果這次出題跟他們有關係,那就是 john 了!我超級開心的把 MD5 hash value 抓下來丟到 terminal 上拿 rockyou john,結果破解不出來,一度還想是不是我一直忘記 john 的用法,甚至跑了 admin
的 MD5 hash value 測試,但就可以破解的開,表示不是指令問題,那就…?這題卡在這關就先結束了
整體來說 CTF 難嗎?不難啊絕對不難!Pwn 那種題目有基本概念解一下絕對不是問題,rev 題二三沒看姑且不說,第四題會寫腳本跑一下就結束了,Web 看的到洞應該就可以解出來,跟以往國內 CTF 比賽相比是很親民了
心得 && 致謝#
雖然說止步於分區賽,但目標算是達到了。這次經歷絕對絕對不能說是毫無收穫,因為三個月的準備歷程比之前任何一次資安競賽都還要盡力,CTF、靶機也打得比之前兇
人生第一次的技能競賽,倉促的組隊、報名,很多東西都是靠著兩個學生的手邊資源慢慢摸索得到,去年年底報名完,到寒假開始準備,寒假會乖乖寫 CTF,把 pico CTF 的 easy 都完成,從 medium 開始只要有解出來就寫 writeup,開學之後針對技能競賽的歷屆學習新技能,安全強化從熟悉的 Linux 開始,學到 ACL 的概念、iptables
也再次理解,怕正式賽出憑證,還回去看 SEED LAB PKI 的 lab 搞懂 openssl
的指令和邏輯;Windows 則是在 AWS 上開了一台 Windows Server 2022,花了幾天的時間嘗試密碼原則、users、groups 的設定;鑑識比較晚開始,但也是學習了 volatility,也玩了一些 memory forensic 的 labs,不確定會不會有特別的鑑識,在 pico CTF 上也特別著重在鑑識題目的訓練,認識一堆圖片鑑識的工具,什麼 zsteg
、steghide
等等,也為了應對技能競賽的 CTF,在正式賽前兩三禮拜順便參加了 pico CTF 2025,維持刷 CTF 的手感
當然要謝謝跟我一起參加比賽的 Ray,在資安圈 Ray 絕對是新手,結果就被我抓來一個技能點要求極高的活動,競賽兩天從新北大老遠到超偏僻的萬能科大(萬能科大不排除提告),希望這三個月不會讓你對資安打退堂鼓
下一個要感謝的應該是上學期高等資安攻防演練課程整整 16 週遇到的種種,因為那堂課讓我正式接觸到滲透、攻擊鏈這些更進階的知識,雖然從那堂課之後進展差不多就是認識了一些新名詞,有沒有真的搞懂、甚至會活用是另一個問題,但比起甚麼都不懂,「這個名詞好像有聽過」好很多,至少知道可能成長進步學習的方向
最後給想參加技能競賽而且花時間讀到這裡的讀者一些不專業建議,畢竟網路上有寫技能競賽準備過程、心得或 writeups 的不像一般 CTF 一樣關鍵字下一下就跑出一堆
- [報名] 技能競賽報名時間很短,確定要比賽之後一定要隨時關注官網,簡章時程也要全部先列進去行事曆,根據大前輩 Mico 說最難的關卡就是報名,過了這關已經贏過很多人了
- [報名] 一定要注意郵局關門時間和學校用印時間,最好預留兩天跑流程,當初為了讓報名表給學校用印還需要找系主任和學院院長簽名,這關就卡了一天(尤其當你要找人時,那個人一定剛好不在)
- [報名] 技能競賽需要有培訓單位,以學生來說就是學校,但需要找一個老師作為指導老師,這個需要先找,同時也表示不能玩玩而已,畢竟掛了學校和老師的名字
- [報名] 網路安全組需要兩人組一隊,所以找一個可靠的隊友也需要事前準備
- [報名] 政府主辦的活動,聯繫方式只有電話,mail 什麼的找不到
- [報名] 需要準備 400 塊,但以今年分區賽來說拿到小禮物和三份餐盒一份便當,應該是賺吧?
- [準備] 最好的準備方式就是跟著歷屆準備,考點很明確,可以從裡面學習到需要的技能
- [準備] 事前公布的工具表也是準備方向之一,至少要熟悉裡面提到的工具,版本可能是需要考量的因素,像是今年 volatility 給 2.6 版,但現在比較多都用 3.0 版本,因為 2.6 版是用 Python2 在跑,現在誰還在 Python2?為了環境問題也是處理了好一陣子
- [競賽] 不能連外網、不能連外網、不能連外網,這點最重要,大多數網路安全競賽都是網路吃到飽,但技能競賽不允許連網,所以很考驗選手各方面知識廣度
- [競賽] 呈上一點,網路安全有一個 partner,不完全要求一定要當全能的神,所以「分工」顯得很重要,好的分工可以減輕準備的負擔
- [競賽] 這次 CTF 有提供 Cyberchef,但不能保證一定會提供,可以先準備如何使用 command line、各種程式語言做各種 encode, decode
- [競賽] 賽後記得留下來聽裁判講評,會說一些出題者策略、希望選手學到的技能,或許會被點出一些還可以嘗試、學習的方向
- [心態] 參加競賽一定會想要拿到一個名份,但記得在過程中嘗試理解「主辦方想要透過競賽告訴你什麼」,每個出題者在出題時通常都會去想希望答題者怎麼解題,需要用到什麼觀念,某種程度上跟著出題者的設計走完全程一定會是收穫滿滿的