其實正式名稱是 台交網路攻防搶旗賽 XD

Attack - Defense 形式的 CTF

是台大計算機安全和交大程式安全兩門課的期末考

其中台大 9 隊,交大 6 隊,加上一台讓人家打的 NPC,一共 16 隊參加

因為考試形式特殊,加上各方宣傳的關係

結果搞到上新聞了XD ( link1 , link2 )  ( 話說是 bruce30262 不是 bruce20362 啊啊啊啊啊 )

跟實驗室同學組成了 DSNS 參加

合力拿下了第三名的成績!

 

=====================================

 

賽前準備

 

因為在交大程式安全課程裡面幾乎都在教怎麼 attack

關於 defense 的技巧只花了一堂課來介紹

因此賽前準備就特別著重在 defense 的部份

attack 方面就是靠平時累積的實力硬上這樣@@

 

defense 的話除了課堂上教過的 wrapper , hook ( LD_PRELOAD ) 和 binary patch 之外

還另外看了一下台大 CTF 課程教的其他奇技淫巧(ptrace, seccomp....)

看得差不多之後就開始寫 wrapper 和 hook

 

wrapper 簡單來說就是一個程式

將原本的 service 包起來

兩者之間透過 IPC 溝通

這樣子有連線一進來,我們就可以先對這個連線動一些手腳,再將其餵給真正的 service

好處就是我們可以隨時掌控 service 的執行情況

壞處就是很容易 service check failed = =

 

我們將 wrapper 分成了兩個版本 : pipe 版跟socket 版

兩者的不同在於它們分別是用 pipe 跟 socket 的方式跟原本的 service 做溝通

功能除了用來溝通原本的 service 之外

還多加了過濾字串和將連線記錄 log 起來的功能

此外還加了 ptrace 跟 seccomp 來監控 service 的 system call (不過正式比賽時被禁就是了= =)

 

hook 則是要自己寫一個 shared librery

在真正的 service 被呼叫起來的時候

只要這個 service 是一個 dynamic link 的 ELF

我們就可以透過設定 LD_PRELOAD 這個環境變數

將我們自己寫的 library load 進程式裡面

這樣一來我們就可以 hook 一些 function

像是 system()之類的

另外也可以透過將 function 的 attribute 設成 constructor 的方式

讓自己寫的 function 能在 main function 之前被執行

進而對 service 的 binary file 做一些 dynamic patch 的動作

 

這個部分比較特別的是使用到了random libc 戰術

自己編好一堆 glibc.so

然後 service 啟動時用隨機挑選一個 libc.so, 使用 LD_PRELOAD 動態載入

這樣子就可以適度防止 return to libc 的攻擊 (無法確定正確的function address)

除此之外實作了 hook system() 和 constructor function 

並利用 constructor function 被呼叫的時候做了 dynamic patch 的練習

還有就是和隊友用 ascii art 畫了根 dildo,想說可以用來嘲諷對手wwwwww

 

binary patch 的話就是純靠經驗了

這裡我只跟另外一個同學拿程式安全的作業,花了一個晚上的時間練習而已

主要就是 patch 的時候要注意 machine code 的長度

patch 這個動作本身不會很難,重點是在於要想說"怎麼patch"

 

除此之外就是準備 script 了

像是備份,監控 process 執行情況....等等

然後就是進行分工

DSNS 一共有 5 名隊員

基本上我跟健賀負責 binary 的部份

attack 交給他,defense 交給我

script 和整台機器的監控工作則是交給宗育

鄭白和鼎文則是負責 web 題

 

是說賽前看了一下參賽隊伍名單

在 <(_ _)>shik 裡面赫然發現了 217 大神 時丕勳 的名字 ( shik 本人倒是沒打 )

他可是打過 DEFCON 決賽的強者啊...

看得出來台大派這隊出來擺明就是要拿第一了... ಠ_ಠ

也因此這次比賽設定的目標就是交大第一,台大的話能打贏幾個就打贏幾個囉 ╮(╯▽╰)╭

 

==================================================

 

練習賽

 

比賽前一天開放 2 小時的練習賽進行比賽環境測試

題目也就三題

一題台大 CTF 的題目 Lottery ( 基礎BOF )

一題 python 腦殘題 minibomb2 ( 裡面就一行 cat flag 指令 = =)

一題交大 CTF 的題目 magic ( 同樣是BOF )

 

