In modern DBMSes, writing to files in the back-end server is more restricted.
Write File Privileges
Let’s first check whether we have right to write file
.
To be able to write files in MySQL, we need three things:
- User with
FILE
privilege enabled - MySQL global
secure_file_priv
variable disabled - Write access to the location we want to write to on the back-end server
secure_file_priv
secure_file_priv
is used to determine where to read/write files from.
- Empty means we can read files from the entire file system.
- If a directory is set inside
secure_file_priv
, we can only read from specified folder. - NULL means we can’t read/write from any directory.
MariaDB - variable set as empty by default.
MySQL - /var/lib/mysql-files
is set as the default folder.
Modern SQLs - default set as NULL
.
Let’s check out the value of secure_file_priv
:
To use it with UNION
:
Another example:
SELECT INTO OUTFILE
Now let’s assume we have confirmed that our user can write files to the back-end server.
SELECT INTO OUTFILE
can be used to write data from select queries into files.
e.g - save the out of the users
table into /tmp/credentials
:
e.g - write arbitrary files to the back-end server:
Write Files through SQLi
Let’s try writing a file to the webroot:
With UNION
injection it should look like such:
Now if we go to http://server:port/proof.txt
, we will see the message file written successfully!
.
Web Shell
Let’s write a PHP web shell to the webroot folder.
We can write the following PHP webshell:
With UNION
injection, it should look like this:
Now we can execute commands as such:
http://server:port/shell.php?0=whoami