统计
  • 建站日期:2021-03-15
  • 文章总数:62 篇
  • 评论总数:43 条
  • 分类总数:14 个
  • 最后更新:6天前

一篇“不一样”的真实渗透测试案例分析文章

本文阅读 14 分钟
广告

0x00 前言

本文是由一次真实的授权渗透案例引申而出的技术分析和总结文章。在文章中我们会首先简单介绍这次案例的整体渗透流程并进行部分演绎,但不会进行详细的截图和描述,一是怕“有心人”发现端倪去目标复现漏洞和破坏,二是作为一线攻击人员,大家都明白渗透过程也是一个试错过程,针对某一个点我们可能尝试了无数种方法,最后写入文章的只有成功的一种,而这种方法很有可能也是众所周知的方法。因此我们只会简单介绍渗透流程,然后提取整个渗透过程中比较精华的点,以点及面来进行技术分析和探讨,望不同的人有不同的收获。

0x01 渗透流程简述

在接到项目以后,由“前端”小组(初步技术分析小组)进行项目分析和信息收集以及整理,整理出了一批域名和一些关键站点,其中有一个phpmyadmin 和 discuz的组合建站,且均暴露在外网,这也是很常见的一种情况。由于网站某个web端口的解析配置问题导致了php不被解析而形成任意文件下载漏洞,通过这个漏洞我们拿到了mysql的root账户密码。由于linux服务器权限设置比较严格的问题没法直接使用phpmyadmin登录mysql而提权拿到discuz的webshell。经过多种尝试我们利用phpmyadmin替换管理员hash而登录discuz后台,在discuz后台利用修改ucenter配置文件的漏洞写入了webshell。

在进入内网以后,通过简单的80、443探测内网的web时候发现了一个含有java webdav的服务(域内windows,后文中以A服务器称呼),利用java webdav的xxe去执行NTLM Relay。同时收集discuz数据库中用户名利用kerberos AS_REQ和密码喷射(一个密码和不同用户名的组合去KDC枚举)幸运的获得了一组域内用户的账户和密码,利用这个用户增加了一个机器账户。结合NTLM Relay和这个机器账户利用基于资源的约束委派,成功的使这个机器账户具有了控制A服务器的权限。登录A服务器绕过卡巴斯基抓取到了域管理密码,这次攻坚任务也因此而结束。图示如下:

在这次渗透流程中我们认为Discuz x3系列和xxe到域控这两个点是值得拿出来分析和探讨的。

0x02 Discuz X3系列

本节分为3部分,首先将对Discuz X3以后的版本出现的主要漏洞做一个简单总结,然后针对discuz的几种密钥做一些分析,最后发布一个discuz最新的后台getshell。

Discuz X3以后漏洞总结

目前市面上基本都是x3以上的Discuz程序了,x3以下的网站占比已经非常低了,因此在此只总结x3以上的漏洞。总结并不是对每个漏洞进行重新分析,这是没有必要的,网上已经有很多优秀的分析文章了。那我们为什么还要总结呢?如果你是在一线做渗透测试或者红队评估的同学,应该会经常遇到discuz,往往大部分同学一看程序版本再搜搜漏洞或者群里问问就放弃了。在大家的印象中discuz是一块硬骨头,没必要耗太多时间在它身上,但事实上discuz并不是你所想象的那么安全。本小节将通过总结discuz的各种小漏洞,再结合我们自己的几次对discuz目标的突破,提出一些利用思路和利用可能。

