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

在这里插入图片描述

前言

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

渗透流程简述

在接到项目以后,由“前端”小组(初步技术分析小组)进行项目分析和信息收集以及整理,整理出了一批域名和一些关键站点,其中有一个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到域控这两个点是值得拿出来分析和探讨的。白嫖的福音网安学习资料》》

Discuz X3系列

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

以后漏洞总结

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

类型 适用版本 适用条件 利用分析 分析文章
SSRF <= x3.4 修复补丁 1.windows
2.php>5.3+php-curl<=7.54
3.DZ开放在80端口
SSRF的利用主要是攻击其他服务,大部分情况都需要利用到gopher协议
在DZ中需要利用缓存(redis,memcache)getshell,当然gopher模拟的tcp协议,如果服务器或内网中存在其他的可利用服务也是可以精心构造数据表利用的。
1.Discuz x3.4前台SSRF分析
2.DiscuzX 两处 SSRF 挖掘及利用
3.Discuz!因Memcached未授权访问导致的RCE
任意文件删除 <= x3.4
修复补丁
前台用户权限 Discuz 在安装成功后,登陆后台就会删除安装文件,所以重装利用是不能实现的。
现实中的主要利用集中于删除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
修复补丁
后台权限 discuz后台已经具备数据库备份功能,所以select 注入作用将减小很多,该漏洞的最大意义在于mysql较低版本的写文件getshell(这里向discuz备份目录写也不行,因为discuz的mkdir设置的0777,但是受到umask的影响,实际写入的是0755,所以写文件也比较困难),但由于x3后台没有了直接执行sql的功能,如果有一个注入,我们可以夸库查询,搞定同mysql的其他网站。 Discuz! X系列全版本后台Sql注入漏洞
后台注入漏洞 <=3.4
修复补丁
后台权限 由于是update型注入,我们在后台已经可以利用数据库备份获得数据,对本网站意义不大,但是有同mysql的其他网站,如果权限不严,夸库查询,搞定同mysql的其他网站。 SQL注入
后台设置mysql任意文件读取 <=3.4
修复补丁
后台权限 通过文件读取后,我们可以结合uc_key、authkey等key的利用。 Mysql任意文件读取攻击链拓展
后台命令执行 1.5-2.5
修复补丁
后台权限 这个漏洞是命令注入漏洞,但是由于开发者的失误,导致3.x不可用。漏洞本身也是在x3.4才被修复 CVE-2018-14729
Memcached未授权访问导致的RCE <=3.4 memcached 权限 需要memcached的修改权限,这个权限可以来自于ssrf,也可以来自于未授权 Discuz!因Memcached未授权访问导致的RCE
Discuz! X3.1后台任意代码执行 <=x3.1 后台权限 x3.1中间版本的getshell方法,用作参考 Discuz! X3.1后台任意代码执行
后台uc_center代码执行 < 3.4
修复补丁
后台权限 利用分析请看下面的文章内容 本文分析

总结:

针对于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,我们可以修改用户的注册邮箱,然后利用密码找回来登陆前台用户(管理员不能使用密码找回功能)。

2. UC_KEY(dz)
UC_KEY(dz)也是经常提到的UC_KEY GetWebShell的主角。它主要在2个地方被使用:一个是数据库备份api/db/dbbak.php;一个是针对用户以及登录和缓存文件相关的操作,主要函数位于api/uc.php中的uc_note类。

关于UC_KEY(dz)的利用,网上基本都是通过uc.php来GetWebShell,但这个漏洞在新版本已经被修复了。UC_KEY(dz)的利用并不局限与此,你去阅读dbbak.php代码就会发现,有了UC_KEY(dz)我们可以直接备份数据库,下载数据库,从数据库中找到相关信息进行进一步渗透。

另外一个地方就是uc_note类,比如里面的synlogin()函数可以伪造登陆任意前台用户。当然还有其他的函数,在这里就不一一分析。

3. UC_KEY(uc_server)
UC_KEY(uc_server)往往是被大家忽视的一个key,它其实比UC_KEY(dz)的使用更多。首先他同样可以备份数据库,对discuz代码比较熟悉的同学应该知道dbbak.php这个文件有2个,一个是上面提到的api/db/dbbak.php;另外一个是uc_server/api/dbbak.php,他们的代码可以说几乎相同。唯一的区别是api/db/dbbak.php中多了2个常量的定义,基本没有太大影响。这个2个文件都能被UC_KEY(dz)和UC_KEY(uc_server)操控。

UC_KEY(uc_server)几乎管控了Ucenter的所有和权限认证相关的功能。例如权限验证函数 sid_decode() ,在该函数中UC_KEY(uc_server)和用户可控的http header共同产生了用于权限认证的sid,因此我们可以伪造sid绕过一些权限检测。还有seccode的相关利用,在这里就不一一介绍。

整个discuz的程序其实是包含了discuz主程序和Ucenter,Ucenter更依赖于固定密钥体系,个人感觉Ucenter的漏洞可能要比discuz主程序好挖些,你可以去试试。

4. UC_MYKEY
UC_MYKEY主要用来加密和解密UC_KEY(discuz),如下所示:

UC_KEY(dz) ----- authcode(UC_MYKEY, ENCODE) ----> authkey(uc_server)

authkey(uc_server) ----
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值