DEFCON 23 CTF參賽記

8月4日

從北京出發,起飛前兩小時發現機票沒有買成功,立即買了一張,感謝諸位隊友。到達San Francisco後與昨日航班延遲一天的隊友會合,21:00多飛往Las Vegas。今年DEFCON會場從Rio遷到了Paris & Bally's。我們提前到達的在這裏訂了幾間房間。

場外選手所在的套房

8月5日

在LINQ吃了一頓Hash a Go Go,一頓管一天,吃完就難受了,疼了一天,這一天什麼都沒做就過去了……

Hash a Go Go

8月6日

準備了一天binary hardening。

8月7日

比賽分三天進行,前兩天從11:00到20:00,第三天從11:00到14:00。

10:00入場,CTF比賽和其他一些活動共用一個分會場,找到會場就花了不少工夫。參賽隊伍的桌上有LED燈,每輪開始會閃爍一下,似乎還能表示攻擊和被打,具體規則不明。大屏幕可視化各戰隊攻擊情況。

可視化攻防狀態的屏幕

比賽爲攻防形式(attack and defense),每5分鐘爲一輪,每輪主辦方更新各個服務的flag文件,分析題目程序、挖掘漏洞、編寫exploit攻破其他隊伍的服務,獲取權限訪問flag以得分。主辦方有service level agreement,會檢測各服務的可用性,如果判斷爲down也會扣分。具體分數計算規則不明。

10:40左右通網,我們可以訪問gamebox了,ctf@10.5.8.4,~/README提供了一些說明。開賽前必須修改初始密碼後,否則會扣分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- Important IP addresses
10.3.1.7 scorebot
10.5.8.6 capture
#### team vulnerable boxes
10.5.1.4 team1 ppp
10.5.2.4 team2 bushwhackers
10.5.3.4 team3 samurai
10.5.4.4 team4 hitcon
10.5.5.4 team5 defkor
10.5.6.4 team6 team9447
10.5.7.4 team7 gallopsled
10.5.8.4 team8 bluelotus
10.5.9.4 team9 spamandhex
10.5.10.4 team10 corndump
10.5.11.4 team11 0ops
10.5.12.4 team12 0daysober
10.5.13.4 team13 dragonsector
10.5.14.4 team14 shellphish
10.5.15.4 team15 lcbc

隊伍編號是根據決賽晉級順序得到的。

前兩年的決賽平臺都是armv7,大家都覺得今年仍是ARM的可能性很大,結果是個x86-64的機器,CPU是AMD Opteron(tm) Processor 6128 HE,Ubuntu 14.04,uname信息是Linux version 3.16.7-ckt13 (root@lxc1)。可能所有隊伍共享一個機器,用lxc隔離,每支隊伍分到20GB磁盤空間。

11:00比賽開始,每5分鐘爲一輪,每輪主辦方會更新各個服務的flag文件,分析題目程序、挖掘漏洞、編寫exploit攻破其他隊伍的服務,獲取權限訪問flag以得分。主辦方有service level agreement,會檢測各服務的可用性,如果判斷爲down也會扣分。具體分數計算規則不明。

首先開放的服務是rxc,程序在/home/rxc/rxc,所有者是ctf;flag文件在/home/flags/rxc,rxc用戶可以讀取。我們用Dropbox把文件分享給場外套房選手。

10.5.8.6開放了sftp服務提供PCAPNG格式的流量文件,數據包文件會延遲一段時間提供。今年流量文件被處理過了,所有IP都被改成了1.1.1.1,無法判斷連接發起的來源。這可能有幾方面原因,如更好地隱藏service level agreement檢查流量、讓選手難以根據連接發起源做檢查。

服務都是使用標準輸入輸出進行交互的,使用xinetd監聽端口,xinetd運行服務時會把權限drop至服務名對應的用戶比如rxc,配置文件/etc/xinetd.d/rxc如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
service bluelotus-service
{
disable = no
type = UNLISTED
socket_type = stream
protocol = tcp
user = rxc
group = rxc
wait = no
server = /home/rxc/rxc
port = 799
per_source = 2
log_on_failure = HOST
banner_fail = /etc/DoS-msg
nice = 10
killafter = 25
seccomp_whitelist = 0 1 2 3 5 9 10 11 12 13 14 16 21 23 35 56 59 97 158 202 218 231 273
}

