0%

DedeCMSv5.7SP2代码审计

审计环境

PHP7.0

Apache

PHPSTORM

这里需要注意的是

dedecms在php5.4以上会因为session_register()等函数已移除,无法正常运行

在include/userlogin.class.php中代码替换,被替换代码大致在288到304行之间,代码如下:

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
@session_register($this->keepUserIDTag);
$_SESSION[$this->keepUserIDTag] = $this->userID;
@session_register($this->keepUserTypeTag);
$_SESSION[$this->keepUserTypeTag] = $this->userType;
@session_register($this->keepUserChannelTag);
$_SESSION[$this->keepUserChannelTag] = $this->userChannel;
@session_register($this->keepUserNameTag);
$_SESSION[$this->keepUserNameTag] = $this->userName;
@session_register($this->keepUserPurviewTag);
$_SESSION[$this->keepUserPurviewTag] = $this->userPurview;
@session_register($this->keepAdminStyleTag);
$_SESSION[$this->keepAdminStyleTag] = $adminstyle;

替换为如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
$_SESSION[$this->keepUserIDTag] = $this->keepUserIDTag;
$_SESSION[$this->keepUserIDTag] = $this->userID;
$_SESSION[$this->keepUserTypeTag] = $this->keepUserTypeTag;
$_SESSION[$this->keepUserTypeTag] = $this->userType;
$_SESSION[$this->keepUserChannelTag] = $this->keepUserChannelTag;
$_SESSION[$this->keepUserChannelTag] = $this->userChannel;
$_SESSION[$this->keepUserNameTag] = $this->keepUserNameTag;
$_SESSION[$this->keepUserNameTag] = $this->userName;
$_SESSION[$this->keepUserPurviewTag] = $this->keepUserPurviewTag;
$_SESSION[$this->keepUserPurviewTag] = $this->userPurview;
$_SESSION[$this->keepAdminStyleTag] = $this->keepAdminStyleTag;
$_SESSION[$this->keepAdminStyleTag] = $adminstyle;

364到368替换如下:

1
2
3
4
5
unset($this->keepUserIDTag);
unset($this->keepUserTypeTag);
unset($this->keepUserChannelTag);
unset($this->keepUserNameTag);
unset($this->keepUserPurviewTag);

cookie伪造导致任意前台用户登录

  • 漏洞分析

    屏幕截图 2021-03-13 103333

    跟进PutCookie方法,在该方法中的第27行中将值与配置文件中的$cfg_cookie_encode进行拼接,然后进行MD5和截断处理substr(md5($cfg_cookie_encode.$value),0,16),然后下发到客户端

    image-20210313104510453

    而在include/common.inc.php使用的外部变量注册的方法进行变量声明,因此此处的$uid是用户可控的。

    屏幕截图 2021-03-13 104107

    这里我们就可以获取到任意用户的last_vid last_vid__ckMd5

    而在文件include/helpers/cookie.helper.php中的第54-72行的GetCookie方法的代码块,其中第63行用于校验客户端cookie是否进行了伪造,因此要进行cookie就自然想到要获取uploads/data/config.cache.inc.php文件中的内容,需要存在任意文件读取或下载的漏洞,当然还有另外一种方式,就是控制$uid,利用PutCookie直接生成cookie,这样的cookie定会通过GetCookie方法。

    image-20210313105340716

接着查看登录相关的代码,看它的cookie生成方法是否是PutCookie。在include/memberlogin.class.php 498行PutLoginInfo方法处理正确输入用户名和密码的情况

image-20210313112216221

继续跟进PutLoginInfo方法,果然用的是PutCookie方法,存在cookie伪造漏洞

屏幕截图 2021-03-13 112733

在文件include/memberlogin.class.php的第160-242行发现代码块,其中第170行检测cookie中的DedeUserID参数的值,178行将这个值转换为整数,185行通过这个给值来查询用户。我们通过伪造DedeUserID即可任意用户登录了。

屏幕截图 2021-03-13 121536

  • 漏洞复现

    情况一:

    由于mid在数据库中是int,所以要进行cookie的伪造需要注册用户名为要越权的用户mid数值,而admin默认为1。因此可以直接登录为admin。

    需要注册用户名为对应数据库中dede_member表中mid对应的值。如注册用户名为0001对应dede_member表中mid为1,便是admin的mid。

    屏幕截图 2021-03-13 123051

然后访问/member/index.php?uid=0001获取伪造的cookie

屏幕截图 2021-03-13 130027

最后访问/member/index.php并带上cookie即可

屏幕截图 2021-03-13 130235

​ 情况二:

​ 在member/index.php文件第124行,当uid不为空时会require_once(DEDEMEMBER.'/inc/config_space.php')

image-20210313131650792

​ 跟进member/inc/config_space.php在第29行调用了GetUserSpaceInfos方法

image-20210313131855022

​ 跟进GetUserSpaceInfos方法,其SQL查询语句使用了like获取数据,通过构造特殊的用户名即可让其下发伪造cookie

屏幕截图 2021-03-13 131954

这里我们假设要登录mid为5的用户

image-20210313132505860

我们先注册类似于xx5xx的用户

image-20210313132632833

然后访问/member/index.php?uid=%5%获取伪造cookie

屏幕截图 2021-03-13 132811

加上cookie访问/member/index.php

image-20210313132944373

