James Forshaw:大家下午好,我是James Forshaw。我们的部门主要是看一些微软和苹果的项目,我所做的工作就是Windows平台,比如说基础问题、系统问题。我们今天的讨论是和大家分享我们的一些研究,有一些有意思的漏洞。
我所说的是记录,记录可能并不是非常有意思的一个话题,但是我做了一些研究,我把这个微软的记录作为我的研究中心,作为深阶的记录,比如一些潜在的功能,这个可能是对Chrome的浏览器是非常重要的,比如所做的一些事情怎么使浏览器系统更加安全。
我们看到潜在的或者是隐藏的安全的事情,比如可以有API,可以有Windows,看看最后的功能。我们也要找漏洞,非常有意思的是我们找到不一样的漏洞,有一个解释的方式。
记录有一个问题是写数据,并不是所有的API都容纳下来,必须有一些有限的真正的这么一些数据可以放在我们的记录里,太长了开发者就可能不会来读,所以另一个问题就是Windows在演变,一直被增加和被更新,这样就给我们带来一个问题,有的记录并不是更新的,可能不是现有的时间写的记录。
还有一个记录并不是表现的现实,并不是来解释API的功能,所以有的时候有一些内容是丢失了,或者我们没有放进去,这个实际上会影响我们的能力,比如说我们在看这个的能力,比如说在写这个安全密码的时候可能会影响我们的能力。有的时候可能并不是非常准确,而且也不能非常完美的详细的执行。
整个系统的工作流程怎么样在执行过程当中充分发挥功效?我们做这样的事情是基于以下的原因,因为我们要在不同的平台上有不同的密码,所以我们想,我们的一些应用,我们打开一个文件,最后有一个开放的系统,可以在这个体系之下打开一个文档。
但这只是一个例子,我们有两个参数和两个限制,实际上打开的需要三个参数,所以我们要把这两个功能进行对接,我们要翻译这些参数,这样的话,能够让其很好的执行。很多情况下我们可以有这样的路径,这是一个典型的POSIX的应用。
Windows在这一方面有了新的举措,首先在Win32 API的复杂性,有简单的系统,必须建立开放文件的API,我们可以看到这个路径,其他的东西必须要从这个参数中来引出,这个实际上更增加了复杂性。
但是这个系统的呼叫可以变得更加差劲,比如在Windows,在这个概况之下,我们有的时候不能来保证这个路径能够进入这个文件,因为这个内容是不一样的,所以我们必须来进行改变,我们必须改变文件的参数。
Windows有不同的API的层面,但是我们只是要想一下比较重要的,一个就是最上面的一个应用,比如说内核,Windows API大家比较熟悉了。我们再深挖一下,到核,比如说有一些空的ADL,他们有不同的功效。
为什么我们要有这样的研究呢?因为我们发现了有意思的一个项目,是Bug Bounty的这么一个项目,我们把它设为IE是1,因为有些逃离,这是漏洞。这些漏洞实际上可以让你有登录的钥匙,这样的话,可以非常容易挖掘。
但是这个漏洞很有意思,实际上是一个固定的东西,要阻碍这个有意义的形象方面的链接。我们会看到在不同的层面上路过,也就是意味着,我想不受形象上的攻击,我想保护这方面,使我的系统不受攻击,我们必须从零开始。
必须是零,必须是记载,我们看MSDN实际上被记录了,是像大家期待的那样,是开放的,象征性的这么一个数据链接。还有一些相关的文件,实际上同样的参数,但是它的反应并不一样。
比如说我们开放的钥匙的通入,所以这个就告诉了我们在执行的过程中,如果支持这个方面,有这个安全功能的话,实际上没有被记录,这个记录并不是一贯的,即使它是有相似的功能。
当然,到现在差不多是三年之前,我在想我们怎么样最后能够利用这个来找到功效或者是找到漏洞,我就说我在找不同的参数之前需要API的记录,所以我们就有MSDN,我们可以上网来下载MSDN,可以下载文件。
有这个技术方面文件的记录,还有微软通过的一个方式,还有三方的一个文件,比如Windows,还有外方的一些技术,可以帮助你执行一些建议,比如说Windows API,就可以更加深入的了解系统的漏洞。
如果你有这些了,你就有源泉的密码了。这个通常是Windows给你的,所以可能是向外走的时候得到这些信息。这些有可能会泄漏到真实的世界中,你们可以使用。
我需要把这些文件记录,然后引出我们的研究,比如说线上和线下的。很明显,我可以使用Bing,你可以在美国用谷歌,用Bing引擎。如果是微软的产品,实际上有的时候可能并不是很容易的搜到,
你还有其他的一些引擎的选择,然后可以回到我们的记录,确实能够帮助我,这个没有问题,我需要有一种方式,能够找到一些功能。这样的话,我可以找到我们的文件和记录,然后来做我的分析。
所以我想起了DLL进口的这些图书馆,很多的这些内容实际上没有很多的口令,他们只是一个图书馆。如果你建立这个文件,你找你内部的一些项目来吸入,来进入,然后做你的项目。
这个就是一个有记录的样子,我把这个内容输入进去,最后有这么一些结果,这个结果理论上讲,实际上通过开发者来引进这个项目,引进这个图书馆的内容,这是基础的东西。这里差不多给我介绍了27000种功效,这么长的功效的名字,我们需要很长的时间来进行过滤,来把这些我需要的功能调出来。
也就是说,有Windows API的功效,我要把它过滤出来。
我想我不需要这些名字,我可以在SDN的线上来搜索,在搜索引擎上找到。但是我并不建议大家这样做,因为在此你可以看到非常小的文件,一个API是100KB,这个实际上有的时候不是很有实效,用的时候不是非常的实际,
有的时候可能不是你想要的,这里面包括了其他的内容可能不是你要的。但是还有一个线下的SDN,并不光是线上的。线下实际上有很多锁住的文件,这个实际上非常简单。现在就有问题了,我们没有目录,但是目录里边也有很多杂的内容,
每一个文件的头部都会说,比如说你可以选择,可以找到API的文件,这个可以让我使用这些信息来建立我的目录。然后我得到的这个结果,差不多有8千多个功能,是2万个功能之内做出来的,所以已经小多了。
现在我有我的这个文件了,非常接近我的这个简单的数据了。但是这些文字,XHTML的文件我需要来搜索。那么怎么做呢?XHTML的文件把节点放进去,搜索关键词。在此我认为,微软实际上在控制我,因为每一个文件都有保留的APL的提醒,还有自己的权限,知识产权,我并不想被这个来阻碍。
所以我把这个文件找出来,然后会有一些后端的这么一个非常好解构的信息,我可以找到这个信息,然后有参数可以进入。
我看不同的一些点和元素,是不是这个参数为未来保留和预留了,还有价值是不是被保留了,然后放到零,使用了还是没使用,这些都是我的参数后选的列。这个已经比2万的功能少很多了,我还需要一个原代码,这个语言是为了能够找到你的功效是不是正确的,
比如说这个参数必须包括一个节点的这么一个内容,怒容能够告诉你这是对的,你可以通过这个缓冲区,而且可以做出这样的决定,这就是一个安全方面的漏洞。在这些不同的情景,这些没有记录的密码,我们把它找出来,然后把它预留,作为预留的参数,微软用这些注释,所以这些注释实际上是一些普遍的参数,源代码,实际上意味着不同的功效。
为什么说这个很有意思呢?如果你想尝试一下,其实它是挺有意思的。我们可以通过这样的参数,比如说验证它是零,但是我们这是一个值,我们通过计算认为可能是一些Bug,我们就进行了一些修改。
通过这样一些静态分析的工具,我们就发现其实它只是对Call这一方来发起了一个警告。因为这个参数被存储了,所以说这个分析器并没有觉得你应该有任何的函数产生。比如说有600多个函数,如果有100个函数,我们发现它并没有被存储,就成为了一个很大的Flag。
但是我很喜欢自己动手去做这些事情,我们找出这样的一些函数,600个函数还是太多了,所以我就想去限制一下。
用一种系统的方法,我们就可以去看这个核心的函数,大概最后精简到90个函数,所以说通过这种精简你们可以去运算。至少我需要看一下有哪些参数是已经被存储下来的,我们就看这些文档有哪些信息的信息,然后我们把这些函数进行解析,看看它到底代表着一种什么样的情况,到底是否被使用了没有。
因为这些参数可能会给我们指出一些有可能有兴趣的一些函数,我们再重新看这些文档,看看有没有一些安全的保证或者是假设,怎么很好的看这些函数辅助的信息。我们有三种类型的代码,这是用一些角色表示的,大概有一半左右,基本上都是忽略了这样一个参数,他觉得根本就不关心。
因为我就觉得他已经都被存储了,就没必要去关注,这是一个结果的丰富。
我们知道,他们看到了这些函数很有意思的一种行为,我们就把这些参数拿出来,我们把它用于一个文档访问的限制条件。
它是很有意思的,但是最后的结果就是他并没有使用,我们要看是不是他的访问被签署了。如果说你只是打开这个文档,他是不可能再创建一个新的文档。不管你用的是什么代码,你就不可能实际的去做任何的运行,因为确实没有这样一种方便的方式。
还有另外一个就是说,这个函数因为它想要和一个文档发生连接的话就必须要进行写入。但是这个内核发现这个函数跟这个文件没有这样的连接,所以说我们在研究里面也发现了这样的行为。还有另外一种内核,在里面就记录了,他们把这些参数用于文档的记录。
第一个我觉得很有意思,就是创建了一种边界的描述符,他并没有直接的说他是0,他只是把他保存下来了。最后他是用这样的Flag去设计一个边界描述符。这个是跟私人命名空间相关的,在Windows里面,你可以对很多内核的文件命名,我们还可以跟不同的流程进行分享。
但是也有一个问题,当你出现了这种文件名冲突的话,比如说不同的文档最后都是同样一个名的话,他可能就会说你这个是没办法运行的,或者说你应该重命名。因为他们是在同样一个位置去分享这样的空间的,所以说我们需要分割这个资源,也允许你可以在不同的流程里面去使用这个文件名。
边界描述符的使用就是说,这个Caller必须是在这个边界描述符之内的,有可能是所有的东西,也没有一些特别安全的文档,我觉得这是一种比较通用的描述,但是还是要在这个边界描述符的范围之内。
比如说之前的文本,他们发现在Windows里面有一个用户名,也有一些安全的属性,后面我们看到了非Windows描述符,后面可以用于很多的应用。可能是在一个核里面发生或者怎样,我们不太清楚,我们发现这种边界描述符也是进行访问和检查。
比如他想访问某一个文件,我们要去看是否能够通过这个边界描述符的验证。比如说有一个格式可以看到被利用,有边界里面条目的数目,有名称。这里面有一个题目,只是一个名字,
并没有什么其他的描述符,而且也是把所有的资源,像Windows等等,使用这样的一些资源。其实是给当前的这些使用者,作为的这些应用者。这里面有两个事情,如果他是恶意的使用这个系统的话,他可以重新设定这样一个描述符。
还有就是所有这些应用都可能会打开一个Edge的私人命名,其实这里面有一些应用,你可以有一些命名的空间,并不能说你就是完全的可以去使用它来进行一些访问控制,而且它会影响到所有这些应用的打包。
在文档里面,你用这个边界描述符,还有其他的一些描述符到底有没有存在。在理论上你可以在任何的应用里面找到,但是在实际的操作过程当中还是要去验证。我们播放一下这个短片,在这里面我们有Edge的一个例子,我们在这里面有一个描述符,我们可以打开这个边界描述符,确保所有的人都能够在同样的情况下去打开它。
我们看到,其实它的访问控制是非常弱的,这里面有所有应用的打包,其实这是很糟糕的,因为在同样一个系统里面,基本上他们都是可以去拿到这些信息的,可以看到它里面的资源。这里面需要创建一些命名空间,去继承这些名称。然后我们看不同的应用者,可以把这个先播一下,让大家看一下。
很明显的,这个理想的状态,使用者的Edge有可能是来自用户的,用户在这里面不会有Crash这样的一些问题出现。我们看一下用户,就可以打开其中一个资源,看它是不是能够直接的接入这些资源。我们可以看到,从他们思想的某些概念里面继承过来的这样一种想法,这个就是我们刚才介绍了的。
Reg Load App Key,你必须是管理员,必须具有重新装系统的权限才能获得App Key。它其实也是一种保存参数,这个也没有问题。但是在这里面,这个参数是没有用的。另外我们再看一下这个文档,我们这个文档其实我们要看一下到底有哪些安全保障可以给我们去展示。
如果说我们能够做所有去做的事情,用这样的功能,那我为什么要用一些高级的?第一点你只能去加载到一个注册树里面某一个具体的位置,就像一个机器一样,你用这个注册树,他们把它叫做软件的,会安装到某一个位置,没有办法随意的进行加载。
还有另外一点,就是说没有办法去消除现有的这些Hive。我们可以去测试和验证这样的文档,是不是告诉了我们一个真正的真实情况,而是说事实上还是跨越过了这些受影响的区域。他们做的方法,就是在一些没有典型的受影响的位置,在这里面,基本上业协有一些特别没有办法用数字来定义的文件。
这样也好,我们可以把一些条目等等,这些特殊的Hive来进行处理。把这个应用放在这个默认的内置的系统里面,我们需要去验证,比如说这个是真实的,但是我没办法去验证它是不是真正的Slash A,也有可能是B或者是C等等。
到这个Hive中,我想给大家介绍一个世纪的系统使用的情况。是不是能够复制这个情景呢?可能是不允许的,或者是非法的,但是可以这样做吗?即使我知道我们打不开这个随意的文件,但是我知道这个是实际的,是应该能打开的,但是没有任何语言可以打开,这是有意义的。
如果我可以打开这个,实际上就可以打开更多的东西。但是在注册方面可能就会困难,这个可以找到一个根基,有这个路径可以打开。所以如果最开始的这个注册可以通过这个设施来打开A路径,这是有效的。这样的话,我可以把这个扩展,然后打开其他的路径。
实际上我们有上载和下载,可以建立这个Hive。在下载的过程中,实际上这个系统可以给你更新一个新的Hive。每个人都可以有权限进入这个Hive,可能是有限的一组人,但是实际上你有直接进入的权限。所以一个应用需要这么一个设施,这个Hive被暴露了,那么我们可以进行修改。
所以我就想回到这个记录文档,可能我们有一个选择是有价值的,是不是我要专门的打开这个Hive,可不可以其他人打开和我分享呢?当我把这个路径和大家展示的时候,会有一些在某个器件的水平到这个内核的水平,可能会有特别的一个器件,可以下载上传参数,可能有了这个只能读的一个器件。
我看到有一个可以打开这个注册的钥匙,这个实际上没有被完全的暴露,但是如果是本地的API的话,你可以打开,所以我要看不同的地方,看看怎么样使用。比如说如果你只是读,可能就不用进行交易。
如果有毁坏的话,你可以进行过渡,可以把这个注册的Hive来进行重启。这个可能是不需要了,如果你不能读这个Hive,实际上你不需要打开这个交易的解码。但是如果你要写怎么办呢?不会给你打开一个新的文件,如果你只是一个读的话。
我为什么要打开这个文件呢?要使我们做的事情更有意义,所以最开始的这些函数的链,这里有函数的核心,首先是要打开这个注册的Hive,然后是读,在这个位置读。如果失败了,如果你的路径被否认了,被拒绝了,那么你就可以知道现在的这个过程结果了。
所以我们要打开这个注册的Hive,作为一个用户或者是服务的客户,如果被拒绝了,你就可以进入这个本地的系统然后求助。如果这些服务是代表这个用户提供的,那么应该是以用户的ID身份来进行的。
我们打开一个本地的系统,如果只是打开一个只读的,你要想写的话还要再继续找。如果有这么一个文件,他们可能会忘记以前这个只读的路径。所以我们做这个服务的时候,只是打开这些只读的Hive,有的时候可能会到一些用户的Hive,所以我们可以扔掉一些象征性的。
我们怎么样更好的使用这些服务?怎么样使用这些服务生效?当我们建立一个矩阵的系统应用的话,会有.COM,如果你在开发.COM的时候确实是一个痛苦的经历。不管怎么说,一个矩阵的应用你是有一个目标的,我们使用这个系统的注册Hive,是在使用者的范围框架之内。
比如说我可以有一个矩阵的框架,我来破解这些密码,在我的文档之内来打开我的文件。如果我要进入的要求被拒绝了,比如说核心已经忘记了这只是只读的,那么实际上也有可能有机会进行写,也可以通过这个工具。
在注册Hive方面给大家一些展示,在这方面我们做这种可列举的,首先打开注册,然后作为这个根基的键,然后打开A,打开其他的键。我希望能够得到准入,这个就是我这么多随意得到的一些结果,非常明显,我们的这个Hive实际上是可以得到注册的。
我们可以进行修改这个Edge,这个是向大家展示我们的一些技巧。比如说上传到我们本地的Hive,然后进行运作,看起来很成功,也有失败的时候,我们可以看到我们建立了一个新的文件,这实际上是一个默认的控制,所有的应用有这个器件的准入。
如果我有F的这个文件,我们有ABC已经建立了。最后我要做的就是进入我的本地系统,这个就是我们注册Hive是本地的系统。我们可以获得不同的信息进行运作,然后进入本地的系统。
最后做一下总结,我想这个文件的记录实际上是一个非常好的方式来找漏洞。但是可以看到这个函数怎么样运作,有的时候可以在我们的研究或者调查过程当中使用。我们做的这个研究,比如说一些安全的语言,我们是不是可以使用这些,然后来认证这些注释的东西,是不是适合我。
如果这个开发者不这样做的话,那么就不会被人们注意这些事情。所以我可以这样做,还有可能有很多其他的一些文件的记录可以进行分析,比如说这么一个文件,怎么样能够更新,怎么样改变人们的行为,怎么样给大家一些理解,实际上它也是随着时间来变化的。
最后最大的一个结论那就是API的文件记录,它介绍了整个的情景,不能百分之百的来确保。另一方面,它可以给一些借口,可能有的时候会有一些错误的理解,所以不管你读什么,不要完全的相信。
以上就是我的分享,如果大家有什么问题的话,我会在这个会场欢迎大家来提问,希望大家能够在下午的讲座中有更多的收获。