SQLi to Remote Code Execution
SQL injection can escalate to OS command execution when the database user has FILE privilege or sysadmin rights. MySQL INTO OUTFILE writes a web shell to the web root. MSSQL xp_cmdshell executes OS commands directly from SQL. PostgreSQL COPY TO PROGRAM runs shell commands when the user is a superuser. All three require specific privilege conditions confirmed in vulnerability discovery.
- MySQL FILE privilege check confirms INTO OUTFILE is available and identifies secure_file_priv restrictions.
- MySQL web shell write drops a PHP shell to the web root via UNION SELECT INTO OUTFILE.
- MSSQL xp_cmdshell enables OS command execution directly from SQL when sysadmin rights exist.
- PostgreSQL COPY TO PROGRAM executes OS commands when the database user is a superuser.
- Privilege verification is required before any path. Low-privilege app users rarely have FILE, sysadmin, or superuser.
The MySQL path requires FILE privilege and a web directory the MySQL process can write to. The MSSQL path requires sysadmin or the ALTER SETTINGS server permission. The PostgreSQL path requires superuser role. Running these blind wastes time and may trigger detection.
MySQL: Check FILE Privilege
FILE privilege is required for INTO OUTFILE. Confirm the current user has it. The first query reads File_priv from mysql.user for the active session user. The second query checks secure_file_priv, which restricts where MySQL is allowed to write files. Run both before attempting any file write.
Y
File_priv Y and an empty secure_file_priv confirm unrestricted file write. A non-empty secure_file_priv restricts writes to that path only. If that path sits outside the web root, the shell lands but the web server cannot reach it. File_priv N means INTO OUTFILE returns an access denied error regardless of the target path. The datadir value shows where MySQL stores its own data, not the application web root. Use it to infer the server filesystem layout. Common web root paths include /var/www/html, /srv/www, and /usr/share/nginx/html. Find the web root path before writing:
/var/lib/mysql/
MySQL: Write a Web Shell
Write a PHP web shell to the web root using INTO OUTFILE. The target path must be writable by the MySQL process user. If the directory is owned by root or has restrictive permissions, the write fails with a MySQL error. Try alternate paths like /var/www/ or a world-writable uploads directory if the default root write fails. The shell only executes on PHP-backed applications. On Python, Node, or Ruby stacks, the file is served as plain text and the shell never runs.
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Command execution confirmed. The uid=33(www-data) output confirms the web server process user. This is code execution, not root access. Start privilege escalation enumeration after getting an interactive shell. If bash fails in the reverse shell, substitute sh instead. If outbound TCP is filtered, try a bind shell or interact through the web shell for file operations. Get a reverse shell:
MSSQL: Enable and Abuse xp_cmdshell
When SQLi hits MSSQL with sysadmin rights, enable xp_cmdshell through stacked queries. Stacked queries require the application driver to support query batching. PHP with PDO or ODBC supports stacking. PHP with MySQLi pointed at MSSQL rarely does. Confirm sysadmin first by injecting SELECT IS_SRVROLEMEMBER('sysadmin') into a visible column. A result of 1 confirms sysadmin. Without sysadmin, sp_configure throws a permission error and xp_cmdshell stays off. The show advanced options reconfigure step is only needed when the server has that setting at 0.
nt authority\system
The nt authority\system output means the MSSQL service runs as SYSTEM. No privilege escalation is needed from here. Drop a payload, add a local admin, or dump credentials directly. If xp_cmdshell was already enabled, skip the sp_configure steps. If xp_cmdshell is disabled and sp_configure fails due to missing permissions, try Ole Automation Procedures as an alternative execution path. Both xp_cmdshell activation and execution write to the SQL Server error log and generate Windows event entries. Expect EDR alerts on monitored hosts. On hardened targets, the sysadmin role is locked to a dedicated service account. Reaching that account requires prior credential access, making this technique unavailable without an earlier escalation step.
PostgreSQL: COPY TO PROGRAM
PostgreSQL's COPY TO PROGRAM executes OS commands when the database user is a superuser. This is the primary PostgreSQL RCE vector through SQLi and requires stacked queries. PostgreSQL supports stacked queries natively through most drivers (PDO, psycopg2, JDBC), so this path is commonly available when PostgreSQL SQLi exists. Confirm superuser status first:
SUPERUSER
With superuser confirmed, use COPY TO PROGRAM to execute commands. The output is not returned inline, so write it to a file and read it back, or go straight for a reverse shell:
uid=114(postgres) gid=120(postgres) groups=120(postgres)
Command execution confirmed as the postgres user. Get a reverse shell:
If the shell callback fails, try /bin/sh instead of bash. On older PostgreSQL versions without COPY TO PROGRAM (pre-9.3), the alternative is writing a shared library to disk via lo_export and loading it with CREATE FUNCTION, which is significantly more complex.
Oracle: Code Execution via SQLi
Oracle RCE through SQLi typically requires DBA-level privileges and Java stored procedures (CREATE JAVA SOURCE) or DBMS_SCHEDULER. Both paths are more complex than MySQL, MSSQL, or PostgreSQL vectors and require the Oracle JVM to be installed (for Java procedures) or specific scheduler grants. In practice, Oracle web application users are almost always restricted to SELECT-only grants, making RCE via SQLi rare. When you do have DBA privileges on Oracle, DBMS_SCHEDULER.CREATE_JOB with job_type => 'EXECUTABLE' is the most direct path to OS command execution.
References
-
MySQL: SELECT INTO OUTFILEDOCS: MySQL: SELECT INTO OUTFILE, dev.mysql.com/doc/refman/8.0/en/select-into.html (opens in new tab)
INTO OUTFILE syntax and secure_file_priv interaction
-
Microsoft: xp_cmdshellDOCS: Microsoft: xp_cmdshell, learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/xp-cmdshell-transact-sql (opens in new tab)
xp_cmdshell enable procedure and permission requirements
-
PostgreSQL: COPYDOCS: PostgreSQL: COPY, www.postgresql.org/docs/current/sql-copy.html (opens in new tab)
COPY TO PROGRAM syntax and superuser requirement