DEFCON 21 CTF参赛记

7月31日

我和Kelwin、zTrix、LittleFatter等同行,在大本营集合,并领到了队服:

队服背面logo总感觉需要重新设计一下。另外三名队员已经到达拉斯维加斯了,而Fish尚未启程。在UA888飞机上待了三个多小时,因为飞机故障我们被安排在北京临空皇冠假日酒店住一宿。

8月1日

在San Fransisco转机后飞抵Las Vegas,分组乘出租车到Rio All-Suite Hotel and Casino。有点惊奇的是这里的驾驶员也知道DEFCON。

会场入口处的标识牌:

进入会场需要一个白色badge的,受邀请的人可以免费得到,而其他人需要花$180购买,入场费还是比较贵的。

晚上大家在附近一家自助餐馆吃饭,但分成好几个小组,彼此不知道对方的位置,感觉我们特别像某个地下组织的成员接头……后来好不容易8名队员都聚合在一起,不少对队员是第一次见面。DEFCON CTF主办方安排在21:00举办一个聚会,让个支参数队伍见面。我们整体感觉都很腼腆,只有Kelwin勇敢地站出去一直在和其他队伍聊天,而其他人都是和队友聊。越南队clgt可能更腼腆些吧,都没有来参加聚会。

DEFCON 21 CTF

DEFCON 21 Capture the Flag比赛总共有52小时,分为2日~4日三天举行,前两天的10:00到20:00以及4日的10:00到14:00在DEFCON会场的CTF房间进行,在这段时间那些带有vulnerability的服务对外开放(可以登录给服务打patch,也会遭受到其他队伍的攻击),其他时间段选手们一般在宾馆,无法访问vuln机器,但是可以进行离线分析。

8月2日

8:30左右我所在的Blue-lotus的队员们聚集起来去Burger King吃早餐,赶到赛场已是9:00多了。赛场上有20支队伍,每支队伍都有一份规则说明书。这次CTF采用attack and defense的形式,每支队伍都有一个编号,被分配到一个10.5.$team_id.0/24子网,10.5.$team_id.2为部署了很多需要保护的服务的机器。

10.5.$team_id.2即vuln,是运行在ODROID-U2(ARMv7 little endian)上的Ubuntu 12.04.2系统,启用了ASLR(印象中/proc/sys/kernel/randomize_va_space是1)和NX,所有需要保护的服务都对应/home/下的一个elf比如/home/bookwarm/bookwarm,所有服务都由xinetd代为监听端口,xinetd运行服务时会把权限drop至服务名对应的用户比如bookwarm。选手们拥有10.5.$team_id.2的chroot环境中ctf用户的密码,但没有提供root权限(也不能sudoroot)。内核被修改过,proc下相同UID的很多文件如/proc/self/maps/proc/self/mem等都无法访问,很多软链接如/proc/self/fd/0等也无法readlink。vuln上安装的软件非常少,gdb等很多工具都没有提供,开启了ptrace protection。

/home/tokens/下有各个服务对应的tokens文件如/home/tokens/bookwarm,权限为-rw-r----- 1 root bookwarm的形式。假如bookwarm被其他队伍攻陷,被获取shell(uid为相应的服务名bookwarm),他们就可以cat /home/tokens/bookwarm获取token并在https://scorebot.ctf上提交。每5分钟为一轮,主办方会更新一次token,如果这段时间某个服务的token被其他队伍提交,会被扣19分(即丢失19个flags),这些flags会被平均分配给攻击者。主办方还会对服务做service level agreement检测,如果检测到下线或者不正确,也会扣19个flags。这些flags会被分配给其他19支队伍。比赛开始时20支队伍每支分到2500个flags即2500分,比赛中的分数变化理论上应该是零和的(但后来可以看到分数总和减少了,是因为主办方出了些bug)。

10.5.$team_id.1为网关,每支队伍分配到一个网口,使用的有限网络也属于这个子网。

