严正声明:本文仅限于技术讨论与学术学习研究之用,严禁用于其他用途(特别是非法用途,比如非授权攻击之类),否则自行承担后果,一切与作者和平台无关,如有发现不妥之处,请及时联系作者和平台
翻译:ForrestX386
预估稿费:200RMB
投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿
0x00 为什么需要重现漏洞的利用环境
一般的漏洞披露公告很少包含技术细节去重现这个漏洞的利用。 这件事有好的一面,也有不好的一面,好的一面就是,这让很多脚本小子不能很快利用漏洞披露公告中的信息去编写漏洞利用代码, 会给使用含有漏洞的开源程序的企业争取修复的时间;不好的一面就是: 有时候安全工程师或者安全研究者需要漏洞的详细技术细节去重建漏洞利用环境,这样可以帮助他们更好地理解这个漏洞,然后就可以编写漏洞利用代码去更好地测试系统是否包含这个漏洞。
开源程序出现漏洞,经常是其中的一个开源库出现了问题,一个开源库出了问题很可能影响很多应用程序, 但是我们很难判断一个应用程序就含有漏洞,只因这个应用程序使用了这个含有漏洞的开源库,有时候应用程序并没有使用到含有漏洞的开源库中的问题代码,这个时候应用程序即使使用了问题开源库,也没有安全问题,有时候只有特定的配置条件下,这个含有漏洞的开源库才会触发漏洞。 只要不这样配置,就不会有安全问题。 正是因为我们无法从漏洞披露公告中获取漏洞的技术细节,所以我们不能很好地判断应用程序是否存在安全问题, 也不能单单认为使用了这个含有漏洞代码的开源库就会有安全问题。如果不知道漏洞细节,我们就无法准确评估系统的安全风险,出于成本和升级风险考虑,企业一般对升级含有漏洞的开源库持犹豫不决的态度我曾经遇到这样一家企业,他们的应用程序中包含了含有漏洞的开源库,但是它们不愿意升级系统,它是这样告诉它的用户的:
有人告诉我们,我们系统使用了这个含有漏洞的开源库,但是我们检查之后发现,我们并没有使用其中的漏洞代码,我们升级一次会花很大一笔钱,也会冒很大风险,我们现在的选择是不升级当我第一次听到这家企业的回答的时候,说实话,我非常惊讶,但仔细想想,这家企业说的也不无道理,我曾经经历过一次对Rails开发的大的项目的升级,那次经历真的是不堪回首,超级多的依赖,非常的麻烦。 企业升级一次的,有时候,成本还是蛮大的。 只有在有充足的证据证明系统确实存在重大安全问题,企业才会升级。最直接的证明系统存在安全漏洞的方式就是直接攻击,最好拿下系统shell权限,一般用于测试漏洞是否存在的代码称之为PoC(proof of concept)。要想写一个漏洞利用PoC,你就需要知道漏洞的详细技术细节除了能帮助我们更好的写出PoC,了解漏洞的技术细节还能帮助我们去培训研发工程师,这样就可以避免以后同样的错误再次发生。安全研究者也可以通多了解细节去寻找和这个漏洞相似的漏洞如果漏洞披露方不肯公开漏洞细节,我们应该怎么办呢,毛主席说的好,自己动手,丰衣足食,那就需要我们自己去重现这个漏洞环境,发现漏洞代码,下文就介绍如何通过收集公开的信息,重现一个漏洞环境
0x01. 如何通过公开的漏洞披露信息,完成开源程序漏洞环境的构建,分析漏洞原因,完成漏洞验证
完成漏洞环境主要有4个步骤
1、下载含有漏洞的版本
2、找到修复版本中的fix commit
3、理解这个fix
4、创建一个PoC
定位Fix信息
第1个步骤比较简单,很一般漏洞披露中就包含了影响的版本之类
第2个步骤比较麻烦, 有时候实现这一步很简单,因为有的漏洞披露公开中包含了 修复commit的hash值,但有时候,却很麻烦,你花了好几个小时,在几百个commit中 仅仅只发现 类似 “update
pom.xml” 之类的没有太多价值的commit信息,有时候,这是修复者故意这样做的,他隐藏了修复的fix信息,因为他们认为这样可以防止换人恶意利用,说的有道理,fix信息能够帮助攻击者更快的理解漏洞原因,以便他们完成漏洞利用代码的编写。但我个人认为,真正的攻击者在没有帮助提示的情况下也能够通过源码分析去发现fix信息,从而完成漏洞原因分析,漏洞代码编写,到最后的漏洞批量利用。 把漏洞的fix信息放在显而易见的地方,能够帮助更多的合法用户去利用漏洞成因,以便更好的保护自己降低危害。 如果代码维护者自己这个漏洞细节,这样他就可以屏蔽含有漏洞版本的下载,这样避免更多的人收伤害,当然还包括我上面提到的好处第1个寻找漏洞fix的地方就是漏洞披露公告,这就需要你仔仔细细的读漏洞公告, 留意漏洞披露公告中涉及的功能点,漏洞公告中的上下文信息也能够帮助你更好的定位漏洞fix commit,有时候漏洞披露公告中会涉及一些关键字,这些关键字能很好地帮助我们去定位fix commit如果说真有一个漏洞披露公告,里面包含的有用信息非常少,你必须亲自搜索fix 信息, 摆在首位需要搜索的就是fix version信息, 找到fix version 之后,你至少知道在这个fix version中至少有一个commit包含了fix 。但是不幸的是,你会发现有几百个commit信息,每一个commit信息中包包含了各种修改东东, 你很难分得清到这些修改代码是怎么回事。 所以你还需要继续过滤commit中的无用信息。
首先,你需要再次仔细阅读漏洞披露公告,看看能否在漏洞披露公告中找到以下信息:
1) 修复的是代码还是配置
2)修复信息中有木有提到指定的类名
3)有木有提到指定的功能模块
4)漏洞披露公告中有木有提到代码维护者的名字,也许是他提交了fix信息一般情况下,只有1-2两个修复者
5)fix的时间早于漏洞公告的时间, 公告之后的commit肯定不包含fix信息
6)如果fixed 版本是一个热补丁 版本(比如版本号是1.2.3 变成了一个1.2.3.1),一般的热补丁版本中只包含很少一些commit,这样查找起来就比较容易了
下一步, 你可以尝试用Google 搜索一下, 看你的运气了,也许其他人已经帮你完成了非常繁琐的的定位,可能已经在Blog中贴出了PoC,或者一个MSF的利用模块
如果一个开源项目有一个问题跟踪wiki,你可以试着去那里搜索,利用漏洞披露公告中的关键字进行搜索,或者搜索漏洞披露公告前几周的问题,可能搜索结果中会包含对漏洞的描述,如果wiki中关于问题的描述足够详细,你还可以对影响版本进行过滤另外一个可以搜索的地方就是 git logs。 我最喜欢的搜索方式:
git log ‐‐all ‐i ‐‐grep 'exploit keyword'
git log ‐‐since=12/1/2015 ‐‐before 1/28/2016 ‐i ‐‐grep 'keywords'
–all 选项是搜索所有的分支,有时候,fix信息只包含在某个特定的分支上,你不知道到底在哪一个分支上,所以你需要都搜索一下
-i 表示不区分大小写
另外一个比较好的定位fix信息的方式就是比较fix 版本和之前离这个版本最近的版本之间的区别。这个可以在github上的releases 上找到不同的版本
这里以Apache Storm Releases举个例子
首先找到fixed 版本之前的一个tag版本,比如上图中,V0.10.0-beta 是fixed版本之前的版本,v0.10.0-beta1这个版本包含了fix信息,在V0.10.0-beta这个版本的页面中有个连接显示从这个tag版本之后有1892个commits被提交到fixed的版本上。
我们可以点击这个连接比较V0.10.0-beta 和V0.10.0-beta1之间的不同
理解Fix
好了,现在你已经找到Fix的信息,现在你需要去理解Fix信息,弄明白修改了哪些,修改之后产生了哪些影响,为了弄明白这些,你需要搭建一个环境去测试,你需要去编译,运行和调试修改前后的代码,这里我就不多说了,提醒一下,结合fix Commit信息去理解。
编写PoC
理解了fix信息之后,你需要做的就是搭建一个含有漏洞的版本,尝试编写一个PoC去证明你的想法,编写PoC不是一蹴而就的事,你需要不断的调试修改一般编写PoC会选择python 或者Ruby作为代码语言,因为它们非常的容易上手。 有时候,你可能还需要利用到类似MSF这类框架。
编写PoC的时候,注意记录你遇到的奇葩问题以及是如何解决的,做好代码注释,不然的话,几天或者几周之后吗,你都看不懂你自己的代码了。