DEFCON 25 CTF參賽記

很榮幸今年成爲Tea Deliverers一員參加DEFCON 25 CTF,照例每年寫遊記。因爲錯綜複雜的原因,kelwin聯合blue-lotus、Nu1L、110066以及長亭科技一些實習生組成Tea Deliverers,在Plaid CTF 2017中晉級DEFCON 25 CTF Finals。

我大概兩週前開始學習radare2,在缺乏實踐的情況下發點微小的pull requests,很遺憾確實如所想的那樣,沒有在比賽中用上。正如slipper後來所說,這些人(crowell,XVilka,me(?))都喜歡折騰些奇怪的東西(radare2),然而他們的隊友都不理睬他們的玩具……

DEF CON CTF PPP
RuCTFE Eat Sleep Pwn Repeat
HITCON CTF Cykorkinesis
33C3 CTF pasten
Boston Key Party HITCON
UCSB iCTF Bushwhackers
PlaidCTF Tea Deliverers
DEF CON CTF Qualifiers Shellphish
DEF CON CTF Qualifiers A0E
DEF CON CTF Qualifiers hacking4danbi
DEF CON CTF Qualifiers !SpamAndHex
DEF CON CTF Qualifiers RRR
DEF CON CTF Qualifiers Team Rocket ☠︎
DEF CON CTF Qualifiers Lab RATs
DEF CON CTF Qualifiers koreanbadass

另一支大陸戰隊A*0*E是上海交通大學0ops、騰訊eee、浙江大學AAA、復旦******四支隊伍組成的聯隊,30多人,由騰訊贊助。

7月25日

libmaru做網管和系統配置。我在他的VPS上裝了一個gogs用於比賽時協作開發,晚上寫了一個把PCAPNG按服務端口號拆分的工具。

7月26日

我打車到San Francisco International Airport,14:00多到達Las Vegas,帶了兩個kelwin前幾天在Amazon買的交換機給他們。kelwin、slipper、marche147 24日抵達,參加Black Hat USA 2017。slipper不願意參賽,滯留幾天觀戰。其他隊友們昨日從北京出發,已提前兩個小時抵達Flamingo Las Vegas Hotel,共11名隊員來現場。libmaru似乎越來越喜歡做網管,這次用上了systemd-networkd。我們的服務器是一個Intel NUC7i3BNK,16GB內存,100GB硬盤。

晚上百度安全宴請來Las Vegas參加Black Hat USA、DEFCON等的中國信息安全人員,我见到了少量熟面孔。回酒店时,我當了回Computer Deliverer,kelwin讓我給Riatre遞電腦,Pwn2Own 2017長亭科技的獎品,回來後整理比賽會用到的一些工具。

在長亭科技遠程參與的gyc990326之前寫了RISC-V到ARM的彙編轉譯工具,提交到我們的git repo。

7月27日

9:00主辦方Legitimate Business Syndicate發佈https://blog.legitbs.net/2017/07/the-clemency-architecture.html,公佈了比賽會用到的自定義架構cLEMENCy,提供了手冊(指令集說明、內存映射、中斷等)、去年闭幕式时有消息会用custom hardware, custom architecture, custom operating system,OS和硬件跳票了,不過自定義架構還在。這是個9-bit byte,27-bit register width,middle-endian的奇異架構。

cLEMENCy is the LEgitbs Middle ENdian Computer architecture developed by Lightning for DEF CON CTF.

Each byte is 9 bits of data, bit 0 is the left most significant bit. Middle-Endian data stores bits 9 to 17, followed by bits 0 to 8, then bits 18 to 27 in memory when handling three bytes. Two bytes of data will have bits 9-17 then bits 0 to 8 written to memory.

Register XXYYZZ → Memory YYXXZZ

Register XXYY → Memory YYXX

內存中存儲的常用單位爲3字節27-bit,以middle-endian形式存儲的整數。而從內存中指令解碼也要經過middle-endian處理。長爲2~4字節的指令需要交換前兩字節;6字節指令需要分成兩個三字節組,交換兩次。

[0000000,4000000) Main Program Memory
[4000000,400001e) Clock IO
[4010000,4011000) Flag IO
[5000000,5002000) Data Received
[5002000,5002003) Data Received Size
[5010000,5012000) Data Sent
[5012000,5012003) Data Sent Size
[5100000,5104000) NFO file
[6000000,6800000) Shared Memory
[6800000,7000000) NVRAM Memory
[7ffff00,7ffff1c) Interrupt Pointers
[7ffff80,8000000) Processor Identification and Features