10.5.$team_id.3不提供登录,但开放了sftp,允许以sftp -i ~/.ssh/bluelotus_capture bluelotus@capture:latest.cap /tmp/latest.cap的方式
下载到5分钟更新一次的tcpdump capture file,数据包的延时约为15分钟。其中来自其他队伍子网的数据包的IP地址的主机号都被设置为2即10.5.$other_team_id.2了。

首先要做的就是配置比赛环境,网线只有一根,却有8台电脑需要上网,zTrix同学的小路由器不够用了,紧急打电话给诸葛老师要买一个大的路由器。我们也没有准备好接线板和网线,好在men in black hats队友情给我们提供了好多根网线,非常感谢他们!服务器是ARM,我们对此都没有经验。Kelwin分析lonetuna,他还带了一块Raspberry Pi,ARMv6的,我跟着zTrix琢磨怎么在上面安装系统、配置环境,但是没有成功;另外就是配置QEMU,装好了Ubuntu 9.04,但是不能更新和装gdb。Fish配置的系统没有网络,也不能用。不过好在后来远在大洋彼岸的cbmixx给我们配置好了ARMv7l环境。到大概16:00多似乎都没有队伍发现并利用漏洞,没有出现攻击流量。之后PPP发现了lonetuna程序的拒绝服务漏洞,其他各队都遭到攻击。这个就是tuna:

lonetuna

让人想到清华大学学生网管会TUNA

还有段小插曲,有场外黑客利用蓝牙漏洞控制了主办方的苹果电脑。

大约18:39新的服务reeses出现了。一直到20:00我们对各个服务的分析都没取得进展,由于服务持续处于拒绝服务状态,我们一度垫底,不过到20:00结束时达到了倒数第二。回到宾馆大家分析失利的原因,摩拳擦掌准备第二天的逆袭。我用DNS反查把各个队伍和子网列了出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
PPP 10.5.1.2
[Technopandas] 10.5.2.2
clgt 10.5.3.2
raon_ASRT 10.5.4.2
pwnies 10.5.5.2
Samurai 10.5.6.2
The European Nopsled Team 10.5.7.2
sutegoma2 10.5.8.2
more smoked leet chicken 10.5.9.2
blue lotus 10.5.10.2
routards 10.5.11.2
shell corp 10.5.12.2
shellphish 10.5.13.2
WOWHacker-BI0S 10.5.14.2
9447 10.5.15.2
men in black hats 10.5.16.2
pwningyeti 10.5.17.2
APT8 10.5.18.2
Alternatives 10.5.19.2
Robot Mafia 10.5.20.2
Legitimate Business Syndicate 10.5.22.2

又写了个简单的脚本每个一段时间检测其他各个队伍服务的在线情况,并打算开个nginx供队员们下载数据包。不过只是简单的nmap -sS -p $ports,没有使用服务特定的判定,很多服务失常的情况无法检测出来。

8月3日

昨晚大家通宵修补了三个服务,通过分析流量捕获强队的atmailreeses的exploit,我们运行脚本对其他队伍批量实施replay attack。我们的排名在逐步回升,而逐渐地,有近一半队伍的分数掉至了0分。

11:34左右又出现了两个服务:avoirtrouver。下午我们注意到last命令显示vuln被10.5.1.2登录过,而这个子网是属于PPP的,和主办方交涉后才知道主办方伪造了源IP。这才想到主办方做service level agreement的时候会伪装成来自其他队伍的子网。所以抓包文件中有部分流量是属于主办方的。外援任胜韦(似乎还是高中的学长耶)给我们提供了抓取排名数据的程序,我把它集成到检测服务在线情况的脚本中。flanker017写了脚本通过检测数据包中的1100字样判断是否有token泄漏了。

