opsbet娱乐官网

g22恒峰DEFCON25 杂谈——一场 CTF 奇幻之旅 极客沙龙

来源:大发 | 时间:2018-10-06 人气:1082
  •   大家好,我是来自上海交大 0ops 战队现任队长 seabreeze。今天在 GeekPwn 上海站的“极客沙龙”现场给大家带来关于我们参加美国拉斯维加斯举办的 DEFCON25 CTF 的一些分享。

      首先简单介绍一下 DEFCON25 CTF,g22恒峰它是跨度比较大的比赛。DEFCON25 本身有预赛,就是解题模式获得决赛的资格,决赛每年在拉斯维加斯举办,是攻防模式。

      今年的 DEFCON25 CTF 规则和通常的 CTF 规则基本相同,但是有一些不同的地方,比如选手可以直接获取其他队伍的 patch,你可以知道这个队伍怎么修补漏洞,然后修改你的 patch,这使比赛的场景更加多变,更加复杂化,它也带来一些其它的影响。

      然后还有一个就是 flag 是存在于程序运行时的内存中,一般来说二进制题目的 flag,存在一个文件里面,你要通过读取文件来获取。这次比赛的 flag 都是直接读到内存中,一般用一个任意地址读获取,你攻击的时候就没有必要获取服务器的权限,这个比赛主办方不会让你获取服务器权限。这样的话可以避免很多黑科技。

      今年最大的不同就是 DEFCON25 CTF 使用全新架构,接下来我会介绍一下,它是专门为这次比赛设计的。

      首先介绍一下这个名为 cLEMENCy 为CTF而设计的架构,指的是设计的既不是大端,也不是小端,是一个中端的计算机架构。

      它这里 BYTE 是 9bit,很多的工具都会失去作用,一般来说一个 INT4 个字节,而它这个架构里面一个 INT 是 27bit 的数,也就是 3 个 9-bit 字节。一般的常规工具,它都是处理 8-bit 字节的,这样的话这场 CTF 比赛中所有的基本数据解析,常规工具来做是错的。

      还有一个就是中端,这里有一个图来说明,比如说一个 3 字节的 int 从高到低是 112233,然后内存里面是 221133,先放在前面是中间两位再是高的两位最后是低的两位,这个是它中端表示下的内存,这样的话,它加大了攻击难度。有一种很常见攻击,指针部分覆盖,比如说你只能覆盖指针的第一个字节,就可以把它改到一个相近的地址上,而在这里的话,它是中端,你改第一个字节只能改掉中间的 byte,改的很大,像这样的攻击很难实现,其它的影响还有很多。

      其它各种基本特性,都是与常规架构不同的,所以它和我们的常识是相矛盾的。它的各种指令设计和 ARM 架构是比较类似的,比如说它是支持栈的双向增加,可以递增也可以递减。因为这个架构的文档是在比赛前一天公布的,在比赛前一天我们根本不知道给的的架构什么样,需要在一天之内实现工具。

      它会提供一个调试器,会提供一个反汇编器,还会提供一个模拟器,其它很多工具都没有,比如说汇编器没有提供,还有交互用的库都要重新写,因为一般用的库肯定都是处理 8 比特字节。

      所以这些都是你需要对代码进行修改的,修改已有的工具或者重建自己新的工具,都是一天完成,这个对选手的开发水平也是极大的挑战。

      这个是程序运行的布局,我们可以看到它最低的地址空间是程序的一个空间,然后往后这些,它会直接放到这个地址,然后后面还有一些东西。

      因为它这个架构它只是创造了新的架构没有创造新的操作系统,也就是说没有 syscall 指令,必须通过自己实现指令实现各种必须的操作。比如你要发送一些数据,比如发送到标准输出,你要把你打印的数据放在这个区域,然后把大小写在这个地方,然后它会自动启动发动数据这个操作。然后后面还有一些共享内存,这些是没怎么用到的。

      它有一个新的架构,要有一个新的可运行文件格式,事实上主办方实现了程序的加载的格式,这里我这里表显示就是当你把程序加载到内存中,主要从 0 一直到 3FFF,这个区域的布局就是表显示的,这些都是有的,它直接相邻的贴在一起,它们的页数大小,是程序文件里面地址从 0×57 开始的三个整数,你可以直接设置好,每一段的大小,然后它会设置好权限,它这里实现了 NX,除了基本的程序运行用的 3 个段之外,然后就是程序动态运行所需要的段,它是有几个空页隔开了,栈空间的分配是直接从最高位往低,它的大小在程序里是固定的,除此之外可以看到,堆以外的段空间都不是特别大的,而中间的所有的区域全部给堆,通常的程序运行时的堆并不是一个很大,而是通过 SBRK 增大。

      这个就是非常简单直接把所有的剩余的区域给堆,这是它程序大概的布局,我介绍这里是因为我们后面用的和这个有关,这里我做了一些总结,这个代码段都是从 0 开始,直接连续 3 个段,也就是说它没有 PIE 的,程序代码在一个固定的地方,我知道它这个地方调用了一个函数,这个函数计算出了这些段大小。然后就是它的堆起始地址会放在这里,通过这个我们可以看出实现了一个比较简易的程序初始化机制。

      这是我刚才说的函数,这里有 5 个 SMP 指令,然后这里我们可以看到,有 2 个 CAR 指令,然后可以看到它有 2 个函数,我可以告诉大家,第二个函数就是代码真正在的地方,相当于 main 函数,然后前面的函数可以理解为一个 init 函数,对堆块进行初始化的操作,如果你想分析这个初始化函数,这个函数有 2 个参数,一个参数设置为堆的起始地址,第二个参数是堆的大小,也就是说把这个参数,先设好这两个参数,然后调用第一个函数,它就会自动实现对堆块的初始化,这样我们可以想到对这个程序进行修改。

      如果我们把这个参数,进行一个修改,这里起始地址原本是固定的,如果让起始地址加一个随机数,栈本来直接从高地址分配,我给这个分配栈的地址,减掉一个数,这样就实现了栈的随机化,修改代码可以实现堆栈随机,我们这次比赛也使用了这样的办法。后面到 0×57 显示反汇编错误,因为会把三个段的大小会放到 0×57 的地方,这是 3 个整数,并不是代码。这就和之前说的一致了。

      虽然这个比赛,采用了新的架构,但是也是有一些队伍实现了通用防御,像这次比赛有一个题目,这个题目它有一个功能实现了任意地址写,这个洞非常难补,你不能把这个功能直接去掉,否则就过不了主办方的检查,你要留下这个功能,又不能让攻击者利用这个功能,你就要过滤一下写一些预期之外的地址的操作,大多数队伍都是这样防的。我们不是这样,我们通过实现堆栈地址的随机化,使得攻击者很难拿到一个可控区域。这道题目我们只用了这个 ASLR 就达到了较好的防御效果。

      然后还有 PIE,事实上有些队伍通过也是对初始化函数修改,实现了 PIE,把代码加载到一个随机的地址,选一个不会被用到的地方,把代码数据全部复制过去,把那个地方赋予执行权限,这样你不知道程序在什么地方执行。还有一道题目它最后可以执行 shellcode,也是不能去掉的,你必须让这个功能保留,再进行修补,通常的修补方案是过滤恶意指令,而这样子实现PIE的话你这样根本不知道 shellcode 在哪里执行,实现了非常优秀的防御效果,我们当时想到了实现PIE,但是如果它有一个相对取址,这样的话你程序就崩掉了,所以我们没有加。

      结果事实证明这题并没有相对取址。然后,就是混淆,混淆就是 PPP 这个队伍实现的,他们可以把控制流打乱,这次采用全新架构,你只能看汇编代码。你的程序是可以给别人看到的,如果你程序修改非常小,别人看到你程序怎么补就知道你怎么做的,而如果加了混淆就很难分析这个程序是怎么修补的了。这次比赛主要有这些通用防御的方式。这次比赛,修改的同时要确保程序正常运行,还是难度比较大的,所以真正做到通用防御的队伍不是很多,大多队伍只是针对漏洞修改相应的地方,没有做大幅度的修改。

      你的修补,别人是可以下载的,别人根本不用思考怎么修补,它只要下载修补文件,自己拷贝自己的服务器上,抄袭你的,这样对你是非常不利的,因此产生了后门,通过修改,让你的程序运行时,通过隐蔽的后门可以直接返回公钥加密的flag,如果别人有队伍抄袭你了,你就可以用私钥可以获得他的 flag,可以说是一个有效的避免其它队伍无脑抄袭自己的方法。除了可以防止别人之外,对自己也有帮助,本身比赛里你访问不了你的服务器的,就是说这种情况你不知道你的 flag 是什么,如果给你程序加了后门,你可以获得抄袭你队伍的 flag,也可以获得自己的 flag,你发现别人攻击过来的流量,最后得到了你的 flag,那就是有问题的。然后此外设计的时候一般采用公钥密码系统,这样的作用万一别人没事把你后门逆出来,知道了后门的触发方式也没有用。

      根据开源的分享来看,我所了解的 hitcon 他们是采用背包密码,我当时比赛的时候并没有看到他们有用这个后门就是了,还有一个就是用 RSA。因为它是新的架构,你写这个后门要手写汇编,你要手写公钥加密,所以越简单越好。

      还有一些比赛花絮,这次比赛关注的都知道PPP是第一名,有一道题目,这个程序实现了栈的数据结构,然后 PPP 它修补漏洞的时候把原本的栈挪到另一个固定的地方。这是一种治标不治本的方式,有相当多的队伍直接抄袭了PPP,然后也没有从根本上修补漏洞,就是和 PPP 一样挪到另外一个地方,这种治标不治本的方法,你要把自己攻击的地址换一下就可以继续打了,大家拿着一个没有真正被修改的 patch,放了一天。PPP 自己没有补掉漏洞,自己也留了洞在那里,于是就这样打全场。

      主办方由于它在设置文件下载权限的时候没有设好,它是逐步放开的,结果它题目有一个获取题目的 ID 是直接递增的,你本来第一天只可以获得第一天的题目,你猜出 ID 递增,你可以就可以把所有题目文件下下来。然后还有就是 9bit 下你在逆向的时候不一定直接看汇编,这样的话大家一般选择自己写 IDA processor,有一些队伍把 9bit 扩展到 16bit。这种扩展 16bit 就适应 8bit 的工具了。这是一些花絮,这里我就不一个一个讲题目了。

      这场全新架构的比赛主办方准备了两年。从 2015 年就有这个想法写代码,然后实现了非常好的效果,可以说是一场十分精彩的 CTF 比赛。

相关opsbet娱乐官网信息

    无相关信息
Baidu