後兩個選項是主辦方修改的xinetd特有的,其中killaftersetitimer設置了連接的超時時間,殺死卡死的進程。比如去年決賽的eliza用qemu-i386-aslr執行,CPU佔用很大,經常有長時間不退出的連接,造成DoS攻擊。seccomp_whitelist結合NO_NEW_PRIVSSECCOMP_MODE_FILTER等,設置了進程及子進程允許使用的系統調用。

主辦方在gamebox安全上花了很大工夫,做的防護還有:

  • /home/ctf的權限會被定期改成0700,大概是怕選手不慎把重要資料泄漏出去。
  • /proc/net/tcp等無法讀取,netstatss等工具無法看到TCP連接。
  • 進程自身的/proc/self/{personality,stack,syscall}無法讀取。
  • 無法讀取相同用戶其他進程的/proc/$pid/{auxv,environ,maps,mountstats}等。

近15:00主辦方宣佈DEFKOR獲得rxc的first blood,DEFKOR against PPP。實際發生的first blood應該還在這之前,開始吊打全場,比分逐步拉開。其他隊伍分數相差不大,Shellphish、0daysober不久即相繼防禦成功,分數比餘下隊伍稍高些。

16:00多發現了新題ombdsu,在另外一個gamebox 10.5.8.2上,似乎是MIPS Creator Ci20,CPU是Ingenic JZRISC V4.15 FPU V0.0。

發現新題hearye.zip,ARM64的,做題得一次性分。我們沒有在意,回去後才做,第二天準備提交時發現主辦方關閉了題目,第一天做出來的才有分。

第一天流量混淆已經非常嚴重了。

HITCON似乎重放rxc成功,名次逐步上升。

19:00改了改之前ISC'14時的監控,寫了一個積分榜。 自製積分榜

第一天結束時DEFKOR領先第二名7334分。 第一天結束時積分榜

晚上回去換了一種思路寫binary hardening工具,稍晚研究MIPS的方案,希望第二天能用上。我们写出了rxc的exploit,ombdsu也有replay和exploit。

8月8日

可能大學都覺得現場嘈雜不適於解體,都不願意來現場。10:00多來到現場,仍舊是先搭建環境。

10:40+允許訪問外網,可以連接兩個gamebox了,看到i386的新題hackermud,這是一個MUD遊戲的客戶端,程序啓動時會連接主辦方控制的10.5.17.4的5050/tcp。10.5.17.4:5050只允許gamebox連接,因此要讓場外選手連接的話,得用SSH port forwarding等方式以gamebox爲跳板連接。今天https://10.3.1.7/scoreboard不再顯示積分,只能看到排名。

HITCON開賽即發動第一波攻擊取得tachikoma first blood。

tachikoma似乎被主辦方更新了,因此沒有立即換上我們的patch。換了多個修補版本,改緩衝區大小,關閉NX等,但服務持續down,不知道主辦方怎麼檢查的。折騰了好久,13:20服務狀態終於up了,再改了一會兒終於不丟flag了。

12:31給rxc換上patch似乎不再掉分。

近15:00主辦方宣佈有新題。發現說明文件~/readme-rpi,是Raspberry Pi 2上的ARM Windows 10。參賽選手無法直接管理題目所在的平臺10.5.8.3,只能通過主辦方提供的簡易FTP更新程序,以及通過PowerShell編寫的、8989/tcp上的管理服務停止、啓動服務。

16:00多放出mipsel新題irkd。以/home/irkd/irkd -i 10.5.17.4 -p 666 -n /home/flags/irk_nick的方式執行,需要連接服務端10.5.17.4,是個類似IRC的服務。

19:00多有隊員失誤踢掉電源線,服務器關機,幾乎所有攻擊都無法打出,圖爲這段持續20分鐘的艱難時刻:

第二天結束時名次依次爲:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DEFKOR
0daysober
Plaid Parliament of Pwning
HITCON
Dragon Sector
blue-lotus
0ops
Samurai
Shellphish
LC↯BC
!SpamAndHex
9447
Gallopsled
Bushwhackers
CORNDUMP