NFO file是手冊沒有提到的section,塞了很多ROP gadget。遺憾的是比賽時我們沒有發現。

與之一起發佈的還有clemency-emu,一個帶調試功能的cLEMENCy架構模擬器,运行在x86-64上。可執行文件稱爲firmware,由模擬器解釋執行。

衆人從Flamingo搬到Caesars Palace。explorer、gyc990326、hankein95、spine在長亭科技遠程參與。我們決定用IDAPython寫processor和loader插件,實現cLEMENCy架構firmware的加載、反彙編、交叉引用、函數分析。gyc990326之前一個月用RISC-V練手,寫了很多IDA plugin代碼,熬夜把之前寫的東西改寫成cLEMENCy的IDA loader和processor。他用了bitstringpydevd等庫,我把bitstring去掉了。libmaru一年半前寫過一些IDA plugin,在現場的其他人都不熟悉。在長亭科技遠程協作的hankein95等整理了cLEMENCy一百多條指令的編碼表。

14:00 kelwin去領DEFCON badge。每支隊伍得到8塊badge,即只有8人能去現場,想要同時去更多人就得買badge。儘管今年現場嘈雜情況比往年有所改善,大家還是更喜歡待在酒店幹活。

eadom改寫pwntools,把pwntools.pwnlib.tubes.sock裏的recv,send改寫成9-bit讀寫。BrieflyX在研發ROP gadget工具,實現了一些基礎I/O函數。 晚上cxm搜索hello.bin裏的字串,發現這個firmware靜態鏈接了neatlibc。wxy191和marche147在逆向clemency-emu,研究函數簽名。Atum提出可以使用rizzo製作簽名,第二天大家做好。libmaru、Riatre等把IDA loader/processor改好。賽後和HITCON交流,他們是自行寫插件製作簽名的,開發能力超強。

下午大家都陸續註冊了git repo帳號。

我跑去101 Track 2,radare2開發者Maijin給我展示了radare2的一些用法。radare2用於cLEMENCy的難點是9-bit需要pad 16-bit才能讓IDA、radare2等工具用。radare2 disassembly是基於字節的,虛擬地址和文件偏移增長速度是一致的,難以實現。而IDA Pro虛擬地址增長速度可以和文件偏移不同,因此我們把9-bit pad成16-bit後可以正常顯示,但指令讀取、字符串顯示等地方還有許多需要處理的。

21:00多我開始根據指令編碼表寫彙編器。

7月28日Day 1

2:30我的assembler已經基本能用了。gyc990326的IDA processor樣板代碼很多,容易滋生bug,Riatre在重構,到4:00多已經修復了大量bug。之前的processor是大量elif串起來判斷是否是各條指令的,性能很低。Riatre把指令按長度分類後再用dict查詢,性能提升了很多。

10:00比賽開始。主辦方使用類似去年的網頁界面,可以查看積分榜、下載其他隊伍的firmware、上傳firmware。賽制仍是零和遊戲,15支隊伍初始13370分。顯示服務是否通過主辦方的poller(服務可用性檢測),但不再顯示服務被攻擊的標誌。每5分鐘一輪。爲了擴大first blood的優勢,PCAPNG延後30分鐘才能通過sftp下載。

第一個題目是rubix,一個變體的魔方遊戲,輸入54字節,把魔方還原後即把輸入的54字節作爲shellcode執行。wxy191發現不是標準魔方,u後接u'不會還原。marche147發現以輸入的前3字節作爲種子生成30個隨機數爲魔方旋轉操作。11:55 HITCON first blood。

我給PCAP search加上9-bit搜索支持,不過之後也沒有人用。

出現新題quarter,是個後綴表達式計算器。13:25 HITCON再次first blood。

14:00多A*0*E的人發送惡意流量,利用騰訊挖掘的Wireshark的Multicast Source Discovery Protocol dissector漏洞,讓選手們的Wireshark無法打開PCAPNG。我放棄使用tshark,根據IP/port/TCP sequence寫了粗糙的TCP流拆分工具應對。 15:00多出現新題internet3,是個類似PPPoE的網絡協議題,使用upwards-growing stack。marche147在做。 BrieflyX一直在寫rubix的shellcode,先寫了一個調用firmware裏原有指令的ROP的,後來又轉成純shellcode的。 一直到15:00多才吃到午飯,嗚嗚。 16:00 Riatre給IDA processor加了函數識別。 eadom在弄rubix的重放。 18:10 HITCON internet3 first blood。 19:00 Riatre給IDA processor加了trace_sp支持。gyc990326加了多行字符串顯示。晚上kelwin在寫fuzzing工具,後來說沒什麼用。