运行atmail exploit脚本的DeadCat突然表示Mac电脑的很多应用程序都被删除了,最后分析得出是因为把类似curl -F 'tokens[]=%s' --cacert ca.crt -E bluelotus.crt --key bluelotus.key https://10.3.1.5/redeem的命令行误用python os.system了。而有队伍故意让服务泄漏出1100;' rm -rf /#类似的串。DeadCat运行的脚本先筛选出包含1100的行,然后构造出的curl命令行被os.system执行,单引号被闭合导致rm -rf /命令执行,而Mac用的不是coreutils的高版本,没有--preserve-root的保护机制,导致这条恶意命令被执行。好在数据没有丢失,脚本也仍在执行中,但单点故障让我们觉得exploit运行在一台机器上实在是太危险了,zTrix和flanker017也赶紧运行脚本,避免单点故障。而我一直无法curl HTTPS的10.3.1.5,后来总算发现原来是缺乏client certificate,certificate和private key是curl-E--key选项指定的。Chrome则需要在Settings - Certificate manager里导入PKCS #12格式的certificate及private key。今天比赛截止时我们在第10名左右。晚上众人继续奋战,Fish、zTrix、LittleFatter等熬夜分析avoir和强队的exploit,还有一部分队员研究trouver。我试图对各队的分数做时序分析观察各个队伍解题情况,flanker017研究了好多token泄漏的数据包,同时打算在第二天用带有错误token的虚假数据包伪造攻击流量欺骗其他队伍。

一个小插曲:有个老外来找我们队伍聊了几句,初始还以为是来社工的其他队伍的领队什么的,后来知道原来是Black Hat和DEFCON的创始人Jeff Moss。今天赛场里社交活动挺多的,还有几位之前参加Black Hat的中国一些安全公司的朋友来给我们加油。

8月4日

9:00多到达赛场,发现我们的座位被移动到角落了。主办方的意思是背景音乐有点响,要让各个队伍受到平等待遇,有点主客场的感觉。

我们打patch并紧急赶制avoir exploit的自动化。不过我们的分数还是狂掉,另外也注意到昨天的两个replay attack的效果明显变差了。强队在攻击时已经采取长连接的持续利用方式,昨天看到这条命令时还不以为然,因为服务的漏洞被修复了,大概是今天修补服务时出现了差错。各个服务都是以用户名为服务名的用户执行的,而那些服务的用户都无法登录,我们没有办法断开连接,后来才发现可以sudo -u reeses成相应用户执行pkill操作杀掉长连进程。这里又是个比较奇怪的地方,就是bookwarm用户密码和ctf相同,可以su bookwarm;但是其他服务的用户都无法su

reeses

aay观察到我们的vuln机器上各个服务的连接数都在14~27之间,方差比较小,令人生疑,猜测强队利用弱队作为肉鸡向我们发动DDOS。今天流量分析的准确度也大打折扣,流量中弥漫着伪造的token包。flanker017的exploit流量检测脚本精度大幅下降,我这才开始弄/home/tokens/的自动备份。这些脚本应该提早些写的。这个时候我大概跑了这几个脚本:检测vuln状态(ssh vuln $command)、定期抓取分数榜显示为网页(有队伍还把scoreboard可视化了)、定期抓取/home/tokens/、定期抓取数据包、两个vulnerability exploit脚本。这一天迷惑流量特别多,很多队伍都在payload中加上了1100这样的token疑似字样,干扰分析。我们用了三个工具,tcpdumptshark(和tcpdump相比慢很多,而且容易崩溃)和tcpflow。因为迷惑流量,我之前用的tcp contains 1100误报率极大。除了三四支强队,其他队伍的分数都在狂掉不止,我们对此却无能为力。离比赛结束还有一小时时主办方停止更新分数榜。光靠修补漏洞加几个夺取token的exploit已经不够用了,我们亟需能够弹shell的exploit。可惜Kelwin在比赛结束前几分钟才写出本地利用的弹shell exploit,已经没法挽回局势了。最后PPP(Plaid Parliament of Pwning)以相当于第二、三名分数和的巨大优势夺得第一,奖品是8个黑色badge;Men in Black Hats夺得第二,奖品是比赛中用到的20个ARM开发板;韩国的raon_ASRT获得第三;我们Blue Lotus第十一。