任意修改前台用户密码

  • 漏洞分析

    member/resetpassword.php75-99行,进行安全问题的判断。默认$row['safequestion']在数据库的内容为'0'$row['safeanswer']在数据库中的结果为'',且变量$safeanswer$safequestion是用户可控制的变量,又使用了 ==进行判断, 因此该判断规则存在弱类型问题。如果用户在注册时设置了密保问题则没有这个问题

    屏幕截图 2021-03-13 151940

    这里打印下$row

    对于$safeanswer我们不传值,经过85行处理也会为空,从而相等。

    对于$safequestion我们需要传一个值使其绕过empyt()且等于‘0’

    根据手册,我们可以构造出

    1
    2
    3
    4
    5
    0.0(作为字符串)
    0x0
    0e0
    0e1
    ...

    image-20210313155728546

  • 漏洞复现

    先进行如下请求获取key

    /member/resetpassword.php?dopost=safequestion&safequestion=0x0&safeanswer=&id=2

    屏幕截图 2021-03-13 160236

image-20210313160537171

任意重置后台用户密码

  • 漏洞分析

    member/edit_baseinfo.php 118-123行修改前端密码同时也会修改后端密码

image-20210313161155719

前台任意文件删除

  • 漏洞分析

    问题出在member/inc/inc_batchup.phpDelArc方法,对于$licp['litpic']直接拼接在目录后面只检测文件存不存在,没有检查文件类型就直接删除。重点在于这个litpic我们是否可控

    image-20210313204533734

    接着全局搜索了litpic变量,发现member/inc/archives_check_edit.php发现79-93行可以通过控制$oldlitpiclitpic。在$litpic为空的情况下,$litpic=$oldlitpic

    image-20210314155059165

    接着全局搜索archives_check_edit

    image-20210314152654346

    也就是这四个功能受影响

    屏幕截图 2021-03-14 155544

    而在上传图集的功能里,同样可控litpicmember/album_add.php 88-103行,在$formhtml==1 && $ddisfirst==1 && $litpic=='' && !empty($litpicname)$litpic==$litpicname

    屏幕截图 2021-03-14 160450

    $formhtml可传参控制,$ddisfirst默认为1,至于$litpic我们跟进archives_check.php,在100-102行

    image-20210314161257476

    跟进MemberUploads方法,在include/helpers/upload.helper.php 118-240行,其中215-222行是关键在不上传缩略图的情况下会进入else分支,同时MemberUploadshandname参数默认为空。即返回值也为空。所以$litpic可控

    image-20210314161619071

    最后全局搜索DelArc函数查找触发点,在member/archives_do.php,有个issystem的判断

    image-20210314162605298

    数据库查询一下,默认情况下出了infos其他都会调用DelArc删除文件。

    image-20210314162729095

  • 漏洞复现

    情况一:

    以文章为例

    先发表文章,内容随意填

    image-20210314164413817

    再修改文章同时加上oldlitpic的值

    屏幕截图 2021-03-14 164614

    数据库:

    image-20210314164927927

    最后删除文章即可删除oldlitpic指向的文件。

    屏幕截图 2021-03-14 165328

    情况二:

    上传图集时添加formhtmllitpicname即可

    image-20210314165944131

    删除图集

    image-20210314170320939

前台任意文件上传

  • 漏洞分析

    上传需要admin权限,有点鸡肋。但配合之前的cookie伪造也还行。

    问题在include/dialog/select_images_post.php对于后缀的处理逻辑有问题。在36行获取文件名,然后过滤。

    image-20210316211925145

    这个文件名就是我们上传的文件名,具体的调用是

    1
    select_images_post.php -> config.php -> common.inc.php ->  uploadsafe.inc.php

    屏幕截图 2021-03-16 212521

    接着在58到64行进行后缀拼接和上传。直接通过.来分割文件名,将最后一个后缀作为文件后缀。

    屏幕截图 2021-03-16 212843

    通过构造类似

    1
    2
    3
    4
    5
    p%hp
    p*hp
    p<hp
    p?hp
    ...

    即可绕过上传。

  • 漏洞利用

    屏幕截图 2021-03-16 213715

    屏幕截图 2021-03-16 215140

image-20210316215503126

后台文件写入

  • 漏洞分析

    又是需要后台admin权限,太鸡肋了。DedeCMS后台本来就带有文件管理器,本着学习的态度就记录一下。

    问题出在dede/sys_verifies.phpfwrite的参数未经过过滤,导致文件写入,配合require_oncegetshell

屏幕截图 2021-03-17 190619

屏幕截图 2021-03-17 191424

  • 漏洞复现

    访问/dede/sys_verifies.php?action=getfiles&refiles[]=\";eval($_GET[a]);die();// 写入文件

    image-20210317191752815

    访问/dede/sys_verifies.php?action=down&a=phpinfo();执行命令

    image-20210317191855712

后台二次注入getshell

  • 漏洞分析

    dede/ad_add.php80-83行,参数$normbody未经过滤就放入数据库中

    屏幕截图 2021-03-17 193957

    而在plus/ad_js.php 21-44行,查询结果直接包含。

    屏幕截图 2021-03-17 194249

  • 复现漏洞

    image-20210317194532192

image-20210317194553335

参考

https://www.freebuf.com/column/161703.html

https://www.cnblogs.com/zpchcbd/p/12741373.html

-------------本文结束感谢您的阅读-------------