magic 那題因為之前的 exploit 還留者所以直接交給健賀自動化

patch 的話也很簡單,把 system("sh -i") 用 NOP 抹掉即可,鄭白一下子就 patch 完了

Lottery 的話因為之前玩台大的 CTF 的時候有寫過

所以也是很快就寫出了 exploit , 經測試沒問題後也是直接丟給健賀自動化

patch 的部份就使用了 hook 的技巧去 hook system()

只要發現參數裡面有 sh 就直接丟字串 "go fuck yourself" XD

後面更直接改成丟 dildo 給對手

嘲諷味十足啊 wwww(白目XD)

 

擷取

 

結果在三個 service 都有打出 exploit 的情況下

練習賽拿下了第一名 =w=

此外鄭白還在賽後發現比賽網頁中隊伍資料的 description 欄位有個 XSS 的漏洞 XD

不過這次就沒有再亂搞了,乖乖回報給學長們之後就修掉了 ( 其實也只是不讓我們修改 description 這樣 =w= )

 

upload_2015-01-18_at_4.42.24_pm  

 

陳菊那張是 gif 還會動喔XDDD

 

當然練習賽的重點還是在熟悉比賽環境跟測試工具

比較有問題的是因為是第一次上 patch

所以在上的時候很卡

不知道該怎麼做才最有效率

只能先將 patch 完的 binary先丟到 dropbox

然後再從 gamebox 裡面用 wget 把檔案載下來

之後手動改權限跟檔名

這個情形直到 CTCTF 正式賽打完都沒有解決掉

沒效率又得擔心上 patch 的時候會 service check failed

之後才想到這部分應該要寫 script 去做才會比較有效率 (寫個 scp 或是 sftp 之類的 script )

 

另外就是練習賽的時候 service check 只 check minibomb2 那題

其他2題都沒有 check 到, 導致我們不知道上的 wrapper 有沒有問題

也間接導致了正式賽的出包...

 

======================================

 

正式賽(Day1)

 

比賽 9:00 開始,8:00就可以開始設定環境

宗育和健賀都把 lab 的主機搬下來開啟雙螢幕模式

我則是用 324 的電腦遠端回 lab 電腦, 外加一台筆電開啟另類的雙螢幕模式=w=

鄭白和鼎文也是桌電+筆電的組合

大家都準備好要開始廝殺一翻了XD

 

一開始放了2個 service 出來

AllOfDefalut ( web ) 和 starbound ( binary )

拿到 binary 健賀就先開始分析

我則是先幫 starbound 上 wrapper

在上的時候健賀就先看到了一個 format string 的漏洞

不管三七二十一先 patch 再說

利用之前練習過的 constructor function + dynamic patch

成功將 format string 的漏洞 patch 掉

於是連同修改完的 wrapper 一起丟到 gamebox 上面

 

然後就是惡夢的開始......

 

上完 wrapper 之後 starbound 馬上就跟著 service check failed

於是開始分析問題在哪,之後發現資料夾的權限有設錯,導致在 log 連線記錄時會發生問題

但是改完之後還是 fail

接著拿掉了 wrapper 裡面的一些功能,還是一堆問題

連主辦方的學長們都來關心我們到底發生了什麼事...

跟我們說我們的 service check 到一定的程度就會發生 timeout

( 一旁觀戰的博班學長表示: X ! 在搞什麼啊 ! 快修好啊 !! (╯°д°)╯ )

隨著比賽時間一分一秒得過去

starbound 卻還是呈現 down 的狀態

分數狂噴到一個崩潰的境界

名次一度還掉到那些沒來打的隊伍分數都比我們高的冏境orz

結果搞了好久才發現原來是 socket 版本的 wrapper 寫爛了...

改成 pipe 版本就沒問題了...

 

這裡犯了幾個經驗上的錯誤:

1. wrapper 沒做好完整的壓力測試

2. 比賽剛開始時上完 wrapper 發現 service check failed,一定要馬上把 wrapper 撤下來

除了避免被持續扣分外,另外就是因為比賽才剛開始的關係,所以 exploit 不會那麼快出來,可以大膽的使用原始的 service

 

因為這樣至少被扣了6,7百分, 實在很嘔

搞完 starbound 的問題後也將近中午了

吃完中餐後繼續奮鬥

此時 NPC 看到各隊的 starbound 似乎都沒有進展的樣子

