Before getting into cybersecurity, I was a software developer for many years. Although I had heard about security vulnerabilities introduced to software via poor coding practices, I, like many of my colleagues, did not take security all that seriously. Hacking seemed like an arcane art, only mastered by those willing to spend years pouring over dusty tomes of x86 assembly language manuals and protocol RFCs. It did not occur to us that many of the vulnerabilities could be exploited by anyone with basic web development coding skills and the willingness to spend a few hours on research.
One of these mysterious incantations was the dreaded “SQL Injection” attack. What exactly could one do with a SQL Injection attack, anyway? No one was quite sure, but since our software was going into a secure military installation, we were pretty sure that the perimeter defenses would prevent anyone from harming it.
SQL Injection is a vulnerability that is introduced when software developers do not check data entered by users for validity and suitability to purpose. A malicious user can enter unexpected special characters to modify the structure of a SQL query. This can happen when the developer pastes together pieces of a query with “unsanitized” user input. The unsanitized input contains special characters that modify the structure of the query before it is passed to the query parser.
For example, consider a query in a PHP snippet that tests whether a user entering credentials at a login page is a valid user in the database:
$username = $_GET[‘username’];
$password = $_GET[‘password’];
$sql = “select USER_ID from USERS where USERNAME=’$username’ and PASSWORD=’$password’;”;
In this example, the variables username and password are retrieved from the HTTP POST that was submitted by the user. The strings are taken as-is and inserted, via string interpolation, into the query string. Since no validation is done on the input, the user can enter characters that will modify the structure of the query. For example, if the user enters ‘ or 1=1; # for the username, and nothing for the password, the variable sql will now equal:
$sql = “select USER_ID from USERS where USERNAME=’’ or 1=1; #’ and PASSWORD=’$password’;”
In the MySQL database engine, the “#” sign is a comment, so everything that comes after it is ignored in the query. There are no users with a blank username, but the condition “1=1” is always true, so the query will always succeed, returning all user IDs in the database. The subsequent code will likely only check that at least one record was returned, and it will likely grab just the first ID, which in most cases, will be that of the administrative user.
Doing SQL injection manually requires a fair bit of knowledge of how SQL works. On top of that, there are many different SQL engines, each with slight variations in syntax, such as PostgreSQL, MySQL, Microsoft SQL Server, Oracle, IBM DB2, and others. SQL Injection “cheat sheets” can help pentesters figure out the required syntax for testing a web application, but SQL Injection is still a very time-consuming attack to carry out.
Enter sqlmap. sqlmap is a program that automates tests for SQL Injection. Not only does it work with many different SQL engines, when used against vulnerable applications, it can:
-
Determine the schema of the database: database, table, and column names
-
Dump data from tables
-
Potentially upload or download files to the database server machine
-
Perform out-of-band tests
-
Dump usernames, password hashes, privileges, and roles
-
Pass hashes off to a password cracker for a dictionary attack
-
Perform “Blind” and “Boolean-based” SQL injection attacks, when the web application does not return error messages (this is probably sqlmap’s best time-saving feature. Performing these attacks by hand is almost completely untenable)
-
Potentially even launch a remote shell on the database server
Let’s perform a demo attack against the Mutillidae intentionally-vulnerable web application as it is hosted on the OWASP Broken Web Application virtual machine. We will launch an attack against Mutillidae’s login page.
Multillidae Login Page
sqlmap has many command line parameters, but we are going to set up the attack the easy way. The first thing we must do is to set FireFox’s proxy to run through Burp Community Edition running on localhost on port 8080. Then, we are going to enter a bogus login and password, such as admin / canary. We capture the request in Burp before it goes to the server, as shown below.
Capturing the HTTP POST Request for the Mutillidae Login (Bottom Pane)
Copying the POST request from the bottom pane, we save the request to a text file. In this case, the file is called mutillidae-req.txt, as shown below.
Saving the POST request
We can then run sqlmap using the text file by passing it with the “-r” command line parameter. We also pass “-p username” to give it the name of the parameter we would like to attack.
sqlmap -r mutillidae-req.txt -p username
The first command will do some enumeration of the database to tell us that the database engine is MySQL 5.0 or above.
sqlmap Running
Database Identified as MySQL
Once we have the database engine, we can run sqlmap again, telling it what the engine is, so it does not have to guess again. Also, we will ask sqlmap to get a list of databases on the server by using the following command:
sqlmap -r mutillidae-req.txt -p username --dbms mysql --dbs
Enumerating the Databases on the Database Server
Looking at the results, we notice that there is a database called wordpress that we would like to attack. The WordPress blogging platform can be abused to allow an attacker to install malicious PHP code, as long as the attacker has the administrative credentials. Running sqlmap again, we ask it to enumerate the tables in the wordpress database using the following command:
sqlmap -r mutillide-req.txt -p username --dbms mysql -D wordpress --tables
Below, we can see the results of the WordPress database’s table enumeration.
WordPress Database Table Enumeration
The most interesting table appears to be the wp_users table. We will ask sqlmap to dump the contents of the table with the following command:
sqlmap -r mutillidae-req.txt -p username --dbms mysql -D wordpress -T wp_users --dump
sqlmap Dumps the wp_user Table
sqlmap runs, and as a bonus, it asks us if we want to save credentials that we have found, and if we would like to attempt to crack any password hashes with a dictionary attack. Why YES, please DO! :D
sqlmap Asks if We’d Like to Crack Passwords
When we take the defaults, sqlmap runs a dictionary attack with its default dictionary of about 1.4 million passwords. We could also have chosen our own dictionary. In short order, sqlmap recovers passwords for two WordPress users: admin (daniel1984) and user (zealot777).
sqlmap Cracks the WordPress Passwords
Once we have the admin password, we login to the WordPress admin page using the credentials admin / daniel1984.
Logging in to the WordPress Admin Page
Logged in to the WordPress Admin Page
Once logged in as admin, we can modify the searchform.php page for the default theme, as shown in the screenshots below.
Editing the searchform.php File in the WordPress Default Theme
We replace the searchform.php code with that of the excellent b374k Web Shell.
searchform.php Page Code Replaced by Malicious b374k Web Shell Code
Once we have replaced the searchform.php code with the web shell code, we can simply browse to the searchform.php file directly with the following URL:
http://192.168.115.128/wordpress/wp-content/themes/default/searchform.php
The b374k web shell page is displayed, and we login with the password provided when we created the b374k PHP file.
Logging in to the b374k Web Shell
Once logged in, we are presented with the File Explorer page. We can browse to any page that the web server has permissions to read, and we can inspect its contents.
b374K Web Shell File Explorer
Here, we view the /etc/passwd file.
Using B374k to View the /etc/passwd File
We can do many other things with b374k, such as create a remote shell from the victim web server back to our attacking computer, as shown in the following screenshot:
Using b374k to Create a Remote Shell
As you can see, sqlmap is an incredibly useful tool to demonstrate to web developers and project managers alike that SQL Injection is indeed a serious vulnerability, one that deserves their full attention. SQL Injection can lead to complete system compromise. I am often told after a demo of sqlmap that it is “the scariest thing you have shown us yet”.
Learn more about sqlmap and other hacking tools in one of our Penetration Testing Courses.
Doc Sewell in Dandong, China, across the Yalu River from Shinuiju, North Korea
Author Bio
Daniel "Doc" Sewell is CTO and Trainer for Alpine Security. He currently holds many security-related certifications, including EC-Council Certified Security Analyst (ECSA), Licensed Penetration Tester (Master), Offensive Security Certified Professional (OSCP), Certified Information Systems Security Professional (CISSP) and Certified Secure Software Lifecycle Professional (CSSLP). Doc has many years of experience in software development, working on web interfaces, database applications, thick-client GUIs, battlefield simulation software, automated aircraft scheduling systems, embedded systems, and multi-threaded CPU and GPU applications. Doc's cybersecurity experience includes penetration testing a fighter jet embedded system, penetration testing medical lab devices, creating phishing emails and fake web sites for social engineering engagements, and teaching security courses to world-renowned organizations such as Lockheed Martin and the Hong Kong Police Department. Doc's hobbies and interests include home networking, operating systems, computer gaming, reading, movie watching, and traveling.
No comments:
Post a Comment