Your Oracle Database Can Run Malware, and Someone Did
A routine SQL injection became SYSTEM-level RCE because the app account could compile Java, no CVE required.
Security firm Huntress published a breakdown on August 5 of an intrusion that ought to make anyone running Oracle behind a web app uneasy — not because it burned a zero-day, but because it didn't need one. Attackers turned a garden-variety SQL injection bug into SYSTEM-level command execution and credential theft on a Windows server, and they pulled it off by turning the Oracle Database itself into the malware host. Nothing was dropped to disk. There's no CVE. The post-exploitation toolkit, which its operators named khunt, ran as compiled schema objects living inside the database.
That last detail is the entire story. Everything else is a well-understood consequence.
What actually happened
The victim ran a public-facing Java/Tomcat application with an Oracle backend. An autocomplete search field didn't validate its input, so an attacker at 178.162.151[.]229 fed SQL straight through the app's JDBC connection. Ordinary so far — this is the most tired vulnerability class in existence.
What came next is what matters. Instead of trying to smuggle a binary onto the box, the attacker issued CREATE JAVA SOURCE statements, using Oracle's embedded JVM to compile Java code into the database as schema objects. khunt was a modular kit wired to PL/SQL wrappers that called those Java methods: KhuntCmd spawned cmd.exe and ran arbitrary OS commands passed in as SQL; KhuntHash read usernames and password hashes out of Oracle's internal user table and wrote them to a file; KhuntFS and KhuntFS2 listed, read, searched, and sized files; KhuntT confirmed the install; KhuntUnzip handled archives.
Then the payoff. The attacker ran cmd.exe /c whoami through KhuntCmd and got back NT AUTHORITY\SYSTEM. From there they used PowerShell, reg.exe, and esentutl.exe to copy the SAM, SECURITY, and SYSTEM registry hives into the Oracle directory — F:\Oracle\khuntSECURITY.hiv and friends — the raw material for offline cracking of every local Windows account. tasklist /svc went to khunttasks.txt for good measure.
None of this is new — that's the point
Java has lived inside Oracle since 8i shipped in 1999, and turning PL/SQL or a database-resident Java class into an OS shell has been documented for well over fifteen years. David Litchfield wrote it up in The Oracle Hacker's Handbook; Alexander Kornbrust and the Red Database Security crowd have been demoing CREATE JAVA SOURCE shells at conferences since roughly forever. The capability is a feature, working exactly as designed. Huntress itself notes the technique has been discussed before but "rarely documented" in the wild.
So the honest framing isn't "novel malware." It's a defender's blind spot finally catching up with a database platform that was always a full application runtime. Oracle is not a dumb data store; it's an operating environment with a JVM, a job scheduler, package-level file and network access, and its own privilege model. Treat it like a filing cabinet and you will be surprised exactly this way. The novelty here is operational — a real intruder doing in production what researchers have shown in slides for years.
Windows is what made it catastrophic
The privilege jackpot came from a platform default. On Windows, the Oracle database service has historically run as LocalSystem, so any command khunt executed inherited SYSTEM. Injection at the app layer became total control of the host in one hop.
On Linux this plays out very differently: the Oracle processes run as the unprivileged oracle account, not root, so the same CREATE JAVA SOURCE trick still yields RCE — but confined to that user's blast radius, not the whole machine. The difference is entirely about which account the engine runs as. And Oracle gave Windows admins the fix over a decade ago: the "Oracle Home User" option, introduced in Database 12c, lets you run the services as a low-privilege local or domain account instead of LocalSystem. Almost nobody flips it. If you run Oracle on Windows and never touched that setting, your database process is one injection bug away from handing over the box.
The control that actually failed
Everyone will say "parameterize your queries," and yes, do that — it stops the injection. But parameterization is table stakes, and defense in depth means assuming it will fail somewhere. The real failure here was privilege. The application's database account could author and compile Java. It almost certainly never needed to.
A web app's runtime account should be able to run its SELECT/INSERT/UPDATE/DELETE and nothing else. Audit it for anything that grants a foothold beyond data: CREATE PROCEDURE, CREATE ANY PROCEDURE, CREATE JAVA SOURCE, the JAVAUSERPRIV and JAVASYSPRIV roles, and EXECUTE on heavy machinery like DBMS_JAVA and DBMS_SCHEDULER. Strip them. If the injected session can't compile Java or execute stored code, khunt has nowhere to land — the same SQL injection degrades from full host compromise to, at worst, a data-read problem. That's the whole game of least privilege: not preventing the bug, but capping what the bug can reach.
Stop looking at the filesystem
The reason this ran quietly is that file-based EDR had nothing to scan. The payload was a row in the data dictionary. Detection has to move to where the malware actually lives — the database and the process tree.
Start with the dictionary. Recently created Java objects in an application schema are a loud signal, because well-behaved app schemas basically never author them:
SELECT owner, object_name, object_type, created
FROM dba_objects
WHERE object_type IN ('JAVA SOURCE', 'JAVA CLASS', 'JAVA RESOURCE')
OR object_name LIKE 'KHUNT%'
ORDER BY created DESC;
Then watch the host. The unmistakable tell is oracle.exe spawning cmd.exe, powershell.exe, reg.exe, or esentutl.exe — a database engine has no legitimate reason to launch a shell or dump registry hives. And sweep the Oracle install directories for stray khunt*.hiv files. Any one of these on its own is worth a page.
The uncomfortable takeaway is that this attack required no special access, no exploit, and no custom vulnerability — only an over-permissioned account and a service running as SYSTEM, both of which are depressingly common defaults. khunt is a proof, not a breakthrough: your database is a compute platform whether you manage it as one or not. Someone finally treated it that way in anger.
Sources & further reading
- Inside an Oracle Database SQL Injection Attack — huntress.com
- Hackers run khunt post-exploitation toolkit from Oracle database — bleepingcomputer.com
- Attackers Compile khunt Inside Oracle to Turn SQL Injection Into Windows SYSTEM Access — thehackernews.com
- Attackers hid malware inside Oracle Database after SQL injection breach — csoonline.com
- khunt: SQL Injection to Resident Threat Inside Oracle Database — dev.to
Emeka has spent over a decade tracking threat actors, vulnerability disclosures, and the evolving landscape of application security, bringing a sharp continent-spanning perspective to his reporting. He's known for translating dense CVE advisories into clear, actionable context that developers and security teams alike actually read.
Discussion 0
No comments yet
Be the first to weigh in.