Exemplo n.º 1
0
 def findWritableShare(self, shares):
     # Check we can write a file on the shares, stop in the first one
     writeableShare = None
     for i in shares['Buffer']:
         if i['shi1_type'] == srvs.STYPE_DISKTREE or i[
                 'shi1_type'] == srvs.STYPE_SPECIAL:
             share = i['shi1_netname'][:-1]
             tid = 0
             try:
                 tid = self.connection.connectTree(share)
                 self.connection.openFile(
                     tid,
                     '\\',
                     FILE_WRITE_DATA,
                     creationOption=FILE_DIRECTORY_FILE)
             except:
                 LOG.critical("share '%s' is not writable." % share)
                 pass
             else:
                 LOG.info('Found writable share %s' % share)
                 writeableShare = str(share)
                 break
             finally:
                 if tid != 0:
                     self.connection.disconnectTree(tid)
     return writeableShare
Exemplo n.º 2
0
 def copy_file(self, src, tree, dst):
     LOG.info("Uploading file %s" % dst)
     if isinstance(src, str):
         # We have a filename
         fh = open(src, 'rb')
     else:
         # We have a class instance, it must have a read method
         fh = src
     f = dst
     pathname = string.replace(f, '/', '\\')
     try:
         self.connection.putFile(tree, pathname, fh.read)
     except:
         LOG.critical("Error uploading file %s, aborting....." % dst)
         raise
     fh.close()
Exemplo n.º 3
0
 def uninstall(self):
     fileCopied = True
     serviceCreated = True
     # Do the stuff here
     try:
         # Let's get the shares
         svcManager = self.openSvcManager()
         if svcManager != 0:
             resp = scmr.hROpenServiceW(self.rpcsvc, svcManager,
                                        self.__service_name + '\x00')
             service = resp['lpServiceHandle']
             LOG.info('Stopping service %s.....' % self.__service_name)
             try:
                 scmr.hRControlService(self.rpcsvc, service,
                                       scmr.SERVICE_CONTROL_STOP)
             except:
                 pass
             LOG.info('Removing service %s.....' % self.__service_name)
             scmr.hRDeleteService(self.rpcsvc, service)
             scmr.hRCloseServiceHandle(self.rpcsvc, service)
             scmr.hRCloseServiceHandle(self.rpcsvc, svcManager)
         LOG.info('Removing file %s.....' % self.__binary_service_name)
         self.connection.deleteFile(self.share, self.__binary_service_name)
     except Exception:
         LOG.critical("Error performing the uninstallation, cleaning up")
         try:
             scmr.hRControlService(self.rpcsvc, service,
                                   scmr.SERVICE_CONTROL_STOP)
         except:
             pass
         if fileCopied is True:
             try:
                 self.connection.deleteFile(self.share,
                                            self.__binary_service_name)
             except:
                 try:
                     self.connection.deleteFile(self.share,
                                                self.__binary_service_name)
                 except:
                     pass
                 pass
         if serviceCreated is True:
             try:
                 scmr.hRDeleteService(self.rpcsvc, service)
             except:
                 pass
Exemplo n.º 4
0
class TargetsProcessor:
    def __init__(self,
                 targetListFile=None,
                 singleTarget=None,
                 protocolClients=None):
        # Here we store the attacks that already finished, mostly the ones that have usernames, since the
        # other ones will never finish.
        self.finishedAttacks = []
        self.protocolClients = protocolClients
        if targetListFile is None:
            self.filename = None
            self.originalTargets = self.processTarget(singleTarget,
                                                      protocolClients)
        else:
            self.filename = targetListFile
            self.originalTargets = []
            self.readTargets()

        self.candidates = [x for x in self.originalTargets]

    @staticmethod
    def processTarget(target, protocolClients):
        # Check if we have a single target, with no URI form
        if target.find('://') <= 0:
            # Target is a single IP, assuming it's SMB.
            return [urlparse('smb://%s' % target)]

        # Checks if it needs to expand the list if there's a all://*
        retVals = []
        if target[:3].upper() == 'ALL':
            strippedTarget = target[3:]
            for protocol in protocolClients:
                retVals.append(urlparse('%s%s' % (protocol, strippedTarget)))
            return retVals
        else:
            return [urlparse(target)]

    def readTargets(self):
        try:
            with open(self.filename, 'r') as f:
                self.originalTargets = []
                for line in f:
                    target = line.strip()
                    if target != '':
                        self.originalTargets.extend(
                            self.processTarget(target, self.protocolClients))
        except IOError, e:
            LOG.error("Could not open file: %s - " % (self.filename, str(e)))

        if len(self.originalTargets) == 0:
            LOG.critical("Warning: no valid targets specified!")

        self.candidates = [
            x for x in self.originalTargets if x not in self.finishedAttacks
        ]
