DedeCMS V5.7 SP2漏洞分析 – 作者:MoriartyC

任意用户密码重置漏洞分析

漏洞分析

由于在resetpassword.php中对接受的safeanswer参数的类型比较不够严格,所以会遭受弱类型比较攻击。
1、漏洞点在忘记密码功能,源码文件在/member/resetpassword.php
1609290125_5febd18d96347a56f54a4.png!small?1609290125950
首先说明一下PHP中empty()函数的特性,在empty($var)中,当var存在,并且是一个非空非零的值时,返回FALSE否则返回TRUE。而其中若变量为0则会被认为是空的,返回TRUE。
在问题代码else if里,当$dopost == safequestion时,通过用户ID查询出用户的安全问题和答案,当问题和答案不为空且等于数据库中查出来的问题和答案时就进入sn()函数。
而在$row[‘safequestion’] == $safequestion && $row[‘safeanswer’] == $safeanswer中,因为使用了不够严谨的==进行了比较,导致if语句的条件为真,就会进入分支sn函数。
但如果用户没有设置问题和答案,系统默认的问题是0而答案是空。
1609290150_5febd1a64350806088f0f.png!small?1609290150977
理一下逻辑:
当输入密保答案为空时,即传入答案$safeanswer=”时:
$row[‘safeanswer’] == $safeanswer 成立
但是传入问题$safequestion=”0″时,由于empty()函数,会进入if(empty($safequestion)) $safequestion=”,导致$safequestion等于空。此时$row[safequestion] == $safequestion不成立。
因此要让$row[safequestion] == $safequestion
必须绕过if判断,这就是PHP弱类型问题,使用”0.0″、”0.”、”0e1″就可以绕过判断,例如输入密保问题为0.0,那么:
if(empty(0.0))为FALSE,可以绕过if(empty($safequestion)) $safequestion=”的判断
if(‘0.0’==’0’)为TRUE,可以使$row[safequestion] == $safequestion成立
成功进入sn()函数,跟进sn()函数
2、sn()函数,源码文件在 /member/inc/inc_pwd_function.php:
1609290180_5febd1c41335dbd20742d.png!small?1609290180762
首先在数据库中根据id到pwd_tmp表中查询,判断之前是否进行过忘记密码操作。
如果没有$row则为空,进入第一个if条件,到发送新邮件的newmail()函数中。
newmail()函数
1609290199_5febd1d739cd8aa8cc355.png!small?1609290200346
进入newmail()函数中,会根据邮件地址发送邮件并插入一个记录到pwd_tmp表中。
1609290211_5febd1e341ce35e0e4c6b.png!small?1609290211535
如果之前进行过忘记密码的操作,但时间超过了10分钟,则会更新pwd_tmp表中数据。
1609290217_5febd1e99b01e248cbccb.png!small?1609290217951
跟进newmail函数:
1609290224_5febd1f008b852d4c8e0b.png!small?1609290224293
如果是第一次进行忘记密码操作,则newmail()函数会进入insert操作,将8位的随机字符串$randval加密后插入到pwd_tmp表中,然后当$send=N时(默认传入N),将随机字符串$randval拼接到url中返回,返回的url为:
1609290231_5febd1f70494abb685415.png!small?1609290231275
其中$mid为可控参数member_id,且返回的URL中含有重置密码的验证码key,那么就可以直接重置对应id的用户密码了。
再回到重置密码文件/member/resetpassword.php ,在重置密码时,判断用户id是否存在且进行过密码重置操作,若没有则退出。
1609290243_5febd203a5a4a1a3af350.png!small?1609290243999
判断完成后,进入下一个分支,判断是否超时
1609290250_5febd20a71c21ffd972db.png!small?1609290250714
如果超时,则删除pwd_tmp表中数据;如果未超时,则跳转到修改密码界面resetpassword2.htm
输入要修改的密码并提交后,数据包中提交setp变量值为2
1609290255_5febd20f5aed16c17ca24.png!small?1609290256181
1609290261_5febd21505340890fbdfa.png!small?1609290261274
判断传入key的md5值是否等于数据库中的值,若相等则修改对应用户密码。

