空指针-Base on windows Writeup -- 最新版DZ3.4实战渗透

作者:LoRexxar’@知道创宇404实验室
时间:2020年5月11日
原文地址:https://paper.seebug.org/1197/

周末看了一下这次空指针的第三次Web公开赛,稍微研究了下发现这是一份最新版DZ3.4几乎默认配置的环境,我们需要在这样一份几乎真实环境下的DZ中完成Get shell。这一下子提起了我的兴趣,接下来我们就一起梳理下这个渗透过程。

与默认环境的区别是,我们这次拥有两个额外的条件。

1、Web环境的后端为Windows
2、我们获得了一份config文件,里面有最重要的authkey

得到这两个条件之后,我们开始这次的渗透过程。

以下可能会多次提到的出题人写的DZ漏洞整理

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

authkey有什么用?

/ -------------------------  CONFIG SECURITY  -------------------------- //
$_config['security']['authkey'] = '87042ce12d71b427eec3db2262db3765fQvehoxXi4yfNnjK5E';

authkey是DZ安全体系里最重要的主密钥,在DZ本体中,涉及到密钥相关的,基本都是用authkey和cookie中的saltkey加密构造的。

当我们拥有了这个authkey之后,我们可以计算DZ本体各类操作相关的formhash(DZ所有POST相关的操作都需要计算formhash)

配合authkey,我们可以配合source/include/misc/misc_emailcheck.php中的修改注册邮箱项来修改任意用户绑定的邮箱,但管理员不能使用修改找回密码的api。

可以用下面的脚本计算formhash

$username = "ddog";
$uid = 51;
$saltkey = "SuPq5mmP";
$config_authkey = "87042ce12d71b427eec3db2262db3765fQvehoxXi4yfNnjK5E";
$authkey = md5($config_authkey.$saltkey);
$formhash = substr(md5(substr($t, 0, -7).$username.$uid.$authkey."".""), 8, 8);

当我们发现光靠authkey没办法进一步渗透的时候,我们把目标转回到hint上。

1、Web环境的后端为Windows
2、dz有正常的备份数据,备份数据里有重要的key值

windows短文件名安全问题

在2019年8月,dz曾爆出过这样一个问题。

windows短文件名安全问题 数据库备份爆破
在windows环境下,有许多特殊的有关通配符类型的文件名展示方法,其中不仅仅有 <>"这类可以做通配符的符号,还有类似于~的省略写法。这个问题由于问题的根在服务端,所以cms无法修复,所以这也就成了一个长久的问题存在。

具体的细节可以参考下面这篇文章:

Windows下的"你画我猜" – 告别效率低下的目录扫描方法
配合这两篇文章,我们可以直接去读数据库的备份文件,这个备份文件存在

/data/backup_xxxxxx/200509_xxxxxx-1.sql

我们可以直接用

http://xxxxx/data/backup~1/200507~2.sql

拿到数据库文件

从数据库文件中,我们可以找到UC_KEY(dz)

pre_ucenter_applications的authkey字段找到UC_KEY(dz)

至此我们得到了两个信息:

uckey

x9L1efE1ff17a4O7i158xcSbUfo1U2V7Lebef3g974YdG4w0E2LfI4s5R1p2t4m5

authkey

87042ce12d71b427eec3db2262db3765fQvehoxXi4yfNnjK5E

当我们有了这两个key之后,我们可以直接调用uc_client的uc.php任意api。,后面的进一步利用也是建立在这个基础上。

uc.php api 利用

这里我们主要关注/api/uc.php

在这里插入图片描述

通过UC_KEY来计算code,然后通过authkey计算formhash,我们就可以调用当前api下的任意函数,而在这个api下有几个比较重要的操作。

我们先把目光集中到updateapps上来,这个函数的特殊之处在于由于DZ直接使用preg_replace替换了UC_API,可以导致后台的getshell。

具体详细分析可以看,这个漏洞最初来自于@dawu,我在CSS上的演讲中提到过这个后台getshell:

https://paper.seebug.org/1144/#getwebshell
https://lorexxar.cn/2020/01/14/css-mysql-chain/#%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E8%AF%BB-with-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E6%B3%84%E9%9C%B2
根据这里的操作,我们可以构造$code = 'time='.time().'&action=updateapps';

来触发updateapps,可以修改配置中的UC_API,但是在之前的某一个版本更新中,这里加入了条件限制。

if($post['UC_API']) {
   
    $UC_API = str_replace(array('\'', '"', '\\', "\0", "\n", "\r"), '', $post['UC_API']);
    unset($post['UC_API']);
}

由于过滤了单引号,导致我们注入的uc api不能闭合引号,所以单靠这里的api我们没办法完成getshell。

换言之,我们必须登录后台使用后台的修改功能,才能配合getshell。至此,我们的渗透目标改为如何进入后台。

如何进入DZ后台?

首先我们必须明白,DZ的前后台账户体系是分离的,包括uc api在内的多处功能,login都只能登录前台账户,

也就是说,进入DZ的后台的唯一办法就是必须知道DZ的后台密码,而这个密码是不能通过前台的忘记密码来修改的,所以我们需要寻找办法来修改密码。

这里主要有两种办法,也对应两种攻击思路:

1、配合报错注入的攻击链
2、使用数据库备份还原修改密码

1、配合报错注入的攻击链

继续研究uc.php,我在renameuser中找到一个注入点。

function renameuser($get, $post) {
   
        global $_G;

        if(!API_RENAMEUSER) {
   
            return API_RETURN_FORBIDDEN;
        }



        $tables = array(
            'common_block' => array('id' => 'uid', 'name' => 'username'),
            'common_invite' => array('id' => 'fuid', 'name' => 'fusername'),
            'common_member_verify_info' => array('id' => 'uid', 'name' => 'username'),
            'common_mytask' => array('id' => 'uid', 'name' => 'username'),
            'common_report' => array('id' => 'uid', 'name' => 'username'),

            'forum_thread' => array('id' => 'authorid', 'name' => 'author'),
            'forum_activityapply' => array('id' => 'uid'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值