首页
社区
课程
招聘
[原创]dedecms cookie伪造任意前台用户登录
发表于: 2018-1-24 22:37 12899

[原创]dedecms cookie伪造任意前台用户登录

2018-1-24 22:37
12899

dedecms在对前台用户认证时采用的是通过cookie的验证方式,通过Cookie中的DedeUserIDDedeUserID__ckMd5对当前的用户的身份以及登录状态进行验证。此漏洞的原因就是将DedeUserIDDedeUserID__ckMd5伪造成为了其他用户的值,这样就导致伪造其他用户的Cookie而能够以其他的用户登录。

漏洞的前提是要求开启前台用户注册的功能,保证用户能够顺利地进行注册(包括审核通过,能够查看个人空间)

首先需要明确用户登录时后台的处理流程。当会员登录时,后台的处理流程时:

在dedecms中,所有的cookie是成对出现的。如DedeUserID__ckMd5DedeUserID,以及DedeLoginTime__ckMd5DedeLoginTime。其中的DedeUserID__ckMd5这种形式是对DedeUserID进行了校验,防止前台的Cookie被任意地篡改。dedecms中所有的cookie操作都是由include/helpers/cookie.helper.php:PutCookie()方法设置的,如下:

$key.'__ckMd5'是由substr(md5($cfg_cookie_encode.$value),0,16)得到的,其中的cfg_cookie_encode是在程序安装时设置的。所以如果我们不知道这个值,我们是无法破解$key.'__ckMd5'。所以一般情况下,我们是无法破解$key.'__ckMd5'这类值的。

所有的取Cookie的操作都是由include/helpers/cookie.helper.php:GetCookie()设置的,如下:

由于根据$_COOKIE[$key . '__ckMd5']$_COOKIE[$key]进行了校验,这种方式就能够有效地避免前台任意第修改Cookie,这种方式本意上是好的,但是由于dedecms的实现问题,导致这种方式也会成为漏洞的根源。试想一下,如果我们同时修改了$_COOKIE[$key]$_COOKIE[$key . '__ckMd5']就可以绕过这个验证了。

include/memberlogin.class.php中的MemberLogin

其中取得M_ID的函数是$this->M_ID = $this->GetNum(GetCookie("DedeUserID"));,其中GetNum()的做法是:

直接将不是数字的字符全部都替换掉。之后通过SQL语句Select * From '#@__member' where mid='{$this->M_ID}'来判断用户的身份。由于GetNum()采用的是替换的方法,那么如果Cookie中的DedeUserID是0000001,

正常情况下,程序中的DedeUserID就是当前用户的用户ID。但是如果将其中的DedeUserIDDedeUserID__ckMd5都替换为其他的账户,是否就意味着我们可以以其他的账户登录呢?

那么现在的问题就在于,如何进行伪造呢?我们知道管理员admin的mid是1,但是我们如何得到对应的DedeUserID__ckMd5呢?所以目前的问题转变为我们需要得到1所对应的DedeUserID__ckMd5的。

分析member/index.php中的122行之后的代码:

对其中的last_vid的赋值情况进行分析:

那么这就是存在一个漏洞的触发点。如果我们将$uid设置为001,那么得到的last_vidlast_vid__ckMd5刚好就是一对可以使用的Cookie,同时001也刚好可以绕过管理员的验证。

但是需要注意的是,在124行存在代码require_once(DEDEMEMBER.'/inc/config_space.php');,引入了config_space.php文件。跟进member/inc/config_space.php,

在数据库查询的语句中where m.userid like '$uid' ORDER BY g.dtime DESC ",其中传入的$uid作为了userid。如果不存在程序就会退出。那么这就意味着我们传入的uid必须是已经存在的一个用户名,所以我们注册用户名时注册的用户名最好是001这种。

至此,所有的漏洞触发点集合在一起就能够触发这个漏洞了。整个漏洞的触发流程是:

注册一个用户名为001的用户

注册成功之后,跳转到会员首页(会员首页地址是member/index.php)。可以发现此时还是正常用户001,只有4个Cookie值,分别是DedeUserID__ckMd5DedeUserIDDedeLoginTime__ckMd5DedeLoginTime

访问链接member/index.php?uid=001。此时Cookie中会增加一些内容,其中最为重要的是last_vidlast_vid__ckMd5,取得他们的值。在我本地演示中,他们分别是001c6fda866fabaca07

最为关键的第一步,替换掉Cookie中的DedeUserID001,DedeUserID__ckMd5为第四步last_vid__ckMd5得到的值c6fda866fabaca07

修改完毕之后,访问会员首页member/index.php,此时已经变成了管理员了。

演示中主要是登录了管理员的身份。因为其中我们中间访问时利用的是member/index.php?uid=001。如果需要登录其他账户的身份,比如id为7的用户,那么我们就需要注册一个名为007的账户,同时中途需要访问的是member/index.php?uid=007链接,将其中的last_vidlast_vid__ckMd5进行替换,就可以以007的账户登录。以此类推,我们就可以以任意的账户进行登录了。

以上就完成了对整个漏洞的分析与复现。本漏洞其实主要是因为dedecms是通过Cookie中的DedeUserID对用户身份进行鉴别的,虽然使用了DedeUserID__ckMd5,但是我们看到还是可以被绕过的,最终形成了Cookie伪造导致任意用户登录的漏洞。

对于身份认证这类的信息,最好是放在Session中,前台的用户不容易修改,就不会出现这种Cookie伪造的问题了。

 
 
 

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 203
活跃值: (53)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
谢谢分享,楼主非常擅长代码审计呢。
2018-1-26 11:06
0
雪    币: 0
活跃值: (73)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
太难懂了      最好写简单点
2018-2-12 21:18
0
雪    币: 66
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢分享,要看很久才能看懂
2018-2-23 11:28
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
流批,嘤嘤嘤
2018-2-28 16:15
0
雪    币: 2785
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
还得慢慢看
2018-3-4 17:43
0
雪    币: 300
活跃值: (2422)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
谢谢楼主分享
2018-3-4 22:19
0
雪    币: 185
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
可以给个联系方式吗?
2019-3-13 05:43
0
游客
登录 | 注册 方可回帖
返回
//