漏洞验证

直接发送如下请求即可获取重置密码的链接:
1609290267_5febd21b414758b54b287.png!small?1609290268282
直接访问修改页url
1609290274_5febd2228becde1050e9a.png!small?1609290274985
即可直接重置密码

注意事项

若安全问题重置密码出现问题,即一直跳转对不起…则为id没有传进去,修改inc_pwd_function.php文件中如下位置:
1609290281_5febd22939d6a90a3d066.png!small?1609290281501
将amp;删除,留下&id和&key

任意文件上传漏洞

漏洞分析

1、文件上传检测逻辑
先在/include/uploadsafe.ini.php中使用黑名单机制进行检测
1609290290_5febd2324be352ece4a06.png!small?1609290290816
除非是管理员后台dedeadmin才可上传黑名单文件。
之后在/include/dialog/select_images_post.php中进行过滤和白名单检测。
1609290295_5febd237942159c5e6791.png!small?1609290295856
2、上传绕过
在/include/dialog/select_images_post.php中,36行将文件名中正则匹配到的异常符号替换为空白,并在之后38行检测文件名中是否存在白名单中文件格式,这两种做法均未取文件后缀名来进行判断,所以存在被绕过的漏洞。
1609290300_5febd23cf353e6429fe88.png!small?1609290303625
查找$cfg_imgtype白名单,在upload/data/config.cache.inc.php第16行发现了上传格式的限制
1609290306_5febd242f21daac7c04a7.png!small?1609290307324
上传成功后会重命名文件,截取最后一个.后面的字符为后缀,如:1.jpg.php 则会重命名为时间+随机字符.php
1609290313_5febd2490e20073f49e93.png!small?1609290313289
因此可以用1.jpg.p*hp等方式绕过:
其中p*hp绕过uploadsafe.inc.php的黑名单检测,而后因其中包含特殊字符*,在select_images_post.php中被正则匹配替换为空,则变成1.jpg.php,再匹配白名单config.cache.inc.php中的$cfg_imgtype,发现文件名中包含jpg从而绕过白名单检测,最后重命名文件将1.jpg.php重命名为时间+随机字符.php实现上传绕过。

漏洞验证

注册账号进入会员中心
1609290318_5febd24edf88faf31a614.png!small?1609290319452
在内容中心找到文章发表
1609290324_5febd2543db91cd6b8a72.png!small?1609290324488
找到上传点
1609290330_5febd25a4bcf6be5acb0a.png!small?1609290330563
1609290338_5febd2623b2c4bd1b2982.png!small?1609290338459上传图片马并抓包
1609290344_5febd268f00ff05df6c44.png!small?1609290345743
修改filename的2.png为2.png.p*hp后放包
1609290362_5febd27a1f2e3cd900214.png!small?1609290362460
得到路径,访问
1609290367_5febd27fc43b1e4730a1c.png!small?1609290368675

代码执行漏洞

漏洞分析

1609290374_5febd286b898afa9242ba.png!small?1609290375053
由于DedeCMS的全局变量注册特性,content和filename变量可控
可以直接将content的值写入到文件中,因为正则,所以文件必须以.lib.php结尾
因为存在csrf_check()函数,所以请求中必须有token

漏洞利用

首先获取token,访问 127.0.0.1/dedecms/uploads/dede/tpl.php?action=upload,在页面源代码中获取到token值

1609290386_5febd292d9bcd80bc761e.png!small?1609290387187
添加到url的token值中
http://127.0.0.1/dedecms/dede/tpl.php?filename=1.lib.php&action=savetagfile&content=%3C?php%20phpinfo();?%3E&token=7b676a4b62bcba23832632e4fb7534b8
1609290392_5febd298b0d1d09cff510.png!small?1609290393046
访问 127.0.0.1/dedecms/include/taglib/1.lib.php
1609290399_5febd29f88c05ac5e1967.png!small?1609290399866
成功

来源:freebuf.com 2020-12-30 09:21:39 by: MoriartyC

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论