竟然好心的 pwn 了各隊( = 放出了 exploit ) wwww

也因為 wrapper 有做 log 的關係,我們可以立即分析 NPC 的連線記錄

發現似乎是透過某種手段,將加密過後的 flag leak 了出來

研究之後發現是將明文的 flag 做 decrypt ( decrypt 也是一種 encrypt ) 之後 leak 出來

於是健賀便開始研究如何 replay (如何將解密過的 flag 加密回去)

我則開始研究如何 patch

 

想法其實很單純

只要讓攻擊者不知道我們的 decrypt function 長什麼樣子就好了

原本的 binary 裡面有 decryption 和 encryption 這兩個 function

直接把裡面的加解密方式改成只有我們自己知道即可

例如 return 值是 x+95,把它改成 x+64 就好了

 

patch 完丟上去後沒什麼問題

此時健賀也成功將 exploit 寫出來了

將攻擊自動化後開始大規模的 pwn

並且在各隊的 gamebox 上塞後門

此時發現我們是第一個將 exploit 寫出來的隊伍

因此除了引起一陣騷動之外,分數也呈現直線的增長!

名次也從原本的後半段大躍進至第四名!

雖然之後也有組別將 exploit 寫出來並開始攻擊

但是我們的 patch 並沒有被攻破

也因此到第一天比賽結束為止,我們的 starbound 都沒有再掉分過!

 

比賽結束前又放出了一題 binary 的 service -- casio

宗育看到他沒開 DEP 馬上回報給我們

於是我用 execstack -c 的方式將 DEP 打開 

結果 patch 完之後馬上 service check failed = =

看來很多時候都要先搞清楚程式的行為之後再上 patch

否則亂上的結果就是 service check failed......

 

第一天比賽結束後整個人呈現腦弱狀態( 被 wrapper 耗盡腦細胞... )

吃完飯小睡一下之後就開始離線分析 casio 

看起來是個類似計算機的程式

輸入一個運算式後程式會產生 machine code,並做一大堆的運算之後吐出 base64 encode 字串

之後再用程式的其他功能將 base64 encode 字串餵進去

程式就會執行 machine code 將運算結果吐出來 ( 這也是為什麼程式沒開 DEP 的原因 )

與隊友討論之後,健賀負責寫 exploit

我則負責寫 wrapper 來擋 malicious 的 input

wrapper 收到 input 之後會丟到一個 function 裡面做檢查

如果是正常運算式就餵給真正的 service ,否則就餵一個一定會吐錯誤訊息的 input,外加吐一根 dildo 給攻擊者(啊斯~)

 

web 的部份因為都在忙自己的事的關係,因此很多情況都不清楚

不過大致上的流程都是  先被 pwn --> 分析exploit --> 上 patch --> replay 攻擊   這樣

效果還不錯 XD

此外兩位負責 web 的隊員在晚上也是忙著分析封包 + 看有沒有後門

辛苦他們了

 

=============================================

 

正式賽(Day2)

 

第二天也是跟昨天一樣

比賽開始時就先上 patch 過後的 binary + wrapper

情形也跟昨天一樣

馬上就 service check failed = =

不過因為我們一開始就打出了 casio 的 exploit 的關係

因此名次上升到了第三名

且漸漸得拉開了與第四名之間的差距

因此 service down 的影響跟第一天比起來沒那麼嚴重

 

starbound 的部份因為第二天的 service check 有升級的關係

所以第一天的 patch ( 改掉加解密 function ) 會失效

因此先 roll back 成前一個版本

之後這部份就交給健賀 patch 了 ( 此時攻擊方面呈現穩定拿分的局面所以不太需要去care )

 

casio 的部份則是 wrapper 在換行的部分沒有處理好

導致會將正常 input 誤判成 malicious 的 input

進而將 dildo 回給了 service check = =

改完之後 casio 便回復正常.....了幾個回合 =w=

此外又發現其中一隊把我們的 casio pwn 掉了

查看 log 之後,決定使用過濾字串的方式將一些特定字元濾掉

成功暫時止血

 

平安無事的過了幾個回合之後

我們的三個 service 突然在同一回合全部 down 了下來

當下整個傻眼

立馬查看 log 分析 input

casio 的話發現原來 input 允許有註解的出現 (ex. 1+1 /*dwefdhwe*/ )

且沒有注意到單一換行的問題

