如果说,滴滴出行(以下简称滴滴)是近几年来让大家出行发生翻天覆地变化的一家公司,想必你不会反对。
据滴滴给出的官方数据,滴滴全平台上每天超过2000万订单。与此而来的是,这么多乘客的消费数据和个人信息,滴滴怎么守护?
快速增长的滴滴意识到了这一点。2016年9月底,硅谷安全教父弓峰敏与网络安全资深专家卜峥加盟滴滴,弓峰敏出任滴滴信息安全战略副总裁和滴滴研究院副院长,负责制定信息安全战略和研发下一代信息安全技术,卜峥则担任滴滴信息安全副总裁,全面领导信息安全团队。今年3月9日,滴滴又宣布在加利福尼亚硅谷成立滴滴美国研究院,重点发展大数据安全和智能驾驶两大核心领域。
弓峰敏表示:“滴滴平台从乘客到司机到合作伙伴,涉及大量金融付费交易的过程,带来信息保护以及类似身份信息偷盗、欺诈犯罪等有关问题,滴滴需要保护客户信息、避免付费和交易过程中的欺诈以及个人账户信息泄露等,而最让人振奋的是,滴滴不只是解决出行问题,同时还能解决更大的问题,从国家到全球层面,包括城市发展、交通、环境保护等社会问题,这是极大的挑战!”
随后,滴滴在 5 月 17 日启动了首届滴滴信息安全闯关赛 (DDCTF),5月30日已结束。
先挖网络安全大佬,再通过大赛寻找优秀的网络安全人才进行储备,滴滴走了一条“肉眼可见”重视安全的道路。
但是,别人怎么分析都是“边角料”,我们看滴滴自己怎么说。
6月8日,雷锋网宅客频道(微信ID : letshome)邀请滴滴公司三位安全研究人员来一场硬创公开课,聊了聊如何看待当前网络安全新趋势,以及滴滴接下来怎么做。
嘉宾介绍
翟津健:斯坦福大学计算机专业
杨军锋 : 获微软 MitigationBypass Bounty
王宇 : 在 Black Hat USA2014 演讲和出任 GeekPwn 活动评委
刘潇锋:滴滴出行信息安全工程师,多年Web安全建设、攻防溯源、安全研究经历。
[从左到右依次为翟津健、杨军锋、王宇、刘潇锋]
以下是公开课总结文实录+视频,在不妨碍原意的表达上,雷锋网(公众号:雷锋网)略有删节,并分为上下两篇,视频均有:
若想获得此次公开课完整 PPT ,请在雷锋网网络安全频道的微信公众号“宅客频道”(微信ID:letshome)回复“滴滴公开课”。
杨军锋:这次是由我们四个人,包括王宇、翟老师、刘潇锋和我来给各位观众聊聊这次 CTF 比赛以及当前网络趋势的情况。我们讲解题目的同时会穿插一些我们对现在网络安全趋势的看法。
这里是我们四个人一些简单的介绍,可能大伙都比较熟悉,翟老师是属于一路学霸性的,潇锋是搞web搞得比较好的人,我是里面最矬,来打平均线的一个人。
这次我们要聊聊为什么我们要办 CTF 。我们希望通过办 CTF 来传达我们对安全的一些理念,包括我们需要什么样的人才,我们期望的这些技能是什么,我们希望通过 CTF 传达信息给同学们。我们这次办CTF的一个重要目的,就是促进同学们对滴滴安全的了解,知道我们对极客精神的一种追求。
这是我们的愿景,最重要的还是要玩得开心,在玩得开心的同时,能够从中得到一些知识。有什么补充的吗?
刘潇锋:没有什么补充的,我觉得CTF活动更是一种交流,还是玩得开心最重要。
杨军锋:我们这里的愿景是我们都在这次比赛中玩得开心,同时能从玩比赛里拿走一些东西,不管是经验也好,锻炼也好,知识也好。
在这次比赛里面,我看到有一些同学可能在某一个方向比较薄弱,看到他花了几天的时间去学,有时学web,学一些知识,回来解题,我非常高兴看到这样的同学,一边做题,一边学习,然后在学和做中,我看到有一位同学,他在最后解题思路里写到,这次比赛解决了他很多年没有系统化学习过的一些知识点,这就是我们听到最好的回馈,同学们学到东西,我们非常开心。
我们接下来的议程就是会讲解一些题目,但是由于我们的时间有限,不会把每一道题所有细节都陈列出来,主要就是讲讲思路,大概是怎么做的,应该从什么方向想。这些解题思路并不是唯一的,除了这些解题思路之外,可能还有其他的一些很好的解题思路,我们无法一一陈列在这里,可能会有更好的解题思路。我们在这里讲的只是给出了一个预期的解题方式,不是标准,也不是唯一的。
这次比赛我们一共准备了11道题目,很多同学说为什么没有漏洞利用的题目,这个题目由于最初规划候,我们想要作为线上赛,没有任何服务器交互的环节。所以在这种情况下,完全对溢出的利用题目也好,同学们解题、服务器搭建还是各方面,跟我们最初设想的可能会有点儿不一样。
我们最初决定的所有的题目都是离线题,不需要同学们连接服务器,但是最后玩出web题目什么的,还是搭建了线上的环境,这是后来由于出题时一些不得不折中的地方,除了这三道web题,其他都是离线可以解的题目。
第一道题目是Mach-O上的一个逆向题,接下来就是一个安卓题,主要是JAVA的、逆向的,比较简单,这些都是windows题目,这道题目主要就是模拟典型的钓鱼攻击场景,是长着一个word文档的图标。这个是Panic,就是由教授来出题的,这个崩溃题目,你只要加载、驱动,然后你Mach-O,Panic就是会崩溃了。Injection就是web题目。
接下来Android normal这道题就是翟老师出的。这道是快战攻击题,这道题挺有意思的,我相信很多同学如果做到它,印象应该挺深刻的。然后是Crackme,是到RC6到AEC算法变形题目,很多同学对它很有怨气,今天它的出题人也来到了现场,不是来到了现场,也来到了线上。接下来的这道题目就是代码神经题,我见到有好几位同学被卡在这里。Findkey这道题就是比较纯粹的数学题了。最后一道压轴题是翟老师出的安卓难题。
这个排序我们是根据经验按照我们想的难度排的,但是确实是也不是很严格地按照难度梯队排列,但是大体上是升序的难度级别变化。
我们在讲题目之前,先来讲讲解这些题目所需要的一些工具,有一些工具可能是我们比较偏爱的,但是你也可以用其他的同类型的工具,都可以,这个没有一定非得要用哪个工具去完成调试、抓包这些任务。
web版编译工具的话,刚开始比赛的时候有一些国外的同学过来问我们说他们没有IDA,怎么办?其实IDA是有一个5.0的免费版本的,只不过是不支持反编译长C维代码,如果版权意识比较好的同学,可以选择使用免费版本。当然我并不是在这里倡导我们使用盗版的IDA,我出于一个官方的立场,是绝对不能推荐使用盗版的。
这个Hopper,我不知道怎么念前面这个反汇编工具,这个好像只是说Mac的,所以如果有用户Mac电脑的同学,你们可以考虑使用这个反编译工具,听说是挺好用的,但是我本人没有试过。
接下来这个snowman,我不知道有多少同学知道,这个工具是支持生成伪代码的,可以不依赖于IDA直接工作,如果你实在是版权意识比较强,希望享受F5的待遇,snowman可能是不错的选择。
接下来这个应该打CTF的同学都应该知道,但是我其实没怎么用过它,所以我就没办法多介绍。JEB是PK的时候应该用的比较多,后来这个GUI的程序,也是一个JAVA的反编译程序,挺好用的。
调试工具的方面,提供选择的面也是蛮多的,有OD、inmulity,由于前两个Oldydbg inmulity都没有支持64位windows,这个是支持64位的,而且我看到他们最近的开发进度也非常快,我们也可以关注一下,这个可能是我们最常用的,特别是在我们调系统和各方面必不可少的调试工具。GDB我相信用过windows或者是Unis的同学都应该比较熟悉,因为CTF里面出现比较多的题目应该都是需要GDB去调的,IDA本身也有一个调试支持的功能,都是可以用的。
除了前面所有这些调试反编译工具之外,抓包的这部分工具也比较多,各种各样的,这里提供了一些选项给同学们。其他的类似工具我觉得比较有用,而Cooker是一个虚拟的分析系统,特别是你把一个APK、ESE提交到分析平台里面去,会给出一部分比较详细的分析报告,当你有时候在分析的时候是比较有用的,因为你比较直观地得到一些分析报告。
这个工具套件我相信对windows有接触甚至没有接触的老用户都应该知道,它是微软出的一套官方的工具,里面包含了进程监控以及行为监控、进程管理器一些很强大的工具。
这是后面的一些工具,就是Netcat,这个工具就是NC,我们通常所知道端口监听,连端口的时候经常要用到的。然后salcat就是转发端口,这个时候就比较有用了。
这个工具比如说在求解一些线性规划或者是其他很多求解类题目,是比较有用的,你指定了约束条件让它跑吧,可能就比较容易求解了。
这个是我在这次比赛里面看到同学们的解题思路才知道有这么一个神器,我不知道怎么念,它也是一个有点儿像mitlab的这么一个元件,可以求解很多像离散对数、离散数学很多东西它都可以做,就是离散数论的一些计算它能做之外,其他的功能也很强大,推荐都去了解了解。
教授这里有什么地方要补充吗?
王宇:我觉得可能每个人都可能有一些用得比较顺手的小工具吧,也就差不多是这些吧,可能最多再有一些插件,包括我相信每一个选手都会攒一堆特别好用的脚本,每个人都有一点儿擅长的东西。
杨军锋:那教授刚才也提了一些插件什么的,都挺有帮助的,谢谢教授的建议。
接下来这道题目,第一道入门的题目是Mac,为什么出Mac?教授说一说。
王宇:第一道论文题目就是Mac的吗?
杨军锋:对,Mac64位的。
王宇:就是蓝屏的那个?
杨军锋:不是,这道是查理的那个。第一道题目因为毕竟是入门题,我们对选手的预期是比较低的,不管你懂不懂逆向,我们都觉得你应该可以做出来这道题目,因为毕竟是入门题目,我还认为是比较简单的一道题目。所以很多同学刚拿到第一道题目的时候,问我是不是没钱就做不了题目,不是这样的,没钱也能做题目,我们都是没钱的人,所以不是说没有钱就做不了这道题目。
另外这道题目其实由于太简单了,所以静态分析已经足够了,不一定要动态地去调试。当然你可以动态调试,如果你有钱,有Mac笔记本,可以动态调试,即便没有Mac笔记本,搭建一个虚拟机去调试也是可以的。
这道题目就像刚才的,用IDA或者是snowman去反编译后,就基本上能看到只有几个函数,我相信你很容易能找到关键点,你就一个一个函数去翻,看到有一个地方有易货,就是它了。这个函数不在正常的执行流上面,你正常执行可能走不到这里来,你可能发现几个函数,一个一个翻之后发现这里有输出,这里有易货,出于常年打CTF的惯例,应该已经意识到这里有问题了,那这样就比较简单了。
很多同学就觉得在标红框的这句话里面会有一点点困惑,不知道这里是怎么计算出来的,我在这里简单讲讲。这是一个开始,一个函数地址减去另一个函数地址,这个值其实是固定的,你只需要找到这个函数的地址之后,人工算算,算一下这个结果是多少,再移位,移完位之后再易货,这个全局数组的第一个字节,事实上你就已经拿到了V2。这里还有一个函数,你会发现你不需要去关心它到底是干嘛的。
接下来你看到的就是一个典型的解密流程,为什么你知道它是解密流程?后面有一个fanao allput,已经知道这里有一个最终的输出,就是输出解密结果。
我也看到当时很多提交题目的同学们,把这个全局字符数组的第一个字节好像是一个A还是V,就把它当成了邮箱地址的一部分发来,一直没有收到我们的回信,觉得是不是出问题了。其实这里你要留意这句最后的输出,你会发现输出是从第一个,索引是1开始输出的,这里有一个地址,这里是以索引为1的第一个字节,如果从1开始计数是从第二个字节开始输出。
所以这道题目比较简单。
刚才为什么我们第一道题目会是一个Mac题目,我在这里补充一点儿,因为我们现在大量的办公机器都是Mac的,包括我们滴滴里面很多同事,大部分同事都是用Mac办公的,Mac安全对于我们来说是一个很重要的部分。所以不管是我们内部防护,还是在研究方面,我们都认为Mac是一个不可忽视的平台。因为有人用的地方,它就会产生信息,产生信息就会有价值,这些有价值的信息是需要我们保护的,这是我们第一道题出Mac的考虑。
杨军锋:王宇老师是对于windows、安卓、Mac平台都有比较深的研究,属于非常优秀的专家,不知道他对第一道题目有什么看法。
王宇:第一道题是一个入门题,我相信可能不需要太多的训练都能把第一道题处理出来。刚才军锋同学说的我觉得是这样的。
我印象比较深的是2015年,有一个比较大的事件,就是美国的新地平线号探测器,它飞跃了冥王星,花了9年时间,48亿公里,NASA是当时很兴奋的一个机构,它在世界网络上疯狂地放各种冥王星的照片,甚至每天都是在以照片直播的形式直播近距离看冥王星。
你可以看到NASA看到内部庆祝的照片,他们所有的工程师几乎99%都是在用Mac book的机器。从这些照片去分析,你就可以推测出某些特殊的机构,或者是在某些趋势,已经是重心开始慢慢地由传统的PC向Mac平台和移动平台转移。
所以安全这个东西应该是有前缀,它的前缀应该是计算机安全,所以它应该是依附在计算机产业链的链条上的,应该是随着计算机热点的不断变换在变换的。
我觉得各位同学也不应该把自己局限在某一个很窄的领域上,应该是见多识广的多面手,我相信这样更受企业的欢迎。
所以第一道题和我们这次的出题考虑,虽然没有漏洞相关的题目,但是可能我们尽量让平台更丰富一些,有移动的、安卓的、Mac的、web的、windows的,应该来说有这方面的考虑。
杨军锋:好的,那我们就先开始讲Android easy这道题目吧,由于翟老师不在,我在这里简单给大家讲讲这道题目。Android easy这道题目真的就很easy,真的很简单,非常简单,以至于我觉得不用花太多的时间跟大家说。因为你直接反编译之后,看到的就是跟原码差不多的,完全一样的这么一个代码,我们会看得到在这里非常简洁,第一就是易货两个数组。
你看到中间有这些,其实这页PPT是翟老师写的,后面这些像偏移这些都不用看,你直接把两个数组给易货完之后,然后把所有字符打印出来,你发现里面就包含着key,把这个key交过来,这道题目就OK了。
接下来讲这道windows题目,很多同学拿到题目第一个反应就觉得这涉及到windows恶意木马的题目,确实它长得比较像恶意木马,长得像word,你双击它,突然就不见了。所以把一些同学给吓到了,真是不好意思,我们这些题目全部都是比较干净的,不会侵害你的计算机,所以不用担心。
这个题目背景是这样子的,现在当前的APTE以及大众化这种黑客集团、软件这些界限在不断模糊,以前很多时候我们觉得APTE会用高端的技术来做攻击,比如说漏洞,高端的利用去打一个企业,现在你会慢慢发现有一些APTE集团开始用一些钓鱼的手法,你看起来很低端,但是很管用。因为一个企业里面有几万人,只要一个人中招就可以了。
所以这些看起来粗糙,但是成本低,收益大的,这些手法,像现在的红攻击,你在很多地方慢慢发现,十年前曾经很火爆的红病毒,现在有重新泛滥的趋势。那像这些PE文件值长得像一个文档的攻击手法很低级,但是确实到今天为止,还是管用的。
所以这个程序就是一个整个像word文档,双击就会打开一个真正的文档,就把这个删除了,接着是一个Payload来运行,完全就是恶意软件的套路,但是只是一个比较友好的恶意软件。这个恶意软件在UPS外面扎了一层混淆,其实不是两层壳,你可以理解为两层壳,为什么要扎入一场混淆呢?因为我怕很多同学直接就用UPS解压文件,直接就拿到了,根本就不用动手脱壳,不用调试器怎么去分析。
同时里面有一个很小的反调试的功能,只检查PEB的级位,这个位置,如果发现正在被调试的话,就篡改掉默认进程堆,这会导致堆函数里面,离真正原始的反调试的点比较远,这样同学比较难去定位,这是故意恶心人的。
怎么去解这道题目呢?脱壳和不脱壳都是可以的,怎么去避免反调试呢?Ollydbg装OD这个插件就具有的反调试功能,如果你不知道怎么安装,那我今天直接去吾爱破解上直接拉吾爱破解专版,这个插件也集成了反调试的一些功能,我看很多同学直接用Ollydbg,根本就没有去碰反调试的那一块代码。
接下来怎么办?你可以脱壳,然后把它弄出来,用IDA分析,也可以在关键函数,比如说你会用行为监控发现它会写一个文件,会打开一个文件,你在关键函数上杀一个断点,等它断下来的时候,可以dnp这个程序出来进行,或者是你直接就在调试器里面调试也是可以搞定的。
这个主要逻辑就是释放一个文档,释放一个DOCS文档,并且打开,然后把字符复制到临时目录底下,然后创建一个进程,启动一个新的实例,最后删除原始的拷贝。
接下来就是下载Payload,就是像图片一样的东西,使用IC4算法去解密到JPG,解密完之后,在这里执行,然后在里面还会有一个单字节易货解密,最后解密完之后,就把这段削壳,那段其实是面向sbori的削壳,执行之后就弹出一个框,里面就都会有的那个key。
这里面有一个坑点,就是在Payload前面的四个字节其实是个时间戳,这个时间戳如果在1800秒之后,当前的时间戳大约这个图片要是Payload的时间戳1800秒以上,这个Payload就不会被执行,你如果去详细分析的时候,就会发现这里有一个坑,然后把这个坑跳过去,接下来你的代码就可以直接执行这段belou,最后拿到key了。很多同学说这个key事实上出题人是做了一个反向混淆,中间插了H,但是其实不是,由于它是一段代码,所以有一个push,就是H,这是汇编语言的push指令,并不是我故意去混淆的。
下一道题目是教授的Panic题目,把时间交给教授。
王宇:随便弄了一道 Mac 驱动的Panic题目。我觉得任何一个想从事内核开发相关的同学,首先调试环境,还有内核调试工具,包括调试的手段,这些东西都是一个逃不过的话题,无论你去打算做内核开发还是做用户开发,这个话题或者是这个时间的投入是成长必不可少的阶段,是逃不过去的。
我认识的很多同学都是机器上一堆环境,首先是一堆机器,机器上都是一堆环境,就是调试环境,这些都算是简单的,因为厂商会默认给你做一些支持。但是反过来,如果大家以后想做安卓 root或者是iphone的越狱,你会发现那些环境的调试友好程度是更加不友好的,可能在系统上是不会给你有一个内核级等你的调试器连上来,也不会给你提供符号或者是原代码。
这些系统可能都算是最强健的系统,如果大家想搞一些更冷门的东西,比如说像车载的系统调试、手机基站通讯的调试,这些东西的调试难度和调试环境的搭建、模拟,包括像一些思科专属设备的mix指令和一些专属设备的调试,可能会更花时间。
所以我们在这边简单地考察了一下,假设一个学生从来没有接触过Mac,他从零接触,到把调试环境搭起来大概花多长时间,可能这个时间的花费要在三个小时左右,这是给大家预估的成本。
结合第一张图,Mac系统调试的时候,我们可以看到第一张图,我弄了一个10.11的系统,LIDB是可以把这个系统断在加载阶段,这个时候系统启动它的,如果我们愿意的话,可以把它断下来,如果内核是自己编译的话,那就可以做相关的登录。
下一页是这道题目的本身了,这道题目的解法是真的没有太多的难度,因为我是告诉大家,只要加载就一定会crash,只要crash,内存里面一定会有key的信息。
所以我们看到的至少玩这个题的解法有三种,另外为了降低难度的话,这道题其实是放出了所有的符号,既然有符号,静态分析的难度是很低的。很多同学已经在代码中找到了做易货的函数,因为key的格式基本上是公开的,前面是一个生成的哈希值,后面是一个@滴滴出行结尾的域名,你直接去找@,还有.com这种关键字,其实很容易就能把这个邮箱的key给枚举出来。所以我看到大部分同学,可能是90%的同学都是用枚举的方法做的,但是大概也有三位同学用的是大环境去做的。
其实你只要把环境搭起来,从第二张图可以看到,直接在滞尘器里面搜一圈,发现至少是前几个很可疑,每一个都去内存看一眼,就可以找到了。
这是静态的方法和动态的方法。
另外还有一些同学用的是创建了一个pradonp,然后从中间搜这个特征,这也是一个很好的方法。我相信一个人对这个理解和用的手段不一样,有静态简易的方法,也有动态稍微难一点的方法,虽然动态的方法会至少花三小时的时间,但是这个时间我个人认为是值得的。
再下一页,我截了一个调试的截图,一个全黑的页面,就是LIDB,这个图如果大家熟悉undibge的话,再看这个会觉得很简陋,非常简陋。
第一,它连个密令行的输入窗口都没有给你,你想在这边输密令是不太现实的,这个是LIDB在密令行里输JY跳出来的默认界面。
第二,这个界面对于byneri级别的调试支持其实是做得非常烂的。比如,我们在最右边的cosdek的里面,看到战争的第0层,连byneri地址都不给你显示,只是默认显示原代码。
最大的一个问题是它跟nousceoul调试相比的话,windows现在看来真的是越见良性,给你做了大量的工具是免费的。
另外,它还做了上百条内建的building的conmad,你可以输入简单的感叹号××004327系统就能直接帮你解析符号,只要能找到对应的single,能帮你解析符号,能帮你去辨明内核的数据结构,能帮你把内核的数据结构按照相对可读的格式给你打出来。
实际上这件事情已经帮大家省了非常多的时间,但是可能你会发现在××004349没有太多人帮你做这件事情,特别是××可以看到苹果对于Mac的内核开发是非常不友好的。
这个是给大家简单地展示一下调试大概是长什么样。
这个调试环境已经非常简单,如果大家以这个为起点的话,再去看iphone的越狱,你们会发现调试的友好程度可能会再往下一个量级,无论是从符号的支持、加密文件如何做解密,还有调试密令,包括像友好程度,挺考验选手们的耐心和实力的。
我的幻灯片前三页已经讲完了,最后一页其实是做了一个截图,是想说一下那道题目有一个附加的小问题。Panic其实是很简单的,你只要一加载,过一小会儿,这一小会儿可能是几百个毫秒,这个系统就Panic,就蓝屏重启了,但是它的原因是什么?
如果是他想回答这个问题,想得到这个题的附加分,可能需要的背景知识有:
第一,搭建一个调试环境。
第二,可能需要动态调试一下这个驱动,大概是在做什么。
第三,如果调试这个驱动去看这个驱动的时限的话,就会发现这是Mac平台标准的发System Callstack驱动,可能是需要知道一下Mac的文件系统是怎么做回调这件事情。如果大家熟悉windows驱动开发的话,mini showter driver整个的设计其实是非常讲究的,微软20多年、30年的设计迭代了好多版,现在这个mini foot的设计其实是非常漂亮的一版设计。
比如,以第三方做showter driver的方便程度来讲,我说的第三方可能是指杀毒软件厂商,做硬盘加密的厂商,还有做磁盘还原、过滤、影子系统的厂商,这类厂商在做产品架构的时候,微软已经帮你考虑了很多事情了,很多事情都需要你做,但是反过来,在Mac Cernol给你callstack的条件是非常简陋的。你可以看到从2003年到2017年14年间callstack的代码都没有怎么更新过,这件事情在windows cernol其实是不可思议的。
我觉得比较奇葩的一点,你作为一个文件系统的回调,至少系统应该告诉你这个文件应该被创建或者是打开,但是真正去看这个Mac的文件系统规律驱动的时候,你会发现Mac没有把文件创建的事件作为一个回调发给你。我想作为第三方开发的人,一定想要区分出什么是文件的创建和什么是文件的打开,这是一个很关键的问题。怎么做呢?可能只有自己写代码来做了,既然Mac没有给你提供任何的帮助,那就只有自己做了。
所以我在第四页的截图,左边的截图是我自己写的内存的打印,我downp了某一个函数入口的RPP所有callstack的信息,通过解析这个信息,我们能找到每一层callstack的战争和防御。右边就是我在驱动里面集成了一个disdome的引擎,我会访问我想关心的内核函数。
我在这边列了两个,每一个都列了前多少个字节,没有列太多。
第一,反汇编OSKEXT Start这个函数,这个函数是所有驱动加载的函数。
第二,VM Open,这个东西是属于文件系统的处理函数。
也就是说我如果结合左边的图去downp callstack,解析战争,再结合右边的图去反汇编,我能把整个文件系统的callstack调用站,我所有负函数至少能识别出来。这个时候再去结合负函数里面找一些特征。
比如说文件的操作,负函数里面有一个调用,里面带着参数的Fnode,如果置不同位的话,表示的含义是不一样的。比如说2是表示创建,0是表示打开等等。如果我能定位到它,并且我能解析当前文件实践Fnode的值是多少的话,实际上我就能区分出这个行为到底是一个文件的打开行为还是创建行为。但是这个过程理论上应该是操作系统帮你做,但是如果操作系统没有帮你做的话,你就得自己来。所以我其实是在这边演示了一个怎么自己来的一个代码。
再回到这道题目的附加分,为什么这个系统蓝屏了?如果能把这些东西都简单摸一圈,它的答案应该是在31次文件操作的时,并且当前的文件事件是一个qufir操作。
这就是整个出题的考量和题目的细节。它可能会比较花选手的时间,特别是如果选手不熟悉的话,但是实际上真的去花一点儿时间折腾系统调试,我觉得是值得的,并且相对来讲是比较练内功的。
我上大学时,有一位老叫张银奎,他刚开始写他那本鸿篇巨著《软件调试》的第一版,那时候我是上大三。当时我是主动跳出去帮他看看,帮他打杂。实际上我真的去审校这本书的时候,我发现里面有非常多的细节,他那本书更多的是在windows Cenol,因为他本人是英特尔的,他可能集中在英特尔CPU。
如果大家再去工作中结合Mac等等,实际上内功的修炼还是逃不了的。刚才有同学在直播间里说一方面可能需要广度,另一方面深度怎么做呢?每一个点的积累都是值得花时间的。
刘潇锋:我们确定出来一共有四列的时候,就可以在脑子里面构想一下这个 flag 所在的这张表大概是一个什么样的结构,用我们现在在界面上看到的这样一些东西。我们有四个标题,每个标题里面有内容,标题里面可以通过ID这个参数知道肯定在这个表里有一个ID。flag应该是在第四列,因为总共就只有四列。所以我们就画出了像PPT里面的这样的一张图,flag大概是在这个里面,我们需要在这里面注入出来。
刚才前面是限制了空格、逗号、引号、斜线,当然这个对于大家常搞四核注入的人来说,这个比较容易绕过的,不允许空格,我们可以用;不允许逗号,可以用join的形式,我们需要多少字段可以用join构造出这样一个字段数;如果不允许引号的话,可以采用十六进制编码。
有了这些手段,基本上可以去实施了,因为在测试时没有发现关键字被过滤,所以可以尝试一下,先使用联合查询注入这样的方式,接下来的注入方式其实很套路的,就是利用masacal系统表、information sikima这样一些库里面的表的字段。
首先第一个语句,就是把数据库的名给注出来,我做了一个处理,就是把所有的0a,之前说空格是过滤的,但是我们用0a来做间隔符,但是为了方便大家看PPT,我就把0a又改成了空格,实际上大家测试的时候还要换成0a的。第一个语句就是把数据库注出来,中间有一个十六进制编码,解析出来就是information sikima,就是说我们先获取这个数据库里面到底有哪些库名,把information这个系统库先给排出去,这个是很常见的思路。我们注出来一个结果,比如说数据库名是T1。
接下来我们再用table name这个表把表名注出来,这也是很常规的方式,就是news。
接下来再注字段名,是用callum name这个字段来注出来,是secret。
这样我们就还原出了之前我们这张表格里的flag所在字段的字段名是secret。
接下来就是很显然的,我们会去构造,从某一个库、某一张表提取某一个字段,这样我们就可以把flag拿出来了,当时这里有坑,这道题的坑就在这儿,把secret的字段也给过滤了。所以说可能做到这儿会卡一下。其实你去仔细想一下,或者是精心构造一下,就可以绕过这个限制。
这里面有两种方法。
第一,盲注。我可以不知道flag具体是什么,但是我可以用union的方式去构造一个字符串,和flag做一个比较、排序,根据前端页面的显示,我们会发现这个差异,这样的话我们不断地调整这个字符串,按字典序,我们就逐渐比较,就会把这个flag比较出来。这个可能需要大家用panson或者是PHP去写一个脚本,跑得更快一些。
第二,构造一个子查询。大家看我的PPT,相当于是拼了好几次,把这个flag的值给拼出来了。这里提醒一下大家,大家看最后一行为什么要这么写?其实也很显然,因为不允许逗号,我们不能写逗号,只能用这种方式写,这个时候flag就注出来了。
杨军锋:接下来这个题目是Android Normal,很多同学要求重复讲一遍刚才的注入题目的第一页,你把刚才那一页再跟同学们讲一下。
嘉宾:OK,第一页其实没有什么,就是题目的一个介绍。
因为我们在线题,你肯定要访问一下我们的页面,我们会看到页面上显示了这几个标题,每个标题是一个超链,你点进去以后会看到下面有一个针对这个标题的介绍,就是类似于这个标题文章的内容,最下面是flag,点进去,这个flag本身就是标题,flag is here就是这个文章的内容。但是这个页面里面并没有flag的值。
所以我们找到了这个注入点,就是news,叫php ID=4。
接下来我们要测试它有没有过滤特殊字符,我们测试完了发现单引号、双引号、斜线、空格都过滤了。
第一页就是这些内容,接下来我们用all derby去判测出原始的secal语句里面到底有几点,查询出来的内容有几点。因为union查询这个大家应该都知道的,子查询里面的列数和前面的原始查询的列数是一样,才可以在数据库当中成功执行反馈结果。
翟津健:跟Android easy一样,Android Normal就是用C++写的,所以思路也是一样的,看到第18到21行,就是XOR的操作,23行开始是一个outside,就相当于JAVA里的outside,向右移了一位,然后把第一个取出来。24行就是说在不停地找最后一个end,end就是一个0,就从头到尾把这个key取到,这个是Android Normal的题。
杨军锋:翟老师,你出这道题目,我们也是希望安卓平台、windows平台、Mac平台都希望每一个平台都有,使得我们题目的丰富度会更高一点。
下面一个题目是web题目。
刘潇锋:这个XSS题要比cecal room那道题难一些,做出来的人也少一些,大概20个人左右,这道题其实主要是考了一下CSP头,就是HTML5平时持的那个内容安全策略投。
首先这也是一个线上的题,大家访问了这个题的页面,会看到有一个Message Board,就是一个提交信息的界面,就是聊天吧。
下面有一个verification code,就是说验证码还要提交,这个验证码大家看一下,挺复杂的,这个验证码需要我们填写,做了一次MD5,又做了一次字符TRY5的截取6位以后,要和那个相等。
这个目的其实也很明显,因为XSS的题大家常参加CTF比赛的同学应该都知道,它一定是后台有一个程序在跑,你提交给他什么东西,他带着管理员的cookie去用浏览器访问,一定是在做这样的事情。
所以做了这样一个验证码的限制,实际上也是让大家别频繁地这么刷,降低浏览器开启、关闭的速度。这个我本地测试过,我Mac是I7的处理器,算这个码,其实有些码还是要算一段时间的,快的话可能一分钟之内就会出结果,慢的时候可能两、三分钟甚至十分钟可能才能创出MD5这个哈希值。
我们现在回归正题吧,下面的这个脚本大家可以看一下,这种脚本很容易做了。我们用浏览器调试功能就可以看到这个页面在返回的时候有一个CSP头,这个CSP头设置的default-src是self,script-src也是self,默认和脚本状态下只允许加载本域的资源。
但是CSP由于是一个非常新的规范,也就是近几年才开始推广开来的,所以说它存在着一些问题,主要是不同浏览器对标准的支持是不是跟得上最新的标准,支持上有一些问题。
所以说这道题其实也是利用了chrome浏览器对CSP头的一个bypass。
其实大家在网上可以看到这种bypass、CSP头的方式,这道题可以利用link这个标签,REL属性设置成预加载的时候,是可以访问外域的,是可以向外域请求资源的。
我们用一个在公网上的VPS监听一个端口,这里面举例就是7777这样一个端口,然后把这个link标签在Message Borad那个地方提交上去,提交上去以后浏览器一定会带着管理员的cookie打开浏览器访问页面,这个页面里就是你输入的内容,你输入的内容就已经被echo到这个页面里了,是一个link标签,相当于浏览器会自动地加载这个link标签访问那个地址,那个地址是你设置的VPS的地址,这样的话VPS就听到了这个请求,在referer字段里面打出了这样一个信息,这个referer就是指示了浏览器在访问这个link之前所在的页面是什么。
这里面值得关注的就是有一个哈希字段,这个时候大家就可以思考一下,这个哈希字段是做什么用的。其实就是它用来标识每一个用户每次提交的Payload的位置,你访问这个地址,带着哈希,就会执行哈希对应的Payload。其实我们可以在本地浏览器里面访问一下referer里面的请求,我们会发现它就正好是我们刚才提交的Payload,我们就会在我们的浏览器里执行,但是我们的浏览器里面只有我们自己的cookie,没有管理员的cookie,所以说我们没有拿到flag,这道题我们猜到flag是在管理员的cookie里。
这个时候我们发现CSP头里面没有支持脚本的内联执行,也就是说我们在提交的时候塑造的内联JS脚本是没有办法执行的,这个时候我们再结合刚才的哈希,我们开开脑洞怎么绕过这个限制。
我在下面直接告诉大家结果吧,我们可以通过二次攻击。
第一次,我们把一个JS脚本提交上去,提交的同时我们用link标签把这次提交的哈希值从referer里边带出来,大家看一下页面上的这个截图,我们提交了link标签和下面的Location.href,提交这个字段,由于link标签打过来的哈希值我们记录下来。接下来再去提交一个script的标签,script标签的sals字段就是刚才的referer里面记录的地址。
这样的话我们第二次提交的时候,后端会调用浏览器去加载这个script标签的sals的域,加载的时候正好是我们第一次提交的JS代码。这样的话我们没有做inline的操作,我们没有内嵌inline的JS代码,我们是用外域加载,而且这个外域还是在我们的self的限制范围内的,所以说这样我们就实现了一个在CSP这个限制策略下把我们的JS脚本执行起来了,执行的时候就会把cookie也带回来,带回来发现是一个64的编码,我们解码以后发现是这样的,上面写着set cookie、flag,还有flag的内容,有一个时间戳,后面是pass,因为cookie有一个路径。
我们发现这只是这道题flag一个位置的说明,告诉我们这个cookie在当前的根目下是拿不到的,必须要在T2,这个flag is here这个路径下才能拿到cookie。我们就想办法怎么去让我们的页面到这个目录下,然后把cookie拿过来以后再传过来。就是构造下面截图当中这样一个Payload,就是动态创建一个iframe的标签,这个iframe标签的sals字段就是刚才说的那个存放cookie的目录。由于它们是在一个同域下,不存在跨域的问题,所以我们可以在当前域去通过浏览器对象获取到我们创建的iframe标签里面cookie。
大家可以看一下这个Payload,我们通过两次提交,第一次提交的时候把我们接下来要执行的JS脚本先提交上去,换回了这个哈希值,再构造一个script标签,这个标签的sals属性就是刚才的那个referer,这样的话第二次再提交的时候,浏览器带着管理员的cookie去访问这个地址,间接地就访问了刚才动态创建iframe的脚本,这个脚本在iframe的内部是目标路径,在这个目标路径下拿到cookie,然后再通过iframe传到当前的脚本里,再给我们反馈回来。大概就是这样的流程。
最后的结果就是截图里面看到的get后面这样一大串,这里面就把flag给带出来了。
杨军锋:接下来这道题目是教授的,很多同学对这道题目怨气很大,我都理解,因为我对它也有挺大怨气的。下面有请教授。
王宇:为什么要有怨气?
杨军锋:因为太难了。
王宇:这道题其实没有太大的难度,可能就是题型会有比较多的东西,因为它是一张图片做展示,里面肯定是嵌了一些文件,解密有一个密码,反正就是比较杂,最后其实是一个Crackme算法的逆向。
如果从头开始说的话,13行代码就可以完成前两步的工作,主要是做一个解码,把头简单修复一下,就能从图片里面找到了,当然得定位到文件的偏移了,就能从这张图片里提出一个压缩包,压缩包是给了一个密码提示,解密完之后就是一个标准的Crackme算法的破解题了。
这道题目拿到了Crackme的程序,实际上如果大家之前看Crackme大赛,你会发现这道题目已经是难度降得非常低了,它既没有复杂的算法,因为几个标准的东西,MD5、RC6和VES这些东西,没有复杂的算法,也没有加壳,我没有选择加壳,也没有加venpratict这种变态虚拟机壳。理论上只要熟悉算法的话,花的时间应该在两个小时左右。
改的东西是仁者见仁,智者见智,因为这种算法里面可改的地方太多了,我只是随便挑了几个点做了一点儿小微调,但是我做什么微调呢?作为想解题的人就得做一个逆操作,这样的话才能把这个算法给解出来。
微调是几个地方:
第一,MD5里面的init表里面的初始值,这个改实际上对于题目没有任何影响,拿它当黑盒就可以了,根本不用关心我这边改了什么东西。
第二,2、4、6至少变了左移这些东西,左移的位数,包括像矩阵复值的顺序。
第三,AES的算法变了置换表的内容和虚化表的内容,我如果把这些表的东西都给变了的话,反过来查表的方法这个函数可能我也得重新写一下。
第四,4×4矩阵,我把里面的初始值也给变了,做了一下位移,我记得好像是左移了一位。反过来想去解题,解出key的人,所有的操作都得实际操作,我做了左移,他们就得做右移。
其实我觉得只要熟悉这几个算法的人,理论上是可以对比标准算法的生成逻辑,花点儿时间写一个脚本去跑一下我变了什么的逆逻辑。其实能看出规律的,因为我左移一位,大家右移就好了,这样的话就能把所有的东西还原了,这就OK了。
当时写得还比较仓促,还出了bug,因为这个代码实际上是我2009年、2010年甚至是2008年那会儿写的东西,好久没有维护了,只不过这次是把它捆在了一张图片里面,这个可能是想让大家多一些乐趣的地方。
我记得有一次我在蓝莲花参加的一个比赛,他们的图片很变态的,嵌了很多玩意儿。这个题目其实真的没有太多的点,我觉得想要高难度还是最后津健老师给大家展示一下流利的英文演讲。
杨军锋:其实教授刚才讲的这个,他把关键的代码已经贴在这里了,教授给大伙讲讲哪一个地区你做了变化?
王宇:我所有贴出来的地区都做了变化。
杨军锋:好的,那我理解了。
王宇:贴出来的link我是在网上随便找的,因为都是标准算法,那三个link都是标准的link,我变的就是这些地方,如果想去找dif的话,就在这些地方找就好了,实际上没有几处。
杨军锋:同学们都看见了。行,有一些同学会问,如果他们没办法识别出来这个RC6的话,那逆回去了难度是不是很高?
王宇:这是一个好问题,其实当时为了故意没有这样的难度,我隐藏了一些东西,比如说像有些key的生成故意没有写init的函数,然后把init的结果直接写在代码里了,做了一些最基本的特征隐藏。但是这一类的东西如果大家熟悉IDA的话,因为DIA官网每年都有IDA插件的评比,有很多插件得年度冠军的插件,通过bineri级别、相似度去识别你代码里面用了哪些库,如果大家用那个库去分析这个程序的话,他能非常轻易地识别出你的代码里面有多少代码和RC6的代码重合度非常高,相似度可能达到70%、80%、90%,实际上这个算法的识别就跑不了了。AES理论上如果大家熟悉工具,这道题目的解题应该很快的。
杨军锋:好的,这道题目还有别的补充吗?或者是有什么延展性的?对解密这块你有没有什么东西要跟同学们讲?
王宇:这些都是基本功,看雪那本书《加密解密》我觉得可能大家都是看得比较早的几本书之一了,工作中未必能用到,但是这些知识是应该需要掌握的。所以可能把几个串起来,再捆上一些图片逼着自己看一眼,如果能扛下来,这也是一个进步。
杨军锋:好的,我们这道题就到这里了。web题还是最受同学们欢迎的题目,这道题是web题里面最难的一道题目,还是由又帅又瘦的刘老师来跟大家讲解一下。
刘潇锋:这个题出的时候有没有告诉大家这是一个代码审计题?
杨军锋:告诉了。
(由于篇幅限制,想看接下来的内容,请搜索下篇)
本文作者:李勤
本文转自雷锋网禁止二次转载,原文链接