Wordpress SQL Injection, Making Wordprss vulnerable to SQLi (Capgemini Tech Challenge 2020)
Tags: Capgemini, Penetration Testing, Sql Injection, WordPress, Bug Bounty

Note: ORACLE specific SQL injections are at bottom.(Ctrl + F and search for “ORACLE”)

Hi, I have recently participated in a Penetration testing hackathon. This one is my proposed solution for the question given below, In short we first add the vulnerable SQLi code and then exploited that :(:

Question:

Assume you have been hired to test the security of a WordPress website: victimblog.com. You do not have access to the victimblog.com source code. Nevertheless, WordPress is a popular and well documented PHP-based Content Management System (CMS), which also allows inexperienced users to have blogs or personal websites. WordPress allows you to create different levels of privileges for users, including administrator privileges (e.g., to add or remove articles), and regular user privileges (e.g., to just post user comments in the blog).

You notice that there is a “Search” input textbox, which allows you to search for articles in

victimblog.com. Upon inspection, you notice that the search terms are passed to the server via an HTTP GET parameter named “search”.

Write an SQL injection (SQLi) which allows you to view all the information of the registered users. Specify also how could you identify the WordPress table names. Also, write at least two preconditions for a successful SQLi in the search bar.

At first I thought I had to find a SQLi in wordpress. So I just downloaded latest wordpress and started looking for SQLi but then I realized

I was trying to find a SQLi in latest wordpress which could get me a CVE if I succeeded, but then after reading question properly 4–5 times. What I understood was, here we need to recreate the given scenario:

Proposed Solution:

First I will be showing the steps to setup LAMP stack and installing latest WordPress 5.5.2 . I have used docker to host LAMP stack and directory of wordpress app is mapped to a directory on container using -v or –volume, this option allows us to mount a directory of host OS on the container.

1. Running docker container

docker run -p “80:80” -v ${PWD}/app:/app mattrayner/lamp:latest-1804 (PWD in my case is /root/Desktop/app)

(Here docker image will be first downloaded if it does not already exist, you can check downloaded images by docker image ls . You can find more details regarding versions of LAMP here https://hub.docker.com/r/mattrayner/lamp .

Here I got:

Apache: 2.4.29

MYSQL: 5.7.26

PHP: 7.3.6

phpMyAdmin: 4.9.0.1)

Fig. 1 Running docker continer

2. Installing wordpress :(Wordpress has some prerequisites i.e LAMP stack that’s why I did that in my last step)

a. Download the latest wordpress zip to /root/Desktop/app.

Wget https://wordpress.org/latest.zip

b. Setting up database named “wpdb” via phpMyAdmin.

i. First we need to know credentials for MySQL which can be seen when we started the container.

admin:hUrFylBqRXD1

ii. Finding IP address of container(optional step: this is required if there is no mapping of 80:80 i.e port 80 on host OS is maaped to port 80 of container.)

Finding Container ID via docker container ls (Fig.3) then retrieving IP address via docker container inspect — format ‘{{.NetworkSettings.IPAddress}}’ <container id> (Fig.4)

Fig. 3 Finding Container Id

Fig.4 Finding IP address of container

iii. Then we login to phpMyAdmin using these to create new database for wordpress.(Fig. )

Fig.5 Creating new database

c. Installing Wordpress:

i. Creating a admin account. (Fig.6 and Fig.7)

Fig. 6

Fig.7

3. Making it vulnerable to SQLi

Now according to given scenario there is a “search field” for searching articles which is vulnerable to SQLi. So we need to either edit a existing theme or create a new theme from scratch. I have edited the existing “twentytwenty” theme. Steps are as follows:

(Make sure you are logged in wp-admin console with admin creds you have created in previous step)

a. Editing theme

Copy paste this link (“http://127.0.0.1/wp-admin/theme-editor.php?file=index.php&theme=twentytwenty") directly to be able to edit “/index.php” Location of this on drive is “/root/Desktop/app/wp-content/themes/twentytwenty/index.php” we can edit directly edit here also.

Mysql php code:

<?php $dbhostname='1.2.3.4';

$dbuser='username';

$dbpasswords='password';

$dbname='database'; $connection=mysqli_connect($dbhostname, $dbuser, $dbpassword, $dbname);

$query="Select Name, Description FROM Products WHERE ID='3' UNION SELECT Username,Password FROM Accounts;"; $results=mysqli_query($connection, $query);

display_results($results); ?>

$search= $_GET[‘search’]; //print_r(“Param s=”.$s.” “); $conn = mysqli_connect(‘localhost’, ‘admin’, ‘3gtTP6AdK2TW’, ‘wpdb’); if (!$result = mysqli_query($conn, “select * from wp_posts where id=$search”)) { echo(“Error description: “ . $conn -> error); } else { $result = mysqli_query($conn, “select * from wp_posts where id=$search”); //echo “Returned rows are: “ . $result -> num_rows; $jsonArray = array(); while($row = $result->fetch_assoc()) { $jsonArray[]= $row; } echo json_encode($jsonArray); }

Fig.8 Theme editor

b. Add vulnerable code

Now we need to add vulnerable code which will parse our GET parameter named search and then gets incorporated in our SQL query as it is without any sanitization or escaping

c. Adding Search box

Till now we have made changes in our backend. Now we need to make changes in frontend to add HTML form for our vulnerable search field.

i. For this I have used “Customize widgets option” available in appearance option and added form in Footer#1.

Fig. 9 Adding Widgets

ii. Then added my custom html form here (Fig.10 )

<html> <body> <h3>Search articles</h3> <form action=”/index.php” method=”get” target=”_blank”> <label for=”fname”>Search box:</label> <input type=”text” id=”fname” name=”search”><br><br> <input type=”submit” value=”Submit”> </form> </body> </html>

Fig.10 Custom HTML

Fig. 11 Checking the HTML form

4. Now we are ready to exploit our SQL injection.

(Note: This might be hard to explain but I am trying my best. I am showing exploitation of UNION based SQLi)

a. Step 1- Finding injection point:

i. ‘

ii. “

iii. \ (output of this shows that in backend query looks something like this: select <something> from <something> where <something>=search_parameter and <something>; . In short this means parameter is being added as it(like id=1) not as (id=”1”) or (id=’1’) )

Fig. 12 Finding injection point

b. Step 2- Balancing or fixing the query.

Query used: http://127.0.0.1/?search=1%20%20--+ (From last step we know backend query is something like this id=1)

i. 1--+ (passing this fixed our query)

Fig .13 Balancing the query

c. Step-3- Finding number of columns.

There are two methods for finding no of columns which I am aware of 1. ORDER BY <no_of_columns> and 2. ‘ UNION SELECT NULL — . Here in this case I have used order by method. Till column 23 I was able to retrieve the results of query. By increasing it to 24 and more, I started getting error, telling no of columns in the current table are indeed 23. So now I can move to next step of fetching table values.

i. http://127.0.0.1/?search=1+order+by+23--+

Fig.14 Finding No of columns

ii. http://127.0.0.1/?search=1+order+by+24--+

Fig. 15 Got error meaning 23 columns were there.

d. Step 4-Findings name of table and name of columns containing relevant info :

Now we can proceed to fetch information from table but for this we need to know table structure i.e what type of information is there and from which table we need to fetch the information. As an attacker by doing some enumeration using online tools like builtwith.com(Note: this will not work as web app is locally hosted.) or using extension like wappalyzer we can find that this is wordpress site.

Fig. 16

With this information we can look for database structure used by wordpress and as wordpress is well documented it is a piece of cake to get it just by a google search. I have found this here https://codex.wordpress.org/Database_Description

Now according to Question we need to find information of registered users. By referring to database documentation attacker can find this info is stored in table named wp_users also in docs info related to columns and information they contains is explained very well this helped a lot in creating my query. https://codex.wordpress.org/Database_Description#Table:_wp_users

e. Step 5- Constructing the query and fetching information:

For this we need to know how UNION works in sql. You can refer to this https://www.w3schools.com/sql/sql_union.asp

Main points for using UNION are:

i. Each SELECT statement within UNION must have the same number of columns.

ii. The columns must also have similar data types.

iii. The columns in each SELECT statement must also be in the same order.

Keeping these in mind I have created this query:

Fig 17.

This is the solution of first question of Scenario 2. Lets solve second one which is to identify table names in wordpress.

f. Identifying table names:

For this also we can simply refer to wordpress documentation or use the query given below:

information_schema is a standard database which can be used to fetch meta data. It is an ANSI-standard set of read-only views that provide information about all of the tables, views, columns, and procedures in a database.

g. Preconditions of SQLi in searchbox:

i. User input must be passed as it to the backend SQL query, means there should not be any input validation, sql escaping, filtering etc.

ii. No security plugins like Sucuri(https://wordpress.org/plugins/sucuri-scanner/) or WAF(Web application firewall Note: It can be bypassed but having this is good practice) should be installed.

Thank you for reading!