全部處理完後成功救活, 且直到比賽結束時都沒有再 down 過

 

starbound 的部份則是一直到比賽快結束時才找到出問題的 input

只是那個時候因為名次大致底定,且大家都沒力氣了

所以就放著讓它死到最後了XD

AllOfDefault ( web題 ) 則不清楚是什麼原因

總之最後也救活了

 

中午吃完飯後回來發現 casio 被某隊裝後門了@@!

方法是被拿到 shell 之後先是在某個資料夾下載了 backdoor 的 script ( 定期送 flag )

之後再利用 crontab 定期下載 script 並執行

 

因此最後的三小時基本上都在跟宗育砍後門

( 懶得再找 exploit 跟洞在哪了,很大的原因是因為分數跟前後差太大所以不太想管了XD )

宗育還發現到 backdoor 的 script 裡面有 ip 和 port

因此叫我直接送 dildo 給他們XDD

好吧,既然你們想拿我們的 flag,就送給你們一根大大的 dildo 吧XDD

於是寫個 python script 每 5 秒送一次 dildo 給他們...

 

10934579_10206015863662564_177277375_n  

 

靠夭結果真的送到啦啦啦啦啦啦啦XDDDDDDDDDDD

( 要看高清版 dildo 圖請看 這裡 )

 

說真的送到的感覺真的超爽的啦XDDDD

而整場比賽也就在這些飛來飛去的 dildo(s) 中畫下了句點(殺小)

 

===========================================

 

檢討

 

老實說要檢討的地方有很多

包括 wrapper 應該要先作壓力測試,才不會在比賽中出包

( 賽後分析 socket 版本的 wrapper 會出問題主要是因為連線時出現 race condition 的關係 )

還有改完 wrapper 之後也要有針對該 service 的完整測資進行測試

才能夠保證不會有 service check failed 的發生

這次為了要處理 service check failed 的問題耗掉了大部分的時間

我們在這次比賽後半段因為攻擊手沒力的關係 ( 他半夜三點起來找洞 @@ )

導致後續分數增長緩慢 ( 沒有新的exploit , 很多回合只能靠後門拿分 ) , 一直無法超越第二名

要是 wrapper 的部份處理得當搞不好就有更多時間花在 exploit 上面,實在可惜

 

此外發生 service check failed 時

需要馬上判斷是否需要將 wrapper 撤下來

像是如果是比賽一開始的話就一定要馬上撤 ( 因為 exploit 不會這麼快就放出來 )

還有就是必須要立即分析 log ,找出可能的 service check input, 看看是哪裡出了問題

( log 真的很重要,雖然主辦方有提供 delay 3 回合的 pcap 檔供我們下載進行分析,但是本次比賽我們完全看自己的 log, pcap 反而沒人在看)

 

此外一旦發現 service 被 pwn 掉

也必須馬上找出原因,包括 log, 還有分析程式行為 + 研究如何 patch

( 而不是在那邊耍白痴送 dildo = = )

像這次比賽後半段我們的 casio 只被 2 隊 pwn 掉

而這 2 隊的 payload 都是那種超級長的 payload

所以其實可以考慮在 wrapper 裡面算 input 長度,超過一個定值就把連線切掉之類的

 

=======================================================

 

每一次的比賽都是一個寶貴的經驗

這次除了打得很過癮之外

最重要的就是獲取了相當多的經驗值

雖然遇到了許多問題

但是這也代表著下一次的比賽遇到這些問題時

我們就知道該如何處理,如何避免

 

最後感謝學長 ( 同時也是程式安全的授課老師們 ) 這一學期的教導,得到的收穫真的是非常多

也辛苦他們為我們準備了這麼高水準的比賽

也感謝強大的隊友們

無論是強大的攻擊手健賀 ( 用exploit + 塞 backdoor 真的是打爆了好多組XD )

管理機器的宗育 ( 最後三小時狂砍 backdoor 辛苦他了 )

還有鄭白和鼎文辛苦得罩了2天的 web

個人覺得拿到第三名算是 ok 了 ( 雖然賽前就知道最高應該只能拿第二名 = = )

有幸能夠參加到這場比賽實在是很開心

覺得 CTF 這東西真的是好好玩,夠刺激 XD

也希望之後能夠多多加油,多多參加 attack defense 的 CTF 囉 :)

arrow
arrow

    Tube 發表在 痞客邦 留言(0) 人氣()