网络安全日CTF

4.29是首都网络安全日,除安全厂商参展炫技外,还有近70支来路各异的队伍前来参加为期一天的CTF攻防赛事。比赛分为上午和下午两个场次,各3个小时,中间不到一小时的休息时间。上午的比赛内容为线上答题,题目种类包含 Misc,Pwn,Web,Crypto,Reverse五个类别。相比下午的攻防夺旗赛,上午的题目和我平日研究的内容更贴近,因而投入了更多的精力。

上午的比赛,每一道题目的答案都以flag形式出现,通常是一个可以明辨含义的单词或其MD5散列,提交到在线答题系统即可得分,各个队伍的总分实时更新显示在题目侧边。赛程只有三个小时,遗憾的是很多复杂的题目连上手分析的机会都没有,庆幸的是有限时间减轻了精神压力,否则再多几个小时的头脑风暴可能就体力不支了。

Crypto

顾名思义,这类题目主要考察密码分析学的知识。和其他类别一样,每道题目都是自成一篇微小说,描绘了一个历史人物的经典剪辑或是谍战风云的早木皆兵。不难看出题目背后的用心雕琢,力图少几分枯燥,多些娱乐。比如第一道题目即是凯撒大帝经典的移位密码,出题者选择了13作为加密秘钥,刚好是26的一半,意味着利用加密算法穷举到秘钥后不用再绞尽脑汁算解密秘钥,而是再次加密就得到明文。

还有一道题目讲述了一个谍战中通过音乐传递情报的故事,并附上乐谱,要求从中还原明文,如图所示:

比赛时并没能参透,匆匆浏览只注意了数字。赛后后发现歌词原来也是提示,充满了浪漫的小趣味,用八进制格式化音符再转成asc码就是答案ILoveSecurityVeryMuch。

Pwn

这类题目没有太多变数,一般通过溢出漏洞让目标程序做些预期外的事儿。通常先给出Linux下跑的程序,只要分析清楚,写好利用代码,然后向指定服务器发包获得权限就能拿到flag文件。

第一题是在比赛中做出来的题目,还比较简单,只要用超长数据覆盖掉指定变量就能让程序流程改变输出flag信息了。

第二题就困难了一大截,程序运行后包含三次scanf输入,前两次输入都有strlen验证输入长度(可以使用0x00填充绕过长度限制),第三次的输入的内容虽然没有长度验证,但会被预定字串I_Need_BMW异或变换。如果变换后的字串和The_Pursuit_of_Happiness相同则会跳转到该字串起始位置开始执行。

虽然程序sub_804859C函数的溢出点很容易发现,且编译时关闭了ASLR和DEP,加之利用三次输入可以进行栈溢出覆盖返回值,但问题是整个程序空间都定位不到jmp esp类的指令用以跳向shellcode。考虑到题目特意包含了第三次输入内容经变换就可被跳转执行,溢出的思路也开阔了不少。

利用过程要触发两次溢出,第一次溢出覆盖ebp为I_Need_BMW等常量所在内存地址附近(不开ASLR时这个地址固定),然后返回值覆盖为sub_804859C起始位置sub esp, 168h的位置,如图所示:

溢出使得程序随后跳转到sub esp, 168h位置,保证ebp指向常量内存空间

这样第一轮溢出后程序会再执行一轮三次scanf,通过前两次输入中注入大量0x00触发第二次溢出,清空秘钥I_Need_BMW和比对明文The_Pursuit_of_Happiness,使得注入的shellcode不会因为异或有过大改动,只要提前反变换shellcode就可以使得变换后仍然不丢失语义。这样第二轮执行后,末尾会跳转到第三次输入的内容作为代码执行。

Reverse

这部分题目比较灵活,除对二进制程序的逆向分析外,还包含很多结合近年热门的解固件的问题。其中一道题目就是给了路由器的固件,要求分析出当中的后门反向连接的地址信息。虽然看过使用binwalk解包的案例分析,但真正拿到固件包时仍心有余而力不足。第一重解出来一堆zlib和squashfs,和心理预期的文件系统样式不符就停滞不前了。这部分题目要么是简单到分析过后就没有印象,要不就是思路上走不通只好放下。

下午的攻防实战环节还有一道比较难的逆向题目,需要分析一个放大镜后门程序的登录口令。一旦输入正确的口令,程序会弹出资源管理器,这样就能绕过远程桌面认证输入直接渗透进入目标主机了

首先这个看似轻巧的后门包含多种反调试陷门,由于平时分析漏洞多用Immunity Debugger,缺少反反调试的插件,只好用IDA纯静态查看。其次,程序内的函数调用逻辑十分抽象,关键算法都是数十个虚函数的嵌套迭代,用静态分析的方法十分吃亏。赛后求助同事老唐,花了一天时间才了解了背后的蹊跷。

它极可能使用易语言完成了开发,因而程序逻辑不像C语言一样明晰。此外程序中还包含一个陷阱,如果通过URLDecode可以很容易解出来一个口令HXB{YAO-YAO-QIE-KE-NAO},点击登入甚至会弹出添加系统管理员账户的界面,并且IDA上下文内包含net user /add等字样,迷惑程度异常高。

最后用包含反反调试插件的OllyDbg跟踪到了真正的加密函数入口,输入的信息被加密后需要和另一个URLEncode的字串相同才可以。加密算法形似RC4,但部分结构被篡改,使用RC4算法并不能解出来真实口令。一个取巧的办法是在加密入口强制修改内存,将输入数据修改为URLEncode字串,查看加密出口时的内存就能发现真实口令HXB{HAHA-HEHE-HEIHEI-HUOHUO-XIXI}赫然出现了。

Misc

杂项题目就很丰富了,可能综合运用到其他题目的技术,并且包含很多有趣的彩蛋。其中一道题目是叙述了一个谍影重重的案件,高潮迭起的故事结尾,间谍U盘镜像落入囊中。镜像解开后,里面包含了很多映射故事中点滴线索的文档

其中systemzx.exe是关键的程序,执行后会释放机密的flag文件,但提示身份验证失败,flag又被删除。题目本意肯定是希望逆向systemzx.exe后找到应该输入的信息,让解压后身份审核通过,flag文件得以保留。

但实际操作中发现再次执行,由于解压缩的覆盖操作需要用户确认,解压执行流程被暂停,flag文件还未被删除,拷出来后执行就得到了隐藏的机密文件。这种彩蛋式的解法让人有种捡了钱的幻觉。

纵观上午的赛事,题目的设计真是用尽了心思,即保证三个小时各队都能有所收获,也有一定难度可以拉开差距,甚至赛后留给大家意犹未尽的味道。