diff --git a/monkey/infection_monkey/post_breach/actions/add_user.py b/monkey/infection_monkey/post_breach/actions/add_user.py index b217196d3..9354ca417 100644 --- a/monkey/infection_monkey/post_breach/actions/add_user.py +++ b/monkey/infection_monkey/post_breach/actions/add_user.py @@ -27,7 +27,7 @@ class BackdoorUser(PBA): @staticmethod def get_commands_to_add_user(username, password): linux_cmds = BackdoorUser.get_linux_commands_to_add_user(username) - windows_cmds = BackdoorUser.get_windows_commands_to_add_user(password, username) + windows_cmds = BackdoorUser.get_windows_commands_to_add_user(username, password) return linux_cmds, windows_cmds @staticmethod @@ -45,12 +45,13 @@ class BackdoorUser(PBA): return linux_cmds @staticmethod - def get_windows_commands_to_add_user(password, username): + def get_windows_commands_to_add_user(username, password, should_be_active=False): windows_cmds = [ 'net', 'user', username, password, - '/add', - '/ACTIVE:NO'] + '/add'] + if not should_be_active: + windows_cmds.append('/ACTIVE:NO') return windows_cmds diff --git a/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py b/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py index 63daa614c..ba1620180 100644 --- a/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py +++ b/monkey/infection_monkey/post_breach/actions/communicate_as_new_user.py @@ -1,3 +1,4 @@ +import logging import os import random import string @@ -15,7 +16,9 @@ from infection_monkey.telemetry.post_breach_telem import PostBreachTelem from infection_monkey.utils import is_windows_os USERNAME = "somenewuser" -PASSWORD = "N3WPa55W0rD!@12" +PASSWORD = "N3WPa55W0rD!1" + +logger = logging.getLogger(__name__) class CommunicateAsNewUser(PBA): @@ -33,50 +36,50 @@ class CommunicateAsNewUser(PBA): if not self.try_to_create_user_windows(username, PASSWORD): return # no point to continue if failed creating the user. - # Logon as new user: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-logonusera - new_user_logon_token_handle = win32security.LogonUser( - username, - ".", # current domain - PASSWORD, - win32con.LOGON32_LOGON_BATCH, # logon type - win32con.LOGON32_PROVIDER_DEFAULT) # logon provider - - if new_user_logon_token_handle == 0: + try: + # Logon as new user: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-logonusera + new_user_logon_token_handle = win32security.LogonUser( + username, + ".", # use current domain + PASSWORD, + win32con.LOGON32_LOGON_INTERACTIVE, # logon type - interactive (normal user) + win32con.LOGON32_PROVIDER_DEFAULT) # logon provider + except Exception as e: PostBreachTelem( self, - ("Can't logon as {} Last error: {}".format(username, win32api.GetLastError()), False) + ("Can't logon as {}. Error: {}".format(username, e.message), False) ).send() return # no point to continue if can't log on. # Using os.path is OK, as this is on windows for sure ping_app_path = os.path.join(os.environ["WINDIR"], "system32", "PING.exe") if not os.path.exists(ping_app_path): - PostBreachTelem(self, ("{} not found".format(ping_app_path), False)).send() + PostBreachTelem(self, ("{} not found.".format(ping_app_path), False)).send() return # Can't continue without ping. - # Open process as that user: - # https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasusera - return_value_create_process = win32process.CreateProcessAsUser( - new_user_logon_token_handle, # A handle to the primary token that represents a user. - # If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName specifies the module - # to execute, and *lpCommandLine specifies the command line. - ping_app_path, # The name of the module to be executed. - "google.com", # The command line to be executed. - None, # Process attributes - None, # Thread attributes - True, # Should inherit handles - win32con.NORMAL_PRIORITY_CLASS, # The priority class and the creation of the process. - None, # An environment block for the new process. If this parameter is NULL, the new process - # uses the environment of the calling process. - None, # CWD. If this parameter is NULL, the new process will have the same current drive and - # directory as the calling process. - win32process.STARTUPINFO() # STARTUPINFO structure. - # https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa - ) - - if return_value_create_process == 0: + try: + # Open process as that user: + # https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasusera + return_value_create_process = win32process.CreateProcessAsUser( + new_user_logon_token_handle, # A handle to the primary token that represents a user. + # If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName specifies the module + # to execute, and *lpCommandLine specifies the command line. + ping_app_path, # The name of the module to be executed. + "google.com", # The command line to be executed. + None, # Process attributes + None, # Thread attributes + True, # Should inherit handles + win32con.NORMAL_PRIORITY_CLASS, # The priority class and the creation of the process. + None, # An environment block for the new process. If this parameter is NULL, the new process + # uses the environment of the calling process. + None, # CWD. If this parameter is NULL, the new process will have the same current drive and + # directory as the calling process. + win32process.STARTUPINFO() # STARTUPINFO structure. + # https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-startupinfoa + ) + except Exception as e: PostBreachTelem(self, ( - "Failed to open process as user. Last error: {}".format(win32api.GetLastError()), False)).send() + "Failed to open process as user {}. Error: {}".format(username, e.message), False)).send() return else: try: @@ -89,7 +92,8 @@ class CommunicateAsNewUser(PBA): def try_to_create_user_windows(self, username, password): try: - windows_cmds = BackdoorUser.get_windows_commands_to_add_user(username, password) + windows_cmds = BackdoorUser.get_windows_commands_to_add_user(username, password, True) + logger.debug("Trying these commands: {}".format(str(windows_cmds))) subprocess.check_output(windows_cmds, stderr=subprocess.STDOUT, shell=True) return True except subprocess.CalledProcessError as e: