Exemplo n.º 1
0
def connection(exe, computer, user, userpass):
    c = Client(computer, username=user, password=userpass)
    c.connect()
    try:
        c.create_service()
        c.run_executable(exe)
    finally:
        c.cleanup()
        c.disconnect()
    return
Exemplo n.º 2
0
        c.connect()
        print("Connected.")
        try:
            c.create_service()
            print("Service created.")

            #code to start of stop the worker.
            #stdout, stderr, rc = c.run_executable("cmd.exe", arguments="/c ipconfig")
            stdout = WorkerStatus(c, "xmrig.exe")

            print("Command Output\n******")
            print(stdout)
            print("******")

        except Exception as e:
            print("Couldn't create service or execute command. ", end="")
            print(e)

    except Exception as e:
        print("Unable to connect. ", end="")
        print(e)

    finally:
        try:
            c.cleanup()
            c.disconnect()
        except:
            pass
        finally:
            print("Cleaned up: " + host + "\n\n")
Exemplo n.º 3
0
class PSExecAPI(object):
    _cache = {}  # type: Dict[PSExecAPI]

    def __init__(self, hostname, username, password):
        self.hostname = hostname
        self.username = username
        self.password = password
        self._session_id = None  # type: int or None
        self.timeout = 10
        self.__client = None  # Client or None
        self._register_at_exit()

    def __str__(self):
        return "%s%s:%s@%s" % (__name__, self.username, self.password,
                               self.hostname)

    @property
    def session_established(self):
        return self._client and hasattr(self._client, 'session')

    @staticmethod
    def _clear_all():
        PSExecAPI._cache.clear()

    @classmethod
    def get(cls, hostname, username, password):
        # noinspection PyTypeChecker
        output = PSExecAPI._cache.get((hostname, username, password))
        if output is None:
            output = cls(hostname, username, password)
        return output

    @staticmethod
    def _remove_class_cache(class_):
        _key = (class_.hostname, class_.username, class_.password)
        if _key in PSExecAPI._cache:
            # noinspection PyTypeChecker
            PSExecAPI._remove_cache(*_key)

    # noinspection PyTypeChecker
    @staticmethod
    def _remove_cache(hostname, username, password):
        key = (hostname, username, password)
        if key in PSExecAPI._cache.keys():
            # noinspection PyProtectedMember
            PSExecAPI._cache[key]._disconnect()
            PSExecAPI._cache.pop(key)

    @property
    def _client(self):
        # type: () -> Client or None
        if self.__client is None:
            self.__client = Client(self.hostname, self.username, self.password)
            _LOGGER.info(
                'Establishing PSExec connection with %s@%s with timeout %s seconds ... '
                % (self.username, self.hostname, self.timeout))
            # Remote Host Requirements: https://github.com/jborean93/pypsexec#remote-host-requirements
            # try:
            #     self.__client.connect(timeout=self.timeout)
            #     self.__client.cleanup()
            #     self.__client.disconnect()
            # except:
            #     pass

            try:
                self.__client.connect(timeout=self.timeout)
                self.__client.create_service()
            except SMBAuthenticationError as e:
                _LOGGER.error("%s Authentication Error: %s %s" %
                              (__name__, type(e), e))
                self._destroy()
                return
            except SCMRException as e:
                _LOGGER.error("%s SCMRException Exception: %s %s" %
                              (__name__, type(e), e))
            except Exception as e:
                _LOGGER.error("%s Exception: %s %s" % (__name__, type(e), e))
                self._destroy()
                return

            # noinspection PyTypeChecker
            PSExecAPI._cache[(self.hostname, self.username,
                              self.password)] = self
        return self.__client

    def _destroy(self):
        self._disconnect()
        self.__client = None
        PSExecAPI._remove_class_cache(self)

    def _cleanup(self):
        try:
            self.__client.cleanup()
        except:
            pass

    def _disconnect(self):
        if not self.__client:
            return

        try:
            self.__client.remove_service()
            self.__client.disconnect()
        except:
            pass

    def _register_at_exit(self):
        atexit.register(self._disconnect)

    def run_cmd(self,
                cmd,
                interactively=False,
                asynchronous=False,
                session_id=None,
                **kwargs):
        if interactively:
            return self.run_interactively('cmd',
                                          arguments='/c "%s"' % cmd,
                                          asynchronous=asynchronous,
                                          session_id=session_id,
                                          **kwargs)

        return self.run_executable('cmd',
                                   arguments='/c "%s"' % cmd,
                                   interactive_session=session_id,
                                   **kwargs)

    def run_executable(self, executable, **kwargs):
        _LOGGER.debug(
            "Running remote executable @ {s.username}@{s.hostname}: {exe} {kw}"
            .format(s=self, exe=executable, kw=kwargs if kwargs else ''))
        if not self._client:
            _LOGGER.warning(
                "Cannot run executable: connection not established @ %s@%s" %
                (self.username, self.hostname))
            return

        _LOGGER.info("Running executable %s" % executable)
        stdout, stderr, return_code = self._client.run_executable(
            executable, **kwargs)
        _stderr_str = 'Stderr:\n%s\n\n' % stderr.strip(
        ) if stderr and stderr.strip() else ''
        _stdout_str = 'Stdout:\n%s\n\n' % stdout.strip(
        ) if stdout and stdout.strip() else ''
        _LOGGER.debug("%s%sReturn Code: %s" %
                      (_stderr_str, _stdout_str, return_code))
        return stdout, stderr, return_code

    def run_interactively(self,
                          executable,
                          arguments=None,
                          asynchronous=False,
                          session_id=None,
                          **kwargs):
        session_id = session_id or self.session_id
        if not session_id:
            _LOGGER.warning("Cannot run %s interactively: User not logged in" %
                            executable)
            return

        kwargs.update({
            'interactive': True,
            'interactive_session': session_id,
            'asynchronous': asynchronous
        })
        if 'use_system_account' not in kwargs:
            kwargs.update({'use_system_account': True})

        _LOGGER.info("Running %s interactively" % executable)
        return self.run_executable(executable, arguments=arguments, **kwargs)

    def mirror_folder(self,
                      remote_folder,
                      local_folder,
                      multi_thread=True,
                      **kwargs):
        _multi_thread = '/MT' if multi_thread else ''
        _args = '"%s" "%s" /UNICODE /MIR %s' % (remote_folder, local_folder,
                                                _multi_thread)
        kwargs.update({'arguments': _args})
        _LOGGER.info("Mirroring folders %s and %s" %
                     (remote_folder, local_folder))
        output = self.run_executable('robocopy.exe', **kwargs)
        stdout, stderr, return_code = output if output else (None, None, None)
        return stdout, stderr, return_code

    def get_session_id(self, user=None):
        user = user or self.username
        _LOGGER.debug("Getting session ID for %s@%s" % (user, self.hostname))
        _args = '/c tasklist /NH /FI "USERNAME eq %s" /FI "IMAGENAME eq RuntimeBroker.exe"' % user
        stdout, stderr, return_code = self._client.run_executable(
            'cmd', arguments=_args, use_system_account=False)
        _LOGGER.debug("Get Session ID STDOUT: %s" % stdout)
        _LOGGER.debug("Get Session ID STDERR: %s" % stderr)
        _LOGGER.debug("Get Session ID return_code: %s" % return_code)
        if stderr and str(stderr).strip():
            _LOGGER.warning(
                "Error getting session ID for %s@%s. User is not logged in?" %
                (user, self.hostname))
            return

        if stdout and "INFO: No tasks are running which match the specified criteria." in str(
                stdout).strip():
            _LOGGER.warning(
                "Couldn't get Session ID for %s@%s. User is not logged in" %
                (user, self.hostname))
            return

        if not stdout or not str(stdout).strip():
            _LOGGER.warning(
                "Couldn't get Session ID for %s@%s. Stdout empty?\n%s" %
                (user, self.hostname, stdout))
            return

        brokers_split = str(stdout).strip().split('\n')
        if not brokers_split:
            _LOGGER.warning(
                "Couldn't get Session ID for %s@%s. Brokers list empty?\n%s" %
                (user, self.hostname, stdout))
            return

        broker = brokers_split[0].split()
        if len(broker) < 3:
            _LOGGER.warning(
                "Couldn't get Session ID for %s@%s. Broker split empty?\n%s" %
                (user, self.hostname, broker))
            return

        session_id = broker[3]
        _LOGGER.debug("Got session id: %s" % session_id)

        try:
            output = int(session_id)
        except:
            _LOGGER.warning("Error parsing session ID for %s@%s: %s" %
                            (user, self.hostname, str(stdout).strip()))
            return

        _LOGGER.info("Got session ID for %s@%s: %s" %
                     (user, self.hostname, output))
        return output

    @property
    def session_id(self):
        if self._session_id is None:
            if not self._client:
                _LOGGER.warning("Couldn't get session id: client is None")
                return

            self._session_id = self.get_session_id()
        return self._session_id

    def check_file_exists(self, file_path):
        output = self.run_executable('cmd.exe',
                                     arguments='/c where "%s"' % file_path)
        if output is None:
            return

        stdout, stderr, return_code = output
        if stderr is None or stderr.strip(
        ) or stdout is None or not stdout.strip():
            _LOGGER.warning("Couldn't check_file_exists %s " % file_path)
            return

        if "Could not find files for the given pattern" in str(stdout):
            return False

        return stdout.strip()

    def check_install_choco(self):
        choco = self.check_file_exists('choco.exe')
        if not choco:
            self.install_choco()

    def install_choco(self,
                      interactively=False,
                      asynchronous=False,
                      session_id=None):
        return self.run_cmd(
            "powershell Set-ExecutionPolicy Bypass -Scope Process -Force; "
            "iex ((New-Object System.Net.WebClient)."
            "DownloadString('https://chocolatey.org/install.ps1'))"
            "&refreshenv"
            "&choco feature enable -n=allowGlobalConfirmation -y"
            "&choco feature disable -n=ignoreInvalidOptionsSwitches -y"
            "&choco feature enable -n=usePackageExitCodes -y"
            "&choco feature disable -n=showNonElevatedWarnings -y",
            interactively=interactively,
            asynchronous=asynchronous,
            session_id=session_id)

    def install_choco_module(self, module_name):
        self.check_install_choco()
        return self.run_cmd('cinst %s' % module_name)

    def create_shortcut(self,
                        target,
                        location="~$folder.desktop$",
                        title='My Shortcut',
                        arguments='',
                        icon_path="",
                        icon_number=0,
                        run_as=""):
        """
        https://nircmd.nirsoft.net/shortcut.html
        """
        return self.run_cmd(
            'nircmd shortcut "{target}" "{location}" "{title}" "{arguments}" '
            '"{icon_path}" {icon_number} "{run_as}"'.format(
                target=target,
                location=location,
                title=title,
                arguments=arguments,
                icon_path=icon_path,
                icon_number=icon_number,
                run_as=run_as))