7月29日Day 2

我給IDA processor加了adi/sbitrace_sp,之後加了load/store指令。 1:00多gyc990326的cLEMENCy到ARM的彙編轉譯工具做完預覽版,但有一處segment permission的地方沒有改,需要做一番修改才能用。還有不少bug,用於看程序結構還是不錯的,但運算部分都不能信任。

10:00開賽,出現新題babysfirst,是一個模仿PHP的題。

11:00 marche147提出把PCAPNG弄出類似hexdump那樣的9-bit dump會方便分析流量。我把這個功能整合到重組流量的工具中。

大約12:30出現新題half,也是後綴表達式計算。Riatre說這很有趣,quarter在比賽進行到1/4時發佈,half則是比賽進行到1/2時。kelwin寫出了exploit。

很多隊伍在用PPP的patch。我們知道PPP的patch有後門,chao和Atum一直在逆向他們的RSA後門。

大約14:20出現新題legitbbs,是一個字符串處理題目,會在flag page裏搜索字串。cxm在做。

libmaru發現主辦方Day 2修改積分榜代碼出現漏洞,可以按照firmware序列號下載到未公佈的題目。slipper雖然宣稱不參賽,但覺得-1 day比較有趣還是做了babyecho,用%+n解出。

slipper說爲什麼不願意參賽,覺得做別人做過的題沒意思,要玩0day。

我們的NUC磁盤100GB,我根據TCP流生成的文件是存儲在磁盤上的,不得不定期刪除一些舊流量生成的文件。

16:25 PPP legitbbs first blood。

大約17:15出現新題picturemgr。它有agency和image兩個單鏈表,可以執行添加刪除列出等操作。

大約19:35出現新題trackerd,有120KiB,五六十個命令,逆向很麻煩。賽後Shellphish的王若愚說他們發現10+洞,他修補了7個。

PASTEN picturemgr first blood。

晚上kelwin又弄出half三個exploit。

7月30日Day 3

我寫了能比較精確判斷flag被讀的工具,篩選出攻擊流量。

10:00開賽。PPP trackerd first blood。出現新題babyecho,是一個輸入一個字符串,執行printf的簡單題。neatlibc不帶%n,主辦方添加了這個格式化字符串功能,題目中對此進行了判斷。kelwin等待宣佈新題後約1分鐘根據slipper的exploit實現first blood。主辦方過來說“It's good”,因爲機會對所有隊伍都是公平的。HITCON確認他們也提前获得了题目,從PPP的表現來看他們也獲得了。之後其他隊伍修補時,有的把這個功能去掉,有的把n換成s等。

libmaru指出主办方提供的sftp可以实施directory traversal attack,有几个掛載tmpfs的目錄可写,但没有任何有价值的可读文件。

14:00比賽結束,在套房的人(包括我)吃完飯,折騰到14:40到比賽現場,和A*0*E、HITCON、Shellphish等交流。Shellphish的crowell是個radare2 contributor,給了我Boston Key Party CTF的貼紙……但我好想要radare2的啊。

17:00 DEFCON閉幕式,有一段Pac-Man視頻,工作人員展示,各個比賽的頒獎。最後是最受矚目的Capture the Flag項目的頒獎,A*0*E第三名,HITCON第二名,PPP第一名(五年四冠,主辦方都覺得說煩了)。Legitimate Business Syndicate從2013年起擔任DEFCON CTF主辦方,到今年已連續當了五年。今年是他們的謝幕演出,爲此特意搞了大新聞,弄出了cLEMENCy,讓大家的準備都派不上用場。這也像是他們一貫的作風,當大家都用x86時,2013年gamebox使用ARM環境。當時,沒有decompiler也不懂ARM彙編、沒有ARM設備、不會配環境的我們手忙腳亂;2015年弄了ARM、MIPS、x86甚至還有Windows的大雜燴;2016年順應時勢用Cyber Grand Challenge賽制;2017年引入cLEMENCy。新的DEFCON CTF主辦方還在招標中,講道理PPP當主辦方是最合適的,但他們似乎不願意。

place team id score
1 PPP 1 33850
2 HITCON 5 30631
3 A0E 10 19730
4 DEFKOR 3 18474
5 Tea Deliverers 8 13941
6 pasten 4 11332
7 Shellphish 9 10452
8 Eat Sleep Pwn Repeat 2 9369
9 RRR 13 9088
10 Lab RATs 15 8564
11 hacking4danbi 11 8521
12 Team Rocket 14 8496
13 Bushwhackers 6 6894
14 koreanbadass 7 6766
15 !SpamAndHex 12 4405
n/a Legitimate Business Syndicate 16 37

