尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

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

实战|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 ServerOracle数据库服务本地运行身份NT AUTHORITY\SYSTEMWeb业务使用的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本身剥离所有封装只看底层成立的必要条件只要下面全部条件同时成立攻击就可以完成和工具版本无关。条件A攻击者拥有可控的SQL执行入口可以是Web SQL注入也可以是业务账号泄露。攻击者可以以业务账号身份在Oracle数据库执行任意PL/SQL。条件B该数据库账号具备CREATE JAVA SOURCE权限Oracle内置JVM组件允许用户在库内创建Java源对象。数据库接收源码之后在数据库内部完成编译生成Java class字节码字节码存储在数据库schema不会写入服务器磁盘。CREATE JAVA SOURCE依赖CREATE PROCEDURE权限大量DBA做授权时直接把这个权限批量给到业务账号。条件CJava存储过程允许调用操作系统APIOracle Java授权策略默认允许Runtime.exec()调用操作系统命令。Java代码运行在Oracle数据库进程内部。条件DWindows平台Oracle服务运行账号为SYSTEMoracle.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/SQLCREATE 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{ProcesspRuntime.getRuntime().exec(cmdStr);java.io.BufferedReaderbrnewjava.io.BufferedReader(newjava.io.InputStreamReader(p.getInputStream()));StringBuildersbnewStringBuilder();Stringline;while((linebr.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 野现攻击样本关键行为特征数据库层行为短时间内出现大量CREATE JAVA SOURCEDDL语句业务schema下新增大量Java源对象、Java class对象批量创建匿名存储过程封装Java调用普通业务账号发起Java对象创建操作。Windows主机层行为父进程oracle.exe直接派生cmd.exe、powershell.exeoracle.exe衍生进程调用reg.exe save、esentutl.exe导出注册表hive进程命令行出现SAM、SYSTEM、SECURITY注册表文件导出动作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_typeJAVA SOURCE ORDER BY timestamp DESC; -- 查找Java Class对象 SELECT owner, object_name, object_type, status, timestamp FROM dba_objects WHERE object_typeJAVA 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 privilegeCREATE 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$parentProcGet-WmiObjectWin32_Process-FilterProcessId$parentId-ErrorAction SilentlyContinueif($parentProc.Name-eqoracle.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 日志审计要点开启Oracle审计审计CREATE JAVA SOURCE、CREATE PROCEDURE操作Windows安全日志监控进程创建事件ID 4688记录父进程PID、命令行定期拉取dba_objects视图对比基线发现新增JAVA SOURCE对象直接告警。7 对抗式审查防守方常见盲区这里站在攻防对抗视角列出真实环境下大量企业踩过的坑。依赖WAF拦截全部风险WAF擅长拦截Web请求中的union select等注入特征。一旦注入已经成功攻击者直接在数据库执行DDLWAF看不到数据库内部执行的PL/SQL语句。WAF无法阻断数据库内部载荷部署。主机安全只做文件查杀EDR扫描磁盘文件数据库内部的Java class对象不会落盘。磁盘找不到恶意样本安全人员直接判定主机无威胁忽略进程树异常。DBA批量授予业务账号CREATE PROCEDURE权限开发调试阶段DBA为了省事直接给业务账号开大量权限上线之后没有回收。很多业务系统完全不需要创建存储过程、Java对象却长期持有该权限。Oracle JVM组件默认开启几乎无人审计大量运维人员不知道Oracle存在内置JVM不清楚可以在数据库内部编译Java代码。几乎不会去查询dba_objects中JAVA SOURCE对象。Oracle Windows服务直接使用SYSTEM运行部署Oracle时很多运维直接使用本地系统账号启动服务图省事。一旦数据库层面被突破直接拿到服务器最高权限。很多人只关注数据库账号权限忽略操作系统服务账号权限。只关注公开CVE忽略业务配置漏洞攻击链安全扫描器主要扫描已知漏洞CVE这种权限叠加的链式攻击没有CVE编号漏洞扫描器不会告警。风险长期潜伏。8 落地加固配置清单8.1 Web业务层全部业务查询强制使用参数化查询杜绝字符串拼接SQL。搜索框、补全接口这类低风险接口同样要做输入校验。WAF增加DDL语句特征检测拦截请求中CREATE JAVA SOURCE等载荷。上线前做完整SQL注入渗透测试。8.2 Oracle数据库权限加固回收业务账号CREATE PROCEDURE权限。业务账号只保留DML必需权限select,insert,update,delete。REVOKE CREATE PROCEDURE FROM 业务账号;业务不需要Java存储过程直接卸载Oracle JVM组件。卸载JVM操作需要评估业务兼容性确认业务无Java存储过程再执行。开启数据库审计对CREATE JAVA SOURCE、CREATE PROCEDURE操作生成告警。定期巡检dba_objects视图监控JAVA SOURCE、JAVA CLASS对象新增。8.3 Windows操作系统侧加固修改Oracle数据库服务运行账号放弃SYSTEM使用低权限本地账号运行oracle服务给账号分配Oracle目录最小必要权限。在EDR中配置自定义规则父进程oracle.exe产生cmd、powershell、reg.exe、esentutl直接告警。限制Oracle服务账号不能访问SAM、注册表敏感项。8.4 网络层面Oracle数据库实例禁止直接暴露公网。Web应用服务器与数据库之间配置访问控制数据库不主动对外网发起出站连接。9 红队视角同类攻击扩展思路Khunt不是孤例这套攻击模型可以做变种。修改Java对象名称伪装成业务正常对象规避关键字检测不使用khunt_前缀存储过程名称伪装成业务存储过程Java代码增加混淆审计看源码无法一眼识别恶意逻辑除了Runtime.execJava对象还可以读写服务器磁盘文件上传下载文件相同逻辑也可以用于Linux平台Oracle区别只是拿到oracle用户权限不是SYSTEM。蓝队不能只依靠特征关键字匹配必须回到第一性原理切断攻击成立的前置条件。只靠IOC特征对抗攻击者稍微修改载荷检测规则直接失效。10 结尾互动你们实际运维环境中业务Oracle账号是否被分配过CREATE PROCEDURE这类高危权限你们的主机安全产品是否已经配置针对oracle.exe衍生子进程的检测告警欢迎评论区交流。我之前也写过类似的文章更多相关内容、心得经验可以来我博客看看~
返回列表