Exemplo n.º 5
0
    def __compareHash(self, magic, hashData, key):
        if magic == 'lf':
            hashRec = REG_HASH(hashData)
            if hashRec['KeyName'].strip('\x00') == key[:4]:
                return hashRec['OffsetNk']
        elif magic == 'lh':
            hashRec = REG_HASH(hashData)
            if unpack('<L', hashRec['KeyName'])[0] == self.__getLhHash(key):
                return hashRec['OffsetNk']
        elif magic == 'ri':
            # Special case here, don't know exactly why, an ri pointing to a NK :-o
            offset = unpack('<L', hashData[:4])[0]
            nk = self.__getBlock(offset)
            if nk['KeyName'] == key:
                return offset
        else:
            LOG.critical("UNKNOWN Magic %s" % magic)
            sys.exit(1)

        return None
Exemplo n.º 6
0
    def getShares(self):
        # Setup up a DCE SMBTransport with the connection already in place
        LOG.info("Requesting shares on %s....." %
                 (self.connection.getRemoteHost()))
        try:
            self._rpctransport = transport.SMBTransport(
                self.connection.getRemoteHost(),
                self.connection.getRemoteHost(),
                filename=r'\srvsvc',
                smb_connection=self.connection)
            dce_srvs = self._rpctransport.get_dce_rpc()
            dce_srvs.connect()

            dce_srvs.bind(srvs.MSRPC_UUID_SRVS)
            resp = srvs.hNetrShareEnum(dce_srvs, 1)
            return resp['InfoStruct']['ShareInfo']['Level1']
        except:
            LOG.critical("Error requesting shares on %s, aborting....." %
                         (self.connection.getRemoteHost()))
            raise
Exemplo n.º 7
0
 def openSvcManager(self):
     LOG.info("Opening SVCManager on %s....." %
              self.connection.getRemoteHost())
     # Setup up a DCE SMBTransport with the connection already in place
     self._rpctransport = transport.SMBTransport(
         self.connection.getRemoteHost(),
         self.connection.getRemoteHost(),
         filename=r'\svcctl',
         smb_connection=self.connection)
     self.rpcsvc = self._rpctransport.get_dce_rpc()
     self.rpcsvc.connect()
     self.rpcsvc.bind(scmr.MSRPC_UUID_SCMR)
     try:
         resp = scmr.hROpenSCManagerW(self.rpcsvc)
     except:
         LOG.critical("Error opening SVCManager on %s....." %
                      self.connection.getRemoteHost())
         raise Exception('Unable to open SVCManager')
     else:
         return resp['lpScHandle']
Exemplo n.º 8
0
from nebulousAD.modimpacket import LOG, hresult_errors
from nebulousAD.modimpacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantArray, NDRUNION, NDR, NDRENUM
from nebulousAD.modimpacket.dcerpc.v5.dtypes import PUUID, DWORD, NULL, GUID, LPWSTR, BOOL, ULONG, UUID, LONGLONG, ULARGE_INTEGER, LARGE_INTEGER
from nebulousAD.modimpacket import system_errors
from nebulousAD.modimpacket.structure import Structure
from nebulousAD.modimpacket.uuid import uuidtup_to_bin, string_to_bin
from nebulousAD.modimpacket.dcerpc.v5.enum import Enum
from nebulousAD.modimpacket.dcerpc.v5.rpcrt import DCERPCException
from nebulousAD.modimpacket.krb5 import crypto
from pyasn1.type import univ
from pyasn1.codec.ber import decoder

try:
    from Cryptodome.Cipher import ARC4, DES
except Exception:
    LOG.critical(
        "Warning: You don't have any crypto installed. You need pycryptodomex")
    LOG.critical("See https://pypi.org/project/pycryptodomex/")

MSRPC_UUID_DRSUAPI = uuidtup_to_bin(
    ('E3514235-4B06-11D1-AB04-00C04FC2DCD2', '4.0'))


class DCERPCSessionError(DCERPCException):
    def __init__(self, error_string=None, error_code=None, packet=None):
        DCERPCException.__init__(self, error_string, error_code, packet)

    def __str__(self):
        key = self.error_code
        if hresult_errors.ERROR_MESSAGES.has_key(key):
            error_msg_short = hresult_errors.ERROR_MESSAGES[key][0]
            error_msg_verbose = hresult_errors.ERROR_MESSAGES[key][1]
Exemplo n.º 9
0
    def negotiateSession(
            self,
            preferredDialect=None,
            flags1=smb.SMB.FLAGS1_PATHCASELESS
        | smb.SMB.FLAGS1_CANONICALIZED_PATHS,
            flags2=smb.SMB.FLAGS2_EXTENDED_SECURITY | smb.SMB.FLAGS2_NT_STATUS
        | smb.SMB.FLAGS2_LONG_NAMES,
            negoData='\x02NT LM 0.12\x00\x02SMB 2.002\x00\x02SMB 2.???\x00'):
        """
        Perform protocol negotiation

        :param string preferredDialect: the dialect desired to talk with the target server. If None is specified the highest one available will be used
        :param string flags1: the SMB FLAGS capabilities
        :param string flags2: the SMB FLAGS2 capabilities
        :param string negoData: data to be sent as part of the nego handshake

        :return: True, raises a Session Error if error.
        """

        # If port 445 and the name sent is *SMBSERVER we're setting the name to the IP. This is to help some old
        # applications still believing
        # *SMSBSERVER will work against modern OSes. If port is NETBIOS_SESSION_PORT the user better know about i
        # *SMBSERVER's limitations
        if self._sess_port == nmb.SMB_SESSION_PORT and self._remoteName == '*SMBSERVER':
            self._remoteName = self._remoteHost
        elif self._sess_port == nmb.NETBIOS_SESSION_PORT and self._remoteName == '*SMBSERVER':
            # If remote name is *SMBSERVER let's try to query its name.. if can't be guessed, continue and hope for the best
            nb = nmb.NetBIOS()
            try:
                res = nb.getnetbiosname(self._remoteHost)
            except:
                pass
            else:
                self._remoteName = res

        hostType = nmb.TYPE_SERVER
        if preferredDialect is None:
            # If no preferredDialect sent, we try the highest available one.
            packet = self.negotiateSessionWildcard(self._myName,
                                                   self._remoteName,
                                                   self._remoteHost,
                                                   self._sess_port,
                                                   self._timeout,
                                                   True,
                                                   flags1=flags1,
                                                   flags2=flags2,
                                                   data=negoData)
            if packet[0] == '\xfe':
                # Answer is SMB2 packet
                self._SMBConnection = smb3.SMB3(
                    self._remoteName,
                    self._remoteHost,
                    self._myName,
                    hostType,
                    self._sess_port,
                    self._timeout,
                    session=self._nmbSession,
                    negSessionResponse=SMB2Packet(packet))
            else:
                # Answer is SMB packet, sticking to SMBv1
                self._SMBConnection = smb.SMB(self._remoteName,
                                              self._remoteHost,
                                              self._myName,
                                              hostType,
                                              self._sess_port,
                                              self._timeout,
                                              session=self._nmbSession,
                                              negPacket=packet)
        else:
            if preferredDialect == smb.SMB_DIALECT:
                self._SMBConnection = smb.SMB(self._remoteName,
                                              self._remoteHost, self._myName,
                                              hostType, self._sess_port,
                                              self._timeout)
            elif preferredDialect in [
                    SMB2_DIALECT_002, SMB2_DIALECT_21, SMB2_DIALECT_30
            ]:
                self._SMBConnection = smb3.SMB3(
                    self._remoteName,
                    self._remoteHost,
                    self._myName,
                    hostType,
                    self._sess_port,
                    self._timeout,
                    preferredDialect=preferredDialect)
            else:
                LOG.critical("Unknown dialect %s", preferredDialect)
                raise

        # propagate flags to the smb sub-object, except for Unicode (if server supports)
        # does not affect smb3 objects
        if isinstance(self._SMBConnection, smb.SMB):
            if self._SMBConnection.get_flags()[1] & smb.SMB.FLAGS2_UNICODE:
                flags2 |= smb.SMB.FLAGS2_UNICODE
            self._SMBConnection.set_flags(flags1=flags1, flags2=flags2)

        return True
Exemplo n.º 10
0
from binascii import unhexlify

from pyasn1.codec.ber import encoder, decoder
from pyasn1.error import SubstrateUnderrunError
from pyasn1.type.univ import noValue

from nebulousAD.modimpacket import LOG
from nebulousAD.modimpacket.ldap.ldapasn1 import *
from nebulousAD.modimpacket.ntlm import getNTLMSSPType1, getNTLMSSPType3
from nebulousAD.modimpacket.spnego import SPNEGO_NegTokenInit, TypesMech

try:
    import OpenSSL
    from OpenSSL import SSL, crypto
except:
    LOG.critical("pyOpenSSL is not installed, can't continue")
    raise

__all__ = [
    'LDAPConnection',
    'LDAPFilterSyntaxError',
    'LDAPFilterInvalidException',
    'LDAPSessionError',
    'LDAPSearchError',
    'Control',
    'SimplePagedResultsControl',
    'ResultCode',
    'Scope',
    'DerefAliases',
    'Operation',
    'CONTROL_PAGEDRESULTS',
Exemplo n.º 11
0
 def install(self):
     if self.connection.isGuestSession():
         LOG.critical("Authenticated as Guest. Aborting")
         self.connection.logoff()
         del self.connection
     else:
         fileCopied = False
         serviceCreated = False
         # Do the stuff here
         try:
             # Let's get the shares
             shares = self.getShares()
             self.share = self.findWritableShare(shares)
             if self.share is None:
                 return False
             self.copy_file(self.__exeFile, self.share,
                            self.__binary_service_name)
             fileCopied = True
             svcManager = self.openSvcManager()
             if svcManager != 0:
                 serverName = self.connection.getServerName()
                 if self.share.lower() == 'admin$':
                     path = '%systemroot%'
                 else:
                     if serverName != '':
                         path = '\\\\%s\\%s' % (serverName, self.share)
                     else:
                         path = '\\\\127.0.0.1\\' + self.share
                 service = self.createService(svcManager, self.share, path)
                 serviceCreated = True
                 if service != 0:
                     # Start service
                     LOG.info('Starting service %s.....' %
                              self.__service_name)
                     try:
                         scmr.hRStartServiceW(self.rpcsvc, service)
                     except:
                         pass
                     scmr.hRCloseServiceHandle(self.rpcsvc, service)
                 scmr.hRCloseServiceHandle(self.rpcsvc, svcManager)
                 return True
         except Exception, e:
             LOG.critical(
                 "Error performing the installation, cleaning up: %s" % e)
             try:
                 scmr.hRControlService(self.rpcsvc, service,
                                       scmr.SERVICE_CONTROL_STOP)
             except:
                 pass
             if fileCopied is True:
                 try:
                     self.connection.deleteFile(self.share,
                                                self.__binary_service_name)
                 except:
                     pass
             if serviceCreated is True:
                 try:
                     scmr.hRDeleteService(self.rpcsvc, service)
                 except:
                     pass
         return False
Exemplo n.º 12
0
            # It exists, remove it
            scmr.hRDeleteService(self.rpcsvc, resp['lpServiceHandle'])
            scmr.hRCloseServiceHandle(self.rpcsvc, resp['lpServiceHandle'])

        # Create the service
        command = '%s\\%s' % (path, self.__binary_service_name)
        try:
            resp = scmr.hRCreateServiceW(self.rpcsvc,
                                         handle,
                                         self.__service_name + '\x00',
                                         self.__service_name + '\x00',
                                         lpBinaryPathName=command + '\x00',
                                         dwStartType=scmr.SERVICE_DEMAND_START)
        except:
            LOG.critical(
                "Error creating service %s on %s" %
                (self.__service_name, self.connection.getRemoteHost()))
            raise
        else:
            return resp['lpServiceHandle']

    def openSvcManager(self):
        LOG.info("Opening SVCManager on %s....." %
                 self.connection.getRemoteHost())
        # Setup up a DCE SMBTransport with the connection already in place
        self._rpctransport = transport.SMBTransport(
            self.connection.getRemoteHost(),
            self.connection.getRemoteHost(),
            filename=r'\svcctl',
            smb_connection=self.connection)
        self.rpcsvc = self._rpctransport.get_dce_rpc()