逆向一款恶意Eclipse插件的经历
Posted 疯猫网络
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆向一款恶意Eclipse插件的经历相关的知识,希望对你有一定的参考价值。
引言
首先,我想要说明的是,我不是一个安全研究员、白帽子或者逆向工程方面的专家。我目前正在从事Java开发,但一直对信息安全感兴趣。
最近我对信息安全的诸多领域进行了研究,包括二进制、逆向工程到破解WPA。因此,我决定搭建一个信息安全学习博客,用于记录学到的知识。即便没有人读我的博客(译者:事实上还有个小可爱翻译成了中文),至少我能够记录下自己的收获,而且我发现把知识和经历写下来能够让我对知识有更深刻的认识。
寻找目标
今天我有相当多的空闲时间,所以我决定用逆向工程来试手。我具有多年的Java编程经验,而Java反编译器通常可以为我提供确切的源代码,因此对我来说逆向Java项目是个不错的选择。
当我正在考虑逆向哪个项目的时候,我想到之前看到的一条Eclipse插件的评价。在看到这条评价后,我决定停止使用这款插件。
Eclipse Class Decompiler插件页面
这相当值得怀疑,我并不认为这款Eclipse插件需要具备这个功能。
请注意,这个插件上榜了Java Eclipse Plugin Top 20,并有将近400k的下载量。
调查
我首先需要得到这个插件的副本,然后反编译它,或找到项目的源代码。
我第一个检查的地方是项目网站,它引导我前往项目的Github页面。我看过Github上的代码,但并没有找到所说的“phone home”的功能。也许我错过了一些东西,但是我怀疑开发者隐藏了相关的代码。所以我决定安装这个插件,然后反编译它的二进制文件。
这个插件可能会对我的电脑产生危害,所以我在VirtualBox上安装了Windows虚拟机,并在虚拟机内部安装了Java和Eclipse。
接着我安装了该插件,通过研究了Eclipse插件二进制文件的存放位置,最后在<user_home>/.p2/pool/plugins文件夹找到了它们。
我把这些jar包从虚拟机复制到我主机的Eclipse里,使用了一个(我认为是)值得信赖的反编译器——jd,来分析这些类。打开主要的类文件以后,我马上发现了一些有趣的代码,这些代码用来存储在一个名为adclick.count的变量。
值得注意的是,该代码并没有出现在插件的Github版本中。
我很快发现这个二进制文件包含了相当多的类,与其一个个检查它们(可能需要几个小时),根据Eclipse Marketplace上的评论,该插件产生了一些HTTP连接,所以我决定反编译所有调用java.net.*包的源代码。
现在我缩小了需要检查的代码的范围,这样就能更深入地看看这些代码。
检查这些类时,我在IOUtils中发现了一些可疑的代码,它似乎提供了一个关闭HTTP连接的Helper Method(为什么代码反编译器需要关闭HTTP连接?)。
接下来,我在UIUtil类中发现一个方法用来在外部浏览器中打开URL,并增加adclick.count变量。
在UserUtil类中,我发现有一点值得关注——collectUserIp()方法中调用了多个(看似不相关)的各种网站。
我跟踪了这个方法,看看这些代码对用户信息做了什么…然后发现它被用在BackgroundHandler类中。
检查这个类后,我发现该代码收集了用户系统的大量信息,将其转换为JSON对象,然后将其发送到http://decompiler.cpupk.com/statistics.php”。
现在,我想看看插件收集并发送了哪些的信息到他的服务器上。我在主机上安装了Burp Suite,开启HTTP代理,这会让虚拟机中的流量通过这个代理转发。
然后在虚拟机中设置系统代理。
我再次启动Eclipse,并检查通过代理发送的请求和响应。首先产生了一些来自Eclipse的调用,但是我很快收到了来自thecollectUserIp()方法的调用。pv.sohu.com/cityjson返回的是一个javascript变量,其中包含了调用者的IP、所在大陆的id和名称
接下来我观察了对ip.taobao.com/service/ipinfo.php的调用,它则返回了更多关于用户IP的地理信息。
最后我观察到了Eclipse Marketplace上的评论所描述的“call home”功能。它将用这些信息生成JSON对象并将其发送到decompiler.cpupk.com/statistics.php。
把注意力转回analyzeUserInfo()类,调用上传用户信息的这个方法实际上必须有一个重要的服务器响应,而这个响应是通过其他更多的方法来处理的。
这时候我找到了checkAdConfig()方法。checkAdConfig()方法解析了JSON对象的诸多属性,比如adConfig,adCondition,adStyles等等。
根据BurpSuite显示的服务器响应,当前并没有提供其所需的所有变量。
因此我决定在代码中搜索之前注意到的adclick.count变量。这一次我发现了一个新的类——htmlLinkTrimItem。
这个类实现了一些值得琢磨的功能。首先,它实现了一个内部浏览器。其次,它在初始化时调用一个updateTrimUrl()方法,该方法在单独的线程中使用了隐藏的浏览器,并调用了由trayLinkUrl定义的URL。
我在代码中搜索了对HtmlLinkTrimItem类的引用,发现作者在多处引用了HtmlLinkTrimItem类。
LinkTrimChecker类使用了TrayLinkV1类和TrayLinkV2类,用于实例化HtmlLinkTrimItem(由此反过来触发后台浏览器)。
TrayLinkUtil.displayTrayLink()方法又调用了LinkTrimChecker.displayTrayLink()方法,然后被使用在BackgroundHandler.checkTrayLink()方法中。
如果你前面有仔细阅读,那么你可能已经注意到checkTrayLink方法正是处理服务器返回的JSON对象的方法之一。当响应中有trayLink时,TrayLinkUtil.displayTrayLink就会被调用。
BurpSuite上的记录表明这个对象存在,但它是空白的。
所以如果trayLink不是空白的话会发生什么?
如前面讨论的那样,程序将调用displayTrayLink()方法,它将委派给LinkTrimChecker处理。
但是你可能会注意到displayTrayLink()方法的第二个参数TrayLinkUtil.enableShowTrayLink(),很显然只有在解析为true时,才能启用后台浏览器。enableShowTrayLink()方法会检查首选项中包含了trayLinkStrategy,然后UserUtil类中的matchAdCondition方法才会返回true。
根据我之前的研究,trayLinkStrategy是在从服务器返回的JSON对象中解析trayLink时设置的。
接下来我又看了一下matchAdCondition()方法。该方法检查首选项中是否包含adCondition(或默认为100),并将用户反编译类的总数与此值进行比较,如果用户反编译类的总数超过此数字,则返回true。
因此,在用户对超过100个类进行了反编译后,或者服务器返回的adCondition字段更改为小于用户反编译类计数的值时,则后台浏览器将开始发出请求。
接下来我要看看trayLinkUrl是如何被设置的,这是后台浏览器所要打开的URL。我在TrayLinkUtil类中发现了用于设置trayLinkUrl的代码。首先根据服务器返回值设置trayLinkStrategy属性,然后第二种方法检查属性,如果它包含一个具有url字段的JSON对象,则返回此URL。否则,它则为包含这些对象及其权重的数组,程序将根据权重随机选择URL。
我同时注意到后台浏览器是在一个定时器上打开的,这个定时器再次由TrayLinkUtil类中的getTrayUrlDisplayTime方法定义。该方法表明trayLinkStrategy还包含了showTime属性以及前面发现的URL。
我决定结合发现到的所有内容,使用BurpSuite修改服务器响应来触发广告软件功能。我修改了服务器返回的trayLink,使其包含URL到google.com,并将showTime改为1分钟。我还将adCondition属性改为2,毫无疑问,我现在反编译类的数目已经超出了这个限制。
我使用jvisualvm来Hook Eclipse,并查看HeapDump,以确认我已经修改了相关属性。我在HeapDump上运行了以下查询语句(OQL)。
select s from java.lang.String s where s.toString().equals(“trayLinkStrategy”)
结果显示有两条记录,第一条为Eclipse InstanceProperties进行的引用,由此我观察到了之前进行的修改。
值得注意的是,键值表的第3和第8项分别包含trayLinkStrategy和adCondition。现在设置添加的JSON对象,并将adCondition的值改为2。
大约一分钟之后,我注意到BurpSuite有了动静,如图所示,虚拟机已经向google:80发送了一个请求。成功了!
为了确保这不是一个意外(因为可能很多不同的应用程序/代码向Google发送请求),我重复测试了imgur.com 。
结果是一样的,虚拟机向imgur.com:80发出请求。
此时虚拟机弹出了IE证书的问题。这可能是由于imgur通过TLS请求资源,但BurpSuite的证书不符合这些资源的DN(身份识别信息?)。
当离开Eclipse窗口,可以在BurpSuite看到imgur的调用流。
结论
很高兴我对该插件进行的研究产生了一定的成果,我揭露了一个上榜Java Eclipse Plugin Top 20的插件内存在的恶意代码,以及分析了Eclipse Marketplace评论所说的“call home”方法。我认为这个功能的代码没有出现在Github版本的代码中就足以证明它可能不怀好意。
我想要补充的是,尽管这个功能存在,但我并没有观察到服务器提供了所需的JSON对象来触发广告。
我将就该问题联系Eclipse官方,他们不会容忍这种功能。
如果有任何问题,请随时发表评论。
Append:基于进一步的研究,这些恶意代码可能被用于下载文件到用户系统上(仍然要更深入的测试)。因为通信是完全未加密的,所以可能会产生非常恶劣的影响。
Append 2:我对上述猜想进行了测试。
我伪造了一个只包含一个带消息的JFrame的jar文件,并用python开放在80端口
sudo python3 -m http.server 80
我虽然不认为会有人打开或保存这个特定的文件,但可能存在另一个漏洞,在不必点击任何东西的情况下就会对操作系统产生危害,或运用社会工程学,例如,如果弹出窗口设置为EclipseUpdate.exe,那么可能就会有一些人上当了?
由于“call home”基于HTTP,因此也可以通过修改MITM来攻击受害者。
Append 3:Eclipse已经从市场上移除了该插件,并发布了相关通告,建议用户卸载该插件。
以上是关于逆向一款恶意Eclipse插件的经历的主要内容,如果未能解决你的问题,请参考以下文章
Jacoco和Tycho surefire的Eclipse RCP插件代码介绍