类型适用版本适用条件利用分析分析文章
SSRF<= x3.4 修复补丁1.windows<br/>2.php>5.3+php-curl<=7.54<br/>3.DZ开放在80端口SSRF的利用主要是攻击其他服务,大部分情况都需要利用到gopher协议<br/>在DZ中需要利用缓存(redis,memcache)getshell,当然gopher模拟的tcp协议,如果服务器或内网中存在其他的可利用服务也是可以精心构造数据表利用的。1.Discuz x3.4前台SSRF分析<br/>2.DiscuzX 两处 SSRF 挖掘及利用<br/>3.Discuz!因Memcached未授权访问导致的RCE
任意文件删除<= x3.4<br/>修复补丁前台用户权限Discuz 在安装成功后,登陆后台就会删除安装文件,所以重装利用是不能实现的。<br/>现实中的主要利用集中于删除index.htm文件,再利用目录遍历去获取备份文件,通过备份文件中的各种敏感信息(各种KEY,hash),然后再进一步利用。Discuz!X ≤3.4 任意文件删除漏洞分析
短文件名 漏洞未修复windows看似是比较鸡肋的小技巧,但在猜一些随机命令的文件名时非常有用,比如:利用短文件名我们可以下载数据库备份文件(文件名中含有随机字符),利用备份文件我们可以尝试解密用户密码。https://gitee.com/ComsenzDiscuz/DiscuzX/issues/I10NG9
authkey 预测<x 3.4问题的本质在于mt_rand() 在同一个进程中共享随机数种子。利用猜解的authkey我们可以破解discuz主题功能的加密校验过程Discuz_X authkey安全性漏洞分析
后台sql注入<=3.4<br/>修复补丁后台权限discuz后台已经具备数据库备份功能,所以select 注入作用将减小很多,该漏洞的最大意义在于mysql较低版本的写文件getshell(这里向discuz备份目录写也不行,因为discuz的mkdir设置的0777,但是受到umask的影响,实际写入的是0755,所以写文件也比较困难),但由于x3后台没有了直接执行sql的功能,如果有一个注入,我们可以夸库查询,搞定同mysql的其他网站。Discuz! X系列全版本后台Sql注入漏洞
后台注入漏洞<=3.4<br/>修复补丁后台权限由于是update型注入,我们在后台已经可以利用数据库备份获得数据,对本网站意义不大,但是有同mysql的其他网站,如果权限不严,夸库查询,搞定同mysql的其他网站。SQL注入
后台设置mysql任意文件读取<=3.4<br/>修复补丁后台权限通过文件读取后,我们可以结合uc_key、authkey等key的利用。Mysql任意文件读取攻击链拓展
后台命令执行1.5-2.5<br/>修复补丁后台权限这个漏洞是命令注入漏洞,但是由于开发者的失误,导致3.x不可用。漏洞本身也是在x3.4才被修复CVE-2018-14729
Memcached未授权访问导致的RCE<=3.4memcached 权限需要memcached的修改权限,这个权限可以来自于ssrf,也可以来自于未授权Discuz!因Memcached未授权访问导致的RCE
Discuz! X3.1后台任意代码执行<=x3.1后台权限x3.1中间版本的getshell方法,用作参考Discuz! X3.1后台任意代码执行
后台uc_center代码执行< 3.4<br/>修复补丁后台权限利用分析请看下面的文章内容本文分析

总结:

  • 针对于discuz的ssrf漏洞,在补丁 中限制了对内网ip的访问,导致了很难被利用。
  • 在后台getshell中,建议使用uc_center rce比较方便,并且通杀包括最新版本,后文有分析。
  • UC_KEY 直接getshell已在x3以上的最新版本被修复,但在一些老的3.2以前的版本可能被利用。

以上这些漏洞应该并不全面,且看似都比较鸡肋,但往往千里之堤毁于蚁穴,几个不起眼的小漏洞组合一下会发现威力巨大。仔细的读者应该发现以上漏洞大部分能够造成的最大危害是信息泄露,信息泄露有什么用呢?下面我们将接着分析Discuz的几种密钥,看到这儿你应该已经明白了,通过信息泄露,获得相关密钥,突破discuz的加密体系,进而获取更高的权限。

Discuz的几种密钥分析

通过分析,在discuz中,主要有下面的几种密钥, 这些密钥共同构成了discuz的加密解密体系,这里的命名有重复,我已经标记了对应key值以及key所在的位置。如下表所示:

主要探讨的其实就只有 authkey,UC_KEY(dz),UC_KEY(uc_server),UC_MYKEY,authkey(uc_server) 5种,我们首先来看着几个密钥是怎么来的最后又到了哪儿去。

密钥的产生

authkey,UC_KEY(dz),UC_KEY(uc_server),UC_MYKEY 都是在安装的时候产生。authkey(uc_server)的产生是和UC_MYKEY息息相关的,在后文中详细讲述。生成代码如下所示:

