Zabbix SQL injection vulnerability analysis and solution-vulnerability warning-the black bar safety net

2016-08-22T00:00:00
ID MYHACK58:62201678247
Type myhack58
Reporter 长亭科技
Modified 2016-08-22T00:00:00

Description

Vulnerability scope

Where the use Zabbix2. 2. x, 3.0. x website in 3. 0. 4 version have repair may cause the sensitive data leakage, server by a malicious attacker to control and cause more harm.

Zabbix description

zabbix is a WEB-based interface to provide distributed system monitoring and network monitoring capabilities of enterprise-class open source solutions. Can monitor various network parameters, ensure that the server system of the security operations; and to provide flexible notification mechanism to allow system administrators to quickly locate/solve the existing issues.

The vulnerability principle

The vulnerability to the 8 on 1 2 October by a security researcher 1N3@CrowdShield and Brandon Perry responsibly disclosed to the Full Disclosure

Two people are in the mail discloses the PoC, as follows:

!

Although the two trigger points, but the injection process and the key points are to call the CProfile in the insertDB method of lead implantation, it can be classified as the same type of vulnerability, Brandon Perry also in the mail that

“I actually ended up finding this vuln in a different vector (in the profileIdx2 parameter)”

But there is a difference, latest.php the injection requires a high privilege account, and jsrpc.php you only need the guest account.

Due to the zabbix default open guest and the password is empty, so the use of difficulty is low, but not the other post said Do not need to log in.

The injection process

jsrpc. php:1 8 2→CScreenBuilder::getScreen()→CScreenBase::calculateTime()→CProfile::update()

→page_footer. php:4 0→CProfile::flush()→CProfile::insertDB()→DBexecute()

In the vulnerabilities file jsrpc. php:

$requestType = getRequest('type', PAGE_TYPE_JSON);

if ($requestType == PAGE_TYPE_JSON) {

$http_request = new CHttpRequest();

$json = new CJson();

$data = $json->decode($http_request->body(), true);

}

else {

$data = $_REQUEST;

}

$page['title'] = 'RPC';

$page['file'] = 'jsrpc.php';

$page['type'] = detect_page_type($requestType);

require_once dirname(FILE).'/ include/page_header.php';

if (! is_array($data) || ! isset($data['method'])

|| ($requestType == PAGE_TYPE_JSON && (! isset($data['params']) || ! is_array($data['params'])))) {

fatal_error('Wrong RPC call to JS RPC!');

}

$result = [];

switch ($data['method']) {

...

case 'screen. get':

$result = ";

$screenBase = CScreenBuilder::getScreen($data);

if ($screenBase !== null) {

$screen = $screenBase->get();

if ($data['mode'] == SCREEN_MODE_JS) {

$result = $screen;

}

else {

if (is_object($screen)) {

$result = $screen->toString();

}

}

}

break;

...

require_once dirname(FILE).'/ include/page_footer.php';

Through the class CScreenBuilder of the getScreen method of processing $data the incoming data. Continue to track CScreenBuilder categories:

/**

  • Init screen data.

*

  • @param array $options

  • @param boolean $options['isFlickerfree']

  • @param string $options['pageFile']

  • @param int $options['mode']

  • @param int $options['timestamp']

  • @param int $options['hostid']

  • @param int $options['period']

  • @param int $options['stime']

  • @param string $options['profileIdx']

  • @param int $options['profileIdx2']

  • @param boolean $options['updateProfile']

  • @param array $options['screen']

*/

public function __construct(array $options = []) {

$this->isFlickerfree = isset($options['isFlickerfree']) ? $options['isFlickerfree'] : true;

$this->mode = isset($options['mode']) ? $options['mode'] : SCREEN_MODE_SLIDESHOW;

$this->timestamp = ! empty($options['timestamp']) ? $options['timestamp'] : time();

$this->hostid = ! empty($options['hostid']) ? $options['hostid'] : null;

// get page file

if (! empty($options['pageFile'])) {

$this->pageFile = $options['pageFile'];

}

else {

global $page;

$this->pageFile = $page['file'];

}

// get the screen

if (! empty($options['screen'])) {

$this->screen = $options['screen'];

}

elseif (array_key_exists('screenid', $options) && $options['screenid'] > 0) {

$this->screen = API::Screen()->get([

'screenids' => $options['screenid'],

'output' = > API_OUTPUT_EXTEND,

'selectScreenItems' => API_OUTPUT_EXTEND,

[1] [2] next