8月9日

爲了懸念,今天不再顯示排名。每輪時間從300秒縮短到150秒,今天三小時大概有72輪。

開場就看到DEFKOR的badlogger first blood。

badlogger的PowerShell管理界面更新了,可以一次性kill所有進程。我們上傳了修補後的badlogger,但寫好的exploit打不了。之後一直在修改badlogger的exploit,比賽快結束時才弄好,提交了十幾個flag。

比賽前幾分鐘LED狂閃,循環播放The Final Countdown,震耳欲聾,14:00比賽結束。隊員們這幾天睡眠缺乏,大多去睡覺了。

閉幕式

16:00閉幕式。

閉幕式

DEFCON一共有8個urban gaming,Capture the Flag是壓軸項目。第一名是韓國DEFKOR,成員大多來自首爾大學,似乎都是Best of the Best項目的成員,這是一個培養網絡安全人才的計劃。第二名是兩屆DEFCON CTF決賽冠軍PPP (Plaid Parliament of Pwning)。第三名是0daysober,歐洲多國聯隊,成員主要來自瑞士法語地區和法國。

結束後送出了一些吉祥物……但鎮宅之寶我們隊員都沒拿到……

準備

參加完ISC'15 Student Cluster Competition回來已經被剝奪學校寢室居住資格了,這段故事也許之後應該再寫篇文章記錄。飄零,搬到了一個賽前備戰的地方,做了一些東西:

系統管理腳本

下載流量文件自動切分、殺死後門進程等。今年主辦方在封殺後門,營造一個純粹的逆向、漏洞利用的比賽環境上作出的努力不可謂不大。殺死後門我着實思考了很多,不過在這次比賽上都沒用上。

系統管理腳本

左上讀取積分,右上下載流量,左下更新badlogger,右下用coproc實現semaphore,並行化PCAP/PCAPNG的預處理供索引工具使用。

GitHub項目:https://github.com/MaskRay/DEFCONCTFFinalsGameboxAdmin

搜索flag

在流量文件中找到flag定位攻擊流量是流量分析的關鍵。以往使用wireshark的display filter搜索flag,性能很差。因此我寫了一個多串匹配工具搜索flag,定位後解析PCAP/PCAPNG,按frame拆分後把偏移量轉換成frame.number==1337式樣的filter,方便深入檢查。多串匹配採用Multi Backward DAWG Matching算法,網上沒有找到字串長短不一時的構造算法,自己揣摩並實現了一個。大意是取最短的模式串爲窗口大小,初始時窗口左端與文本對齊,檢查所有與窗口右端對齊的模式串能否匹配文本。若找不到則對於所有模式串的所有前綴,找到其中最長的落在窗口右端的前綴,滑動窗口使之與該前綴對齊。

該算法需要實現多串suffix automaton/suffix oracle。General Suffix Automaton Construction Algorithm and Space Bounds提到了一種多串構建方法,但只對suffix-unique的字串集有效。研究後發現常規的單串構造算法稍加修改即可用於多串。

PCAP搜索引擎

流量分析時經幢需要搜索字串。Wireshark display filter中的contains很慢,因此打算自行實現。全文搜索有inverted index和stringology算法兩套思路,調研後決定使用stringology流派的FM index。FM-index以Burrows-Wheeler Transform爲核心,集成了Wavelet Matrix、succinct bit sequence等,趁着這次要寫全文搜索引擎的機會實現了各種succinct data structure:RRR、Elias-Fano encoding、Wavelet Matrix等。

fqj1994編寫了預處理PCAP/PCAPNG,以stream爲單元重組PCAP;我在對預處理後的文件建立索引FM-index;pandada8用riot.js寫了前端。

計分方式和成績

關於我們的名次。可能得再過一陣子才能知曉。如果現在要做個預測的話,我覺得第6、7名是我們較爲可能的名次。

最終名次是第5名,參見http://blog.legitbs.net/2015/08/2015-def-con-ctf-final-scores.html