主辦方說很高興看到大家在比賽中開發了這麼多工具,還特意提到了有隊伍甚至實現了cLEMENCy轉ARM彙編的工具(gyc990326的),很不容易。 Jeff Moss在最後提到要舉辦DEFCON北京分會,聯想到26日百度安全晚宴出現和總裁談笑風生的Dark Tangent……你們會看到DEFCON北京CTF嗎?(喵嗚嗚嗚,edge triggered簽證過期了回國麻煩……)

Orange Tsai: PPP won so many times. Give me a chance, plz :(

robbje: Just pretend order is given in middle endian

23:00多王若愚和slipper在北京9号面馆吃饭,kelwin和我下楼找他们。slipper談論爲什麼不願參賽,因爲覺得學不到新東西,覺得國內太看重比賽成績。kelwin说大家战意低迷,他觉得队伍里还有人想玩,所以今年才又组织了一场。今年大家狀態萎靡讓他覺得很失望,明年也許就不玩了。

7月31日

从Caesars Palace回到Flamingo Las Vegas。下午很多队友们去Las Vegas North Premium Outlets购物,marche147、wxy和我留在Flamingo。晚上kelwin、eadom、cxm、Atum和我去Wynn Las Vegas,吃完飯後,21:30看Le Rêve表演。23:00結束,打車回Flamingo Las Vegas。

8月1日

可憐的slipper睡了好幾天沙發。libmaru作息上來看似乎去了歐洲時區。衆人吃了一頓自助早午餐。

PPP開源了他們的工具https://github.com/pwning/defcon25-public,代碼很乾淨。可以看出他們賽前以RISC-V練手,各主力都參與了開發,diff RISC-V和cLEMENCy可以發現改動的代碼很少。C寫disassembler使得既能當IDA plugin用,又能standalone。assembler可以集成進IDA使用,nc、strings、xxd等工具也都很小但實用。我們的隊員都用着自己做的方的輪子,彆扭但卻用得不亦樂乎。我作爲一個工具提供者應該造更多輪子的,Riatre說應該賽前review gyc990326代碼。能反省的地方很多。A*0*E拿了季軍,老闆也覺得有很多值得總結反思的地方。

8月2日

9:00我出發去McCarran International Airport,坐飛機到San Francisco後回Redwood City。大部隊20:00到達機場,乘坐海南航空回北京。

感想

今年主辦方準備很充分,失誤很少。積分榜用遞增id作爲firmware鏈接是個安全隱患,應該使用hash或其他不易猜解的標識符。提供PCAPNG的sftp未使用ChrootDirectory,可以訪問上級目錄。

還有什麼能做的:fuzzing、無源碼給模擬器加功能、使用gdb經由模擬器調試firmware、反編譯器、IDA compiler/ABI/type system支持、radare2支持。

對於沒有decompiler的架構,IDA Pro、Binary Ninja、radare2等逆向框架的差距被縮小了,差別更多體現在哪一個更hackable。很可惜,熟練使用的IDA Pro的人比用其他工具的多多了。

  • 服務器100GB硬盤太緊,我不得不刪除大量PCAPNG及流量分析創建的文件。對於9-bit dump的文本文件,空間浪費嚴重。客戶端請求時即時生成比較費時,可以考慮壓縮,請求時動態生成,或設法利用nginx的gzip模塊。
  • 今年是五年來唯一一次每天結束後沒有聚在一起總結反思,討論戰術。
  • 分工不明確,沒有分享解題過程,浪費了稀缺的逆向人力。
  • 工具協作不佳。發生了若干起“不知道隊友做了xx”、“不知道隊友沒做xx”、“不知道隊友需要什麼”的事件,比賽中耽擱了很長時間。BrieflyX寫的shellcode手動用ml,mh拼湊一個27-bit立即數,而這個功能應該實現在assembler裏。
  • 思想境界上的差異。跟風重放攻擊可以進前一半,積極研發exploit才能更上一層樓。我們還在苦於如何修補服務,抄襲他人firmware,A*0*E等都在思考如何研製後門了。

PPP明洞、暗洞兼具,分工明確,研發力強,工具齊備,準備充分,求勝心切,輔以策略。差距巨大,心服口服。

Riatre出了道填空題,“五年比赛,三年第五。”(不是“五年高考,三年模擬。”)作爲經歷了每一場legitbs的DEFCON CTF的老人,很慚愧至今也寫不出exploit。

參考