很榮幸今年成爲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。他用了bitstring、pydevd等庫,我把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/sbi的trace_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。
參考
- Legitimate Business Syndicate的cLEMENCy工具鏈、模擬器、文檔:https://github.com/legitbs/cLEMENCy
- Legitimate Business Syndicate公佈的積分榜網站:https://github.com/legitbs/scorebot。很有誠意,保留了從2013年起的每個commit,而沒有squash成一兩個commit。值得注意的是除了Vito Genovese,還有HITCON peter50216 2015年的一個commit。
- Chris Eagle和Shellphish寫的IDA插件:https://github.com/cseagle/ida_clemency
- Binary Ninja的人寫了cLEMENCy支持的插件:https://github.com/trailofbits/binjascripts/tree/master/clemency
- PPP的工具:https://github.com/pwning/defcon25-public