反思

今年起Blue Lotus的战力有了长足的进步,吸纳了Web安全方面诸多高手,在各个CTF比赛中开始崭露头角,有好几个比赛都打入了决赛。但我们和最顶级的队伍还有不少差距:

  • 交流不畅,协作不顺。我们也不熟协作工具的使用,对题目分配人员的方式上也处于摸索阶段。我们使用了Google Docs,也用了口头提醒的方式,但还是有很多队员相互间缺乏了解,发现的东西难以有效分享给大家。
  • 使用的分析工具、设备和其他队伍相比较为落后。顶级队伍似乎都有高版本IDA pro;包括ARM在内的反汇编器;chromebook、树莓派等ARM环境设备。缺乏漏洞自动利用、入侵检测等工具。
  • 缺少自动利用、分数榜可视化、入侵检测、系统加固等方面的工具,导致很多人力浪费在了一些机械重复的劳动中。
  • 分析能力,包括二进制、web、数据包等多方面。队中擅长二进制的人数不够,而主办方Legitimate Business Syndicate出的题目清一色二进制。资格赛时web题目也都是被“秒过”的,主办方出web题目的经验不足可以想象。我和flanker017也是在比赛中学习tcpflowtshark命令行的使用,在数据包分析上和其他队伍有很大的差距。分数榜的可视化做得太晚,可以看到韩国队伍绘制了漂亮的曲线(可能是matplotlib)。
  • 缺乏attack and defense经验。我们参加的jeopardy比赛不少,但攻防就很少,对这方面的经验几乎为零。
  • 思路不够开阔。比如有队伍想到了泄漏1100;rm -rf /#的恶意子串反害攻击者。强队想到了长连接nc多次提交token实施ATP、伪造攻击流量给对手造成分析上的麻烦、利用肉鸡实施DDoS攻击等。

最后第11名,但是没有自主开发的成功exploit,感觉不好。另外背景音乐有点响,很受干扰。

8月5日

8月5日一行人从Rio All-Suite Hotel and Casino离开,入住The Quad Casino and Resort。在Check in的地方看到一张中国面孔。他从我们面前经过,走了很远又回头看了看,没过多久他又走回来了,问我们:“Are you from China?”“Yes.”“我们能用中文吗?你们是Blue-lotus吗?”原来是HITCON的PK丛培侃,果然在这个地方过往的每一个旅人都可能是位顶级黑客。

很荣幸能参加这次CTF,为了这次比赛受到的困阻两只手肯定数不清。好多次我都感到绝望了,能坚持下去克服重重艰险多亏了同学朋友们的支持,组织不出什么语言来,但我真的很感谢你们。除了以前就见到的Kelwin、zTrix、Fish,还有资格赛时见到的flanker017、DeadCat这次又见到aay和LittleFatter。LittleFatter胖乎乎地很可爱,aay也有和远小于的萌形外表,认识诸位并一起为梦想奋斗感到非常高兴。和几位交流中了解到网络安全的很多资讯受益匪浅,最后祝Fish一路顺风,Blue Lotus的各位都会继承你的未完的理想的!

8月21日更新:SQL数据分析

赛后主办方提供了比赛中的一些数据:http://blog.legitbs.net/2013/08/2013-finals-scorebot-sql-download.html

  • 最后的分数榜上20支队伍的flags数之和为42372,而初始时是50000,这是因为剩余的flags都被分配给21号虚拟队伍了,用处是在19 / number_of_explots不能整除时,把余数分配给虚拟队伍,之后虚拟队伍趱足了flags再交还这些flags。但实际的实现存在问题,导致flags总和变少了。从数值上讲,这个bug对非掉flags的所有队伍的影响从绝对值上来说是均等的,所以还算公平,可以看作规则更改了。
  • flags表表示各个flag的最终归属,但captures/redemptions表的处理顺序并非是id/created_at/updated_at,所以要确定出所有历史时刻的分数表是不可行的。