Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
stirling-h2-import-leftover — Stirling-PDF v3.2.0 - Critical - Remote - H2 RUNSCRIPT leftover - CREATE OR REPLACE ALIAS import-database | Kitploit
Tools/GitHubGitHub/abraxas/stirling-h2-import-leftover
Vulnerability AnalysisExploitationWeb Application ExploitationSecurity VirtualizationPenetration TestingDatabase Security
GitHubabraxas/stirling-h2-import-leftover

stirling-h2-import-leftover

Stirling-PDF v3.2.0 - Critical - Remote - H2 RUNSCRIPT leftover - CREATE OR REPLACE ALIAS import-database

View Repository
41 day agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Abraxas Labs - stirling-h2-import-leftover

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  stirling-h2-import-leftover

stirling-h2-import-leftover

Stirling-PDF 3.2.0 - Stirling Tools

Class: H2 RUNSCRIPT leftover of GHSA-mrr8. Reach: Remote ROLE_ADMIN.

POST /api/v1/database/import-database is @PreAuthorize("hasRole('ADMIN')"). validateSqlContent is supposed to stop CREATE ALIAS. The denylist is CREATE\s+(FORCE\s+)?ALIAS. H2 parseCreate allows OR REPLACE before ALIAS, so CREATE OR REPLACE ALIAS … FOR "java.lang.…" matches the allowlist \bCREATE\b and misses the denylist. The validator sanitizes a copy. verifyBackup and production RUNSCRIPT FROM ? the original file.

GHSA-mrr8-934j-4g8m / CVE-2026-85714 closed the original FILE_READ / CREATE ALIAS / CSVWRITE strings. This leftover is the OR REPLACE gap on that same validator.

A ROLE_ADMIN import creates a Java alias the denylist is supposed to stop. A later backup download contains attacker SQL. Host FILE_READ / FileUtils RCE from the original advisory is inferred, not lab-proven in this pack.

IDno CVE yet
CWECWE-94 / CWE-184
CVSS9.1 CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H
ProductStirling-PDF
Affectedv3.2.0 (a7e593728dd9aa81e75318a949789d3c2e9ee754), image stirlingtools/stirling-pdf:3.2.0-fat
AuthROLE_ADMIN, default embedded H2. Default first admin admin / stirling until changed
LicenseGNU Affero GPL v3.0
Lab127.0.0.1:18152 only

Leftover of the Stirling-PDF v3.2.0 leftovers series. Sibling: stirling-storage-folder-idor (processing-folder implied storage root). This pack is the H2 import leftover.

What an attacker can do

ROLE_ADMIN on login-on proprietary/fat with the default embedded H2. Default first admin is admin / stirling when initialLogin is empty. They do not need unauth. Lite image and PostgreSQL datasources do not ship this controller.

Privilege table (exhaustive). Same bar as Signal-Server Dropwizard admin: method + path, what that call grants, recon vs integrity vs availability, lab-proven vs inferred, adjacent surface that stays closed.

AxisMethod + pathGrantsProvenance
IntegrityROLE_ADMIN POST /api/v1/database/import-database with CREATE OR REPLACE ALIAS lab_nano FOR "java.lang.System.nanoTime" plus INSERT INTO lab_w VALUES('STIRLING-H2-IMPORT-WITNESS')200 importIntoDatabaseSuccessed. Java alias created. Attacker SQL committed under RUNSCRIPTLab-proven
ReconROLE_ADMIN GET /api/v1/database/createDatabaseBackup then GET /api/v1/database/download/backup_202610172328.sql50432-byte backup contains STIRLING-H2-IMPORT-WITNESSLab-proven
Recon / host filesame import wrapping FILE_READ('/etc/os-release') in EXECUTE IMMEDIATE500 Backup verification failed. Host bytes not in a backupLab extra FAIL
Integrity / RCEalias org.h2.store.fs.FileUtils plus CSVWRITE of a Python user-site .pth, then office convertCommand execution as the service accountInferred from GHSA-mrr8. Not labbed here
Availabilitynone claimedImport can replace application tablesInferred. Not the lab oracle

Stays closed on this pin

AxisMethod + pathWhy it is closed
Integrityunauth POST /api/v1/database/import-database401 Authentication required. Method security ADMIN stays on when HTTP is permitAll
IntegrityROLE_ADMIN import of bare CREATE ALIAS500 SQL script contains disallowed operations and was rejected
Integritylite / DISABLE_ADDITIONAL_FEATURES imageDatabaseController absent
Integritycustom PostgreSQL datasource@Conditional(H2SQLCondition.class)

I am not claiming a reverse shell, and I am not claiming host FILE_READ as lab-proven. The leftover is the denylist miss that lets CREATE OR REPLACE ALIAS … FOR "java.lang.…" through RUNSCRIPT.

How I found it

v3.2.0 still ships the GHSA-mrr8 validator. I sat on that tag and read DENIED_PATTERNS. The alias line is CREATE\s+(FORCE\s+)?ALIAS. H2's parser accepts CREATE OR REPLACE ALIAS. Tests cover the obvious CREATE ALIAS / FILE_READ( strings. They do not cover OR REPLACE.

The lab logs in as default admin, finishes change-password-on-login, imports a denied CREATE ALIAS (500), then imports CREATE OR REPLACE ALIAS plus an INSERT witness (200). A backup download contains the witness.

Wrong turns: treating unauth import as in-scope (401); treating EXECUTE IMMEDIATE + FILE_READ as the leftover (verifyBackup 500); treating the original un-obfuscated CREATE ALIAS as still live (it is denied).

Lab

python3 stirling-h2-import-leftover-Abraxas-Labs.py

or

cd lab
./run.sh

Target only http://127.0.0.1:18152. Image stirlingtools/stirling-pdf:3.2.0-fat. Docker required. Login-on. The launcher chdirs into lab/ and execs run.sh.

IOC unauth-import http=401
IOC negative-import http=500 ... disallowed operations ...
IOC leftover-import bypass=create-or-replace-alias http=200 ... importIntoDatabaseSuccessed
IOC download file=backup_202610172328.sql http=200 bytes=50432 witness=1
SUCCESS stirling-h2-import-leftover negative-denied=yes bypass=create-or-replace-alias backup-has-witness=yes file=backup_202610172328.sql unauth-import=401 STIRLING-H2-IMPORT-WITNESS

The fix

Extend the denylist so OR REPLACE cannot sit between CREATE and ALIAS. Run validateSqlContent on the same bytes RUNSCRIPT will execute. Deny EXECUTE IMMEDIATE unless the inner SQL is also scanned.

Pattern.compile("(?i)\\bCREATE\\s+(OR\\s+REPLACE\\s+)?(FORCE\\s+)?ALIAS\\b")

Re-run the loopback client against a patched build: leftover import must 400/500 the way bare CREATE ALIAS already does.

Until then, do not treat "I banned CREATE ALIAS" as "I banned H2 Java aliases."

References

Download Tool