很荣幸今年成为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