15支隊伍和主辦方Legitimate Business Syndicate的虛擬隊伍參與計分。x86-64和mipsel兩個gamebox上最終開放的服務計有6個:rxc,irkd,tachikoma,ombdsu,hackermud,badlogger。每支隊伍的每個服務初始被分配1337个flag。每一輪若service level agreement不通過則丟失14個flag,平均分配給其餘14支參賽隊伍;若token被其他隊伍提交,則丟失14個flag,平均分給攻擊者,餘數給legitbs,legitbs趲到的flag會參與以後的分配。不清楚SLA不通過且被攻擊會如何計分。最終得分是所有服務flag數和+4011。

ARM64題hearye.zip即爲livectf_quals,只有第一天解出的隊伍才有分,前三名分別得到600、300、200個flag,其他得到100個。第二天被允許參加livectf_finals的隊伍中第一個解出的PPP得到1000個flag。這些flag參與到計分,一個即爲一分。

我希望flag數用浮點數表示。

Team Score rxc irkd tachikoma ombdsu hackermud badlogger livectf_quals livectf_finals
legitbs 41524 2 0 0 1 0 0 18455 19055
defkor 23949 6746 1359 2624 3731 1368 3510 600 0
ppp 19896 3488 1179 3859 2528 1368 2263 200 1000
0daysober 17943 2095 1284 1605 6216 1338 1294 100 0
hitcon 13560 2304 1329 3871 3 1338 604 100 0
blue-lotus 12442 876 1299 1465 2078 1323 1390 0 0
0ops 11306 2170 1389 1103 1 1383 1249 0 0
dragonsector 11288 2190 1389 1220 461 1323 694 0 0
samurai 10742 0 1254 1129 802 1278 2168 100 0
shellphish 10591 128 1419 379 2057 1338 1159 100 0
lcbc 9941 0 1359 1600 39 1353 1279 300 0
spamandhex 9461 0 1344 286 1578 1368 874 0 0
team-9447 8410 55 1404 387 1 1383 1069 100 0
gallopsled 8608 0 1359 527 559 1353 799 0 0
corndump 7508 1 1299 0 0 1338 859 0 0
bushwhackers 7447 0 1389 0 0 1203 844 0 0

評論和爆料

今年不限制決賽參賽人數,得以成行。每年都希望多做一些,今年又朝這個目標多努力了一些。遺憾:儘管參加了三年DEFCON,但一直都沒機會參加Capture the Flag以外的其他活動。

今年DEFCON CTF決賽的特點是可執行文件變得很大,梳理脈絡變得尤爲困難(這點向PPP討教過,他們也這麼認爲),我們可以從中看到題目向實際應用靠攏的趨勢。

三年參賽,我們也是一支經驗較充足的隊伍了,但也能看到名次進一步提升的天花板。對於很多成員不是安全專業從業者的我們來說,取得這個名次已屬不易,算是發揮出了正常水平,在協作和準備上做出的準備也看到了成果。CTF競賽和安全有很大關聯,但水平到一定程度後還需要大量訓練才能繼續提高。對於大多數人而言,把精力投資在這方面價值遠不如花在其他領域大。賽棍也許是存在的,但和算法競賽相比仍差得很多。

提升競爭力的核心是逆向工程和漏洞利用能力。這方面我們與頂級強隊仍有巨大差距,在其他方面如流量分析還有一定增長空間。Day 1四個小時後DEFKOR rxc first blood吊打全場,各隊分數都差不多,隨後HITCON成功重放,升到第二。善於防禦的Shellphish很快修補服務。即使如此,各隊分數差不了太多,攻擊速度至關重要。小道消息:Day 1 geohot沒來助力PPP,但晚上就到了,莫非是第一天狀態太差就立馬趕來救援?geohot震驚自己一晚上才解出來的題竟然被那個韓國人(lokihardt)用4个小时做出來了……最後PPP應該解出了所有的題目。但是主辦方沒通知irkd服務從監聽0.0.0.0改爲監聽127.0.0.1,讓ricky以爲此題一直在維護狀態而少拿了好多分。頒獎時韓國領隊(?)說lokihardt "solved all the challenges"。關於我們,引用一句話:以其努力程度之低,還不到拼天賦的程度。