//https://gitee.com/ComsenzDiscuz/DiscuzX/blob/v3.4-20191201/upload/install/index.php
<?php
...
                $uid = DZUCFULL ? 1 : $adminuser['uid'];
                $authkey = md5($_SERVER['SERVER_ADDR'].$_SERVER['HTTP_USER_AGENT'].$dbhost.$dbuser.$dbpw.$dbname.$username.$password.$pconnect.substr($timestamp, 0, 8)).random(18);
                $_config['db'][1]['dbhost'] = $dbhost;
                $_config['db'][1]['dbname'] = $dbname;
                $_config['db'][1]['dbpw'] = $dbpw;
                $_config['db'][1]['dbuser'] = $dbuser;
                $_config['db'][1]['tablepre'] = $tablepre;
                $_config['admincp']['founder'] = (string)$uid;
                $_config['security']['authkey'] = $authkey;
                $_config['cookie']['cookiepre'] = random(4).'_';
                $_config['memory']['prefix'] = random(6).'_';

                save_config_file(ROOT_PATH.CONFIG, $_config, $default_config);

                $db = new dbstuff;

                $db->connect($dbhost, $dbuser, $dbpw, $dbname, DBCHARSET);

                if(!VIEW_OFF) {
                        show_header();
                        show_install();
                }

                if(DZUCFULL) {
                        install_uc_server();
                }
...

                $db->query("REPLACE INTO {$tablepre}common_setting (skey, svalue) VALUES ('authkey', '$authkey')");
...
?>

我们看见key的产生都依赖于discuz 自定义的random函数,出现过的authkey爆破问题也因此产生。在安装时由于处于同一个cgi进程,导致mt_rand() 只播种了一次种子,所以产生了随机数种子爆破和推测key的问题,在3.4版本中,authkey的产生已经是拼接了完整的32位字符串,导致了无法进行爆破推算出authkey的前半部,因此这个问题已经被修复,但这个漏洞原理值得学习。代码最后可以看出authkey产生后还放入了数据库中,最终authkey存在于数据库pre_common_setting表和/config/config_global.php配置文件。 代码中的 instal_uc_server()函数实现了UC_KEY(dz),UC_KEY(uc_server)的产生,使用了同一个生成函数_generate_key(),代码如下:

function _generate_key() {
 $random = random(32);
 $info = md5($_SERVER['SERVER_SOFTWARE'].$_SERVER['SERVER_NAME'].$_SERVER['SERVER_ADDR'].$_SERVER['SERVER_PORT'].$_SERVER['HTTP_USER_AGENT'].time());
 $return = array();
 for($i=0; $i<32; $i++) {
  $return[$i] = $random[$i].$info[$i];
 }
 return implode('', $return);
}

产生的算法牵扯到安装环境和安装过程的http header信息,导致爆破基本失效,从而无法预测,最后UC_KEY(dz)保存到了/config/config_ucenter.php中,UC_KEY(uc_server)保存到了/uc_server/data/config.inc.php中。

Discuz Key的相关思考

我们通过查看源码,去分析每个key影响的功能,通过这些功能点,我们可以去获得更多的信息。信息的整合和利用往往是我们渗透的关键。下面我们将做一些抛砖引玉的思考并举一些例子,但不会面面俱到一一分析,这样也没有意义,具体的代码还是需要读者自己亲自去读才能印象深刻。

1. authkey
authkey的使用在discuz主程序中占比很重,主要用户数据的加密存储和解密使用,比如alipay相关支付数据的存储和使用、FTP密码的存储等等;还用于一些功能的校验,比如验证码的校验、上传hash的校验等等;用户权限的校验也用到了authkey,比如source/class/discuz/discuz_application.php 中_init_user() 利用authkey解码了cookie中的auth字段,并利用解开的uid和pw进行权限校验,但是光知道authkey并不能完成权限校验,我们还需要知道用户的”密码hash“(数据库pre_common_member表中的password字段,此处存储的只是一个随机值的md5,真正的用户密码hash在pre_ucenter_members中),当我们通过其他方法可以读取数据库数据时,我们就可以伪造登陆信息进行登陆,再比如source/include/misc/misc_emailcheck.php中authkey的参与了校验hash的生成,当我们知道了authkey后,通过伪造hash,我们可以修改用户的注册邮箱,然后利用密码找回来登陆前台用户(管理员不能使用密码找回功能)。

本文来自投稿,不代表本站立场,如若转载,请注明出处:https://www.cnhacker.cc/web_security/290.html
-- 展开阅读全文 --
红蓝对抗 | 利用MySQL蜜罐获取攻击者微信ID及手机号
« 上一篇 04-19
在腾讯云服务器中使用pipework让Docker容器直接获得公网IP
下一篇 » 05-04
广告

发表评论

V注册会员 L评论等级
R2 条回复
  1. Google+VLv.1 说道:
    2021-06-24     Win 10 /    FireFox

    额,站长是不是没写完阿

    1. RAVENVLv.2 说道:
      2021-06-24     Win 10 /    Chrome

      @Google+

      竟然被你猜到了…

没有更多评论了

作者信息

广告

动态快讯

热门文章

广告

标签TAG

热评文章