如何渗透Discuz论坛(一)
作者:mOon
博客:www.moonsec.com
0x01:叙述:
这几篇文章主要的分享给那些经常渗透Discuz 或者对 Discuz论坛无从下手的初学者,可能帮助或者提高你对Discuz论坛的安全认知,从而找到突破的方法,这几篇都是作者真实渗透的案例,如有雷同纯属巧合,毕竟渗透手法基本相同嘛。
0x02:Discuz简介
Crossday Discuz! Board(以下简称 Discuz!,中国国家版权局著作权登记号 2006SR11895)是康盛创想(北京)科技有限公司(英文简称Comsenz)推出的一套通用的社区论坛软件系统,用户可以在不需要任何编程的基础上,通过简单的设置和安装,在互联网上搭建起具备完善功能、很强负载能力和可高度定制的论坛服务。Discuz! 的基础架构采用世界上最流行的 web 编程组合 PHP+MySQL实现,是一个经过完善设计,适用于各种服务器环境的高效论坛系统解决方案。
作为国内最大的社区软件及服务提供商,Comsenz旗下的 Discuz! 开发组具有丰富的 web 应用程序设计经验,尤其在论坛产品及相关领域,经过长期创新性开发,掌握了一整套从算法,数据结构到产品安全性方面的领先技术。使得 Discuz! 无论在稳定性,负载能力,安全保障等方面都居于国内外同类产品领先地位。
本暗月论坛也是Discuz论坛 使用多年了,安全性 感觉还行,最近的几个漏洞,都是要配合第三方 才能获取权限,所以关于Discuz论坛,一般情况下是很难渗透,除某些大牛手里有大杀器除外。不过这类大牛一般都看不起我们这些站 因为 没有必要下手。一不小心被我获取了,想想也有点小激动。
0x03 常见问题:
- Discuz怎么破解
- Discuz问题破解
- Discuz删帖
- Discuz权限绕过
- Discuz后台获webshell
以上这种这类问题,天天有人私聊,或者在群里提问。提问是对,但是这种问题不是一两句话,说得明白的。
0x04 案例一:
看上某站一个插件,但是在插件中心又看不见。怎么办,我们可以在谷歌搜索这类插件。
inurl:plugin.php?id=这里是插件名 例如我想要微信机机器人这个插件 wuxin_qqrobo
目标确认后,新手如何渗透这样的论坛。记得年前有个基佬写了一款工具名为《Dzscan》针对Discuz论坛安全检测的工具。
Dzscan项目设计的初衷,一方面是向wpscan,jmscan的等国外优秀作品的致敬,另一方面是更符合国情的量身定做。针对国内知名bbs建站系统discuz,所精心打造的一款漏洞扫描框架.
此处为discuz第三方漏洞收集和发布平台,当前的数十个漏洞都由Dzscan团队成员所发掘,为Dzscan能走更远而努力。
国内的大环境所决定,分享不易,漏洞分享更不易。未来,我们希望更多的小伙伴参与到对discuz的代码审计中去。作为国内极为优秀的一款开源cms,多读读其代码也是有益的。
为防止恶意利用,现今只公开低位和中危的漏洞,高危的开放与否留待后期再做决定。
装个python scan go
先对目标干一炮:
好像记得 utility 曾经有个漏洞,可以直接GETSHELL的。不急 我们先看下源码有没有加载exp模块的功能。
def fetch_sensitive(self): # X3 Deafult password 188281MWWxjk # https://www.bugscan.net/#!/n/449 robots_path = '%s/%s' % (self.url, '/source/plugin/tools/tools.php') req = requests.get(robots_path, headers=HEADERS) self.reqs += 1 if req.status_code == 200: print '[!] The Discuz! /'%s/' file exists./n' % robots_path # X3.1 Remote code execute # https://www.sebug.net/vuldb/ssvid-61217 robots_path = '%s/%s' % (self.url, '/utility/convert/index.php?a=config&source=d7.2_x2.0') req = requests.get(robots_path, headers=HEADERS) self.reqs += 1 if req.status_code == 200: print '[!] The Discuz! /'%s/' file exists./n' % robots_path # 7.2 faq.php SQL # https://www.bugscan.net/#!/n/118 robots_path = '%s/%s' % (self.url, '/faq.php') req = requests.get(robots_path, headers=HEADERS) self.reqs += 1 if req.status_code == 200: print '[!] The Discuz! /'%s/' file exists./n' % robots_path # 7.2 manyou SQL # http://www.venustech.com.cn/NewsInfo/124/6791.Html robots_path = '%s/%s' % (self.url, '/manyou/userapp.php') req = requests.get(robots_path, headers=HEADERS) self.reqs += 1 if req.status_code == 200: print '[!] The Discuz! /'%s/' file exists./n' % robots_path # 7.2 admincp.php XSS # https://www.bugscan.net/#!/n/141 robots_path = '%s/%s' % (self.url, '/manyou/admincp.php?my_suffix=%0A%0DTOBY57') req = requests.get(robots_path, headers=HEADERS) self.reqs += 1 if req.status_code == 200: print '[!] The Discuz! /'%s/' file exists./n' % robots_path # 6.x SQL # http://www.wooyun.org/bugs/wooyun-2014-080359 robots_path = '%s/%s' % (self.url, '/my.php') req = requests.get(robots_path, headers=HEADERS) self.reqs += 1 if req.status_code == 200: print '[!] The Discuz! /'%s/' file exists./n' % robots_path # deafult admin login page robots_path = '%s/%s' % (self.url, '/admin.php') req = requests.get(robots_path, headers=HEADERS, allow_redirects=False) self.reqs += 1 if req.status_code == 200 and 'Comsenz' in req.content: print '[!] The Discuz! /'%s/' file exists./n' % robots_path # deafult uc_server login page robots_path = '%s/%s' % (self.url, '/uc_server/admin.php') req = requests.get(robots_path, headers=HEADERS, allow_redirects=False) self.reqs += 1 if req.status_code == 200 and 'UCenter' in req.content: print '[!] The Discuz! /'%s/' file exists./n' % robots_path # develop.php robots_path = '%s/%s' % (self.url, '/develop.php') req = requests.get(robots_path, headers=HEADERS) self.reqs += 1 if req.status_code == 200: print '[!] The Discuz! /'%s/' file exists./n' % robots_path
<?php /** * DiscuzX Convert * * $Id: index.php 10469 2010-05-11 09:12:14Z monkey $ */ require './include/common.inc.php'; $action = getgpc('a'); $action = empty($action) ? getgpc('action') : $action; $source = getgpc('source') ? getgpc('source') : getgpc('s'); $step = getgpc('step'); $start = getgpc('start'); $setting = array(); if($source) { if(!$setting = loadsetting($source)) { showmessage('load_setting_error'); } } $action = empty($action) || empty($source) ? 'source' : $action; showheader($action, $setting); if($action == 'source') { require DISCUZ_ROOT.'./include/do_source.inc.php'; } elseif($action == 'config' || CONFIG_EMPTY) { require DISCUZ_ROOT.'./include/do_config.inc.php'; } elseif($action == 'setting') { require DISCUZ_ROOT.'./include/do_setting.inc.php'; } elseif($action == 'select') { require DISCUZ_ROOT.'./include/do_select.inc.php'; } elseif($action == 'convert') { require DISCUZ_ROOT.'./include/do_convert.inc.php'; } elseif($action == 'finish') { require DISCUZ_ROOT.'./include/do_finish.inc.php'; } else { showmessage('非法请求'); } showfooter(); ?>
?php /** * DiscuzX Convert * * $Id: do_config.inc.php 10469 2010-05-11 09:12:14Z monkey $ */ if(!defined('DISCUZ_ROOT')) { exit('Access error'); } $configfile = DISCUZ_ROOT.'./data/config.inc.php'; $configfile_default = DISCUZ_ROOT.'./data/config.default.php'; @touch($configfile);//创建文件 if(!is_writable($configfile)) {//文件是否可写 showmessage('config_write_error'); } $config_default = loadconfig('config.default.php');//载入默认配置文件 $error = array(); if(submitcheck()) {//检测是否提交 $newconfig = getgpc('newconfig'); if(is_array($newconfig)) {//是否为数组 $checkarray = $setting['config']['ucenter'] ? array('source', 'target', 'ucenter') : array('source', 'target'); foreach ($checkarray as $key) { if(!empty($newconfig[$key]['dbhost'])) { $check = mysql_connect_test($newconfig[$key], $key); if($check < 0) { $error[$key] = lang('mysql_connect_error_'.abs($check)); } } else { $error[$key] = lang('mysql_config_error'); } } save_config_file($configfile, $newconfig, $config_default); if(empty($error)) { $db_target = new db_mysql($newconfig['target']); $db_target->connect(); delete_process('all'); showmessage('config_success', 'index.php?a=select&source='.$source); } } } showtips('如果无法显示设置项目,请删除文件 data/config.inc.php'); $config = loadconfig('config.inc.php'); if(empty($config)) { $config = $config_default; } show_form_header(); show_config_input('source', $config['source'], $error['source']); show_config_input('target', $config['target'], $error['target']); if($setting['config']['ucenter']) { show_config_input('ucenter', $config['ucenter'], $error['ucenter']); } show_form_footer('submit', 'config_save'); ?>
function lang($name, $vars = array()) { static $language; if($language === null) { @include DISCUZ_ROOT.'./language/lang.php'; if(empty($language)) { $language = array(); } } $ret = isset($language[$name]) ? $language[$name] : $name; if(!empty($vars)) { foreach ($vars as $key => $value) { $ret = str_replace('{'.$key.'}', $value); } } return $ret; } function show_hidden_field($name, $value) { echo '<input type="hidden" name="'.$name.'" value="'.$value.'">'."/n"; } function show_form_header($method = 'post') { echo <<<EOT <form method="$method" action="index.php"> <input type="hidden" name="a" value="$GLOBALS[action]"> <input type="hidden" name="source" value="$GLOBALS[source]"> <input type="hidden" name="submit" value="yes"> EOT; } function show_form_footer($submitname = '', $submitvalue = 'submit') { if($submitname != '') { $submitvalue = lang($submitvalue); echo <<<EOT <table class="button"> <tr><td><input type="submit" value="$submitvalue" name="$submitname"></td></tr> </table> EOT; } echo '</form>'; } function show_config_input($type, $config, $error = array()) { $title = lang('config_type_'.$type); show_table_header(); show_table_row(array(array('colspan="3"', $title)), 'header title'); if($type == 'target') { show_table_row(array(array('colspan="3"', '<font color="red">'.lang('config_type_target_comment').'</font>')), 'bg2'); } foreach ($config as $key => $value) { $addmsg = $error && $key == 'dbhost' ? lang($error) : ''; $tip = $key == 'pconnect' ? lang('tips_pconnect') : ''; show_table_row( array( array('width="150"', lang('config_'.$key)), array('class="bg2"', '<input type="text" size="40" name="newconfig['.$type.']['.$key.']" value="'.htmlspecialchars($value).'">'), array('class="bg2"', '<font color="red">'.$tip.'</font><font color="red">'.$addmsg.'</font>') ), 'bg1' ); } show_table_footer(); echo '<br>'; } function getvars($data, $type = 'VAR') { $evaluate = ''; foreach($data as $key => $val) { if(!preg_match("/^[a-zA-Z_/x7f-/xff][a-zA-Z0-9_/x7f-/xff]*$/", $key)) { continue; } if(is_array($val)) { $evaluate .= buildarray($val, 0, "/${$key}")."/r/n"; } else { $val = addcslashes($val, '/'//'); $evaluate .= $type == 'VAR' ? "/$key = '$val';/n" : "define('".strtoupper($key)."', '$val');/n"; } } return $evaluate; } function buildarray($array, $level = 0, $pre = '$_config') { static $ks; if($level == 0) { $ks = array(); $return = ''; } foreach ($array as $key => $val) { if($level == 0) { $newline = str_pad(' CONFIG '.strtoupper($key).' ', 50, '-', STR_PAD_BOTH); $return .= "/r/n// $newline ///r/n"; } $ks[$level] = $ks[$level - 1]."['$key']"; if(is_array($val)) { $ks[$level] = $ks[$level - 1]."['$key']"; $return .= buildarray($val, $level + 1, $pre); } else { $val = !is_array($val) && (!preg_match("/^/-?[1-9]/d*$/", $val) || strlen($val) > 12) ? '/''.addcslashes($val, '/'//').'/'' : $val; $return .= $pre.$ks[$level - 1]."['$key']"." = $val;/r/n"; } } return $return; } function save_config_file($filename, $config, $default) { $config = setdefault($config, $default); $date = gmdate("Y-m-d H:i:s", time() + 3600 * 8); $year = date('Y'); $content = <<<EOT <?php /$_config = array(); EOT; $content .= getvars(array('_config' => $config)); $content .= "/r/n// ".str_pad(' THE END ', 50, '-', STR_PAD_BOTH)." ///r/n/r/n?>"; file_put_contents($filename, $content); } function setdefault($var, $default) { foreach ($default as $k => $v) { if(!isset($var[$k])) { $var[$k] = $default[$k]; } elseif(is_array($v)) { $var[$k] = setdefault($var[$k], $default[$k]); } } return $var; }
0x06:扩展:
最近暗月有时间会写下关于Discuz渗透方面的文章,这是开头篇,欢迎长期关注暗月论坛微信号 (moonsec)和本论坛。
dzscan team:http://dzscan.org/
moon_Discuz_utility 下载:moon_Discuz_utility.zip
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论