Пример #1
0
def CiscoIOSImageFileParser(filename, options):
    global oMD5Database

    image = naft_uf.File2Data(filename)
    if image == None:
        print('Error reading %s' % filename)
        return

    oIOSImage = naft_iipf.cIOSImage(image)
    oIOSImage.Print()

    if options.md5db:
        md5hash = hashlib.md5(image).hexdigest()
        filenameCSV, filenameDB = oMD5Database.Find(md5hash)
        if filenameCSV == None:
            print('File not found in md5 database')
        else:
            print('File found in md5 database %s %s' %
                  (filenameCSV, filenameDB))

    if options.verbose:
        for oSectionHeader in oIOSImage.oELF.sections:
            print(' %2d %-7s %d %d %08X %10d %s' %
                  (oSectionHeader.nameIndex, oSectionHeader.nameIndexString,
                   oSectionHeader.type, oSectionHeader.flags,
                   oSectionHeader.offset, oSectionHeader.size,
                   repr(oSectionHeader.sectionData[0:8])))

    if options.extract:
        naft_uf.Data2File(oIOSImage.imageUncompressed,
                          oIOSImage.imageUncompressedName)

    if options.idapro:
        naft_uf.Data2File(oIOSImage.ImageUncompressedIDAPro(),
                          oIOSImage.imageUncompressedName)
Пример #2
0
 def Parse(self):
     self.error = ''
     self.coredump = naft_uf.File2Data(self.coredumpFilename)
     if self.coredump == None:
         self.error = 'Error reading coredump %s' % self.coredumpFilename
         return
     indexRegionsMetaData = self.coredump.find(cCiscoMagic.STR_REGIONS)
     if indexRegionsMetaData < 0:
         self.error = 'Magic sequence %s not found' % binascii.b2a_hex(cCiscoMagic.STR_REGIONS).upper()
         return
     if self.coredump[indexRegionsMetaData + 4:indexRegionsMetaData + 4 + 4] != '\x00\x00\x00\x05':
         self.error = 'Unexpected data found: %s' % binascii.b2a_hex(self.coredump[indexRegionsMetaData + 4:indexRegionsMetaData + 4 + 4])
         return
     addresses = struct.unpack('>IIII', self.coredump[indexRegionsMetaData + 20:indexRegionsMetaData + 20 + 4 * 4])
     indexHeap = self.coredump.find(cCiscoMagic.STR_BLOCK_BEGIN, addresses[3] - addresses[0])
     if indexHeap < 0:
         self.error = 'Magic sequence %s not found' % binascii.b2a_hex(cCiscoMagic.STR_BLOCK_BEGIN).upper()
         return
     self.address = addresses[0]
     self.size = len(self.coredump)
     addressBegin = self.address
     addressEnd = self.address + self.size
     regionsCalculation = map(lambda x, y : (x, y), ('begin', 'text', 'data', 'bss'), addresses)
     regionsCalculation.append(('heap', addresses[0] + indexHeap))
     regionsCalculation.append(('end', addressEnd))
     indices = range(len(regionsCalculation))
     for index, value in enumerate(indices):
         address = regionsCalculation[value][1]
         if address < addressBegin or address > addressEnd:
             del indices[index]
         regionsCalculation[value] = (regionsCalculation[value][0], regionsCalculation[value][1], None, None)
     for index, value in enumerate(indices[:-1]):
         length = regionsCalculation[indices[index + 1]][1] - regionsCalculation[value][1]
         regionsCalculation[value] = (regionsCalculation[value][0], regionsCalculation[value][1], length, regionsCalculation[value][1] - addressBegin)
     self.regions = regionsCalculation[:-1]
Пример #3
0
def ExtractIPPacketsFromFile(filenamePCAP, filenamesRawData, options):
    naft_uf.LogLine('Start')
    if options.ouitxt == '':
        oFrames = naft_pfef.cFrames()
    else:
        oFrames = naft_pfef.cFrames(options.ouitxt)
    countProcessedFiles = 0

    for filenameRawData in filenamesRawData:
        if options.buffer:
            naft_uf.LogLine('Buffering file %s' % filenameRawData)
            oBufferFile = naft_uf.cBufferFile(filenameRawData, options.buffersize * 1024 * 1024, options.bufferoverlapsize * 1024 * 1024)
            while oBufferFile.Read():
                naft_uf.LogLine('Processing buffer 0x%x size %d MB %d%%' % (oBufferFile.index, len(oBufferFile.buffer) / 1024 / 1024, oBufferFile.Progress()))
                naft_uf.LogLine('Searching for IPv4 packets')
                naft_pfef.ExtractIPPackets(oFrames, oBufferFile.index, oBufferFile.buffer, options.options, options.duplicates, True, filenameRawData)
                naft_uf.LogLine('Searching for ARP Ethernet frames')
                naft_pfef.ExtractARPFrames(oFrames, oBufferFile.index, oBufferFile.buffer, options.duplicates, True, filenameRawData)
            if oBufferFile.error == MemoryError:
                naft_uf.LogLine('Data is too large to fit in memory, use smaller buffer')
            elif oBufferFile.error:
                naft_uf.LogLine('Error reading file')
            countProcessedFiles += 1
        else:
            naft_uf.LogLine('Reading file %s' % filenameRawData)
            rawData = naft_uf.File2Data(filenameRawData)
            if rawData == None:
                naft_uf.LogLine('Error reading file')
            if rawData == MemoryError:
                naft_uf.LogLine('File is too large to fit in memory')
            else:
                naft_uf.LogLine('Searching for IPv4 packets')
                naft_pfef.ExtractIPPackets(oFrames, 0, rawData, options.options, options.duplicates, True, filenameRawData)
                naft_uf.LogLine('Searching for ARP Ethernet frames')
                naft_pfef.ExtractARPFrames(oFrames, 0, rawData, options.duplicates, True, filenameRawData)
                countProcessedFiles += 1

    if countProcessedFiles > 0:
        naft_uf.LogLine('Writing PCAP file %s' % filenamePCAP)
        if not oFrames.WritePCAP(filenamePCAP):
            naft_uf.LogLine('Error writing PCAP file')

        naft_uf.LogLine('Number of identified frames:   %5d' % oFrames.countFrames)
        naft_uf.LogLine('Number of identified packets:  %5d' % oFrames.countPackets)
        naft_uf.LogLine('Number of frames in PCAP file: %5d' % len(oFrames.frames))

        if options.template:
            naft_uf.LogLine('Writing 010 template file %s' % options.template)
            if not oFrames.Write010Template(options.template):
                naft_uf.LogLine('Error writing 010 template file')

    naft_uf.LogLine('Done')
Пример #4
0
def IOSCWStrings(coredumpFilename, options):
    if options.raw:
        coredump = naft_uf.File2Data(coredumpFilename)
        if coredump == None:
            print('Error reading file %s' % coredumpFilename)
        else:
            IOSCWStringsSub(coredump)
    else:
        oIOSCoreDump = naft_impf.cIOSCoreDump(coredumpFilename)
        if oIOSCoreDump.error != '':
            print(oIOSCoreDump.error)
            return
        addressData, memoryData = oIOSCoreDump.RegionDATA()
        if memoryData == None:
            print('Data region not found')
            return
        IOSCWStringsSub(memoryData)
Пример #5
0
def IOSFrames(coredumpFilename, filenameIOMEM, filenamePCAP, options):
    oIOSCoreDump = naft_impf.cIOSCoreDump(coredumpFilename)
    if oIOSCoreDump.error != '':
        print(oIOSCoreDump.error)
        return
    addressHeap, memoryHeap = oIOSCoreDump.RegionHEAP()
    if memoryHeap == None:
        print('Heap region not found')
        return
    oIOSMemoryParserHeap = naft_impf.cIOSMemoryParser(memoryHeap)
    oIOSMemoryParserHeap.ResolveNames(oIOSCoreDump)
    dataIOMEM = naft_uf.File2Data(filenameIOMEM)
    oIOSMemoryParserIOMEM = naft_impf.cIOSMemoryParser(dataIOMEM)
    addressIOMEM = oIOSMemoryParserIOMEM.baseAddress
    if addressIOMEM == None:
        print('Error parsing IOMEM')
        return
    oFrames = naft_pfef.cFrames()
    print(naft_impf.cIOSMemoryBlockHeader.ShowHeader)
    for oIOSMemoryBlockHeader in oIOSMemoryParserHeap.Headers:
        if oIOSMemoryBlockHeader.AllocNameResolved == '*Packet Header*':
            frameAddress = struct.unpack(
                '>I',
                oIOSMemoryBlockHeader.GetData()[40:44])[0]
            frameSize = struct.unpack(
                '>H',
                oIOSMemoryBlockHeader.GetData()[72:74])[0]
            if frameSize <= 1:
                frameSize = struct.unpack(
                    '>H',
                    oIOSMemoryBlockHeader.GetData()[68:70])[0]
            if frameAddress != 0 and frameSize != 0:
                print(oIOSMemoryBlockHeader.ShowLine())
                naft_uf.DumpBytes(
                    dataIOMEM[frameAddress - addressIOMEM:frameAddress -
                              addressIOMEM + frameSize], frameAddress)
                oFrames.AddFrame(
                    frameAddress - addressIOMEM,
                    dataIOMEM[frameAddress - addressIOMEM:frameAddress -
                              addressIOMEM + frameSize], True)
    oFrames.WritePCAP(filenamePCAP)
Пример #6
0
def IOSCheckText(coredumpFilename, imageFilename, options):
    returnString = ''
    oIOSCoreDump = naft_impf.cIOSCoreDump(coredumpFilename)
    if oIOSCoreDump.error != '':
        returnString += (oIOSCoreDump.error) + '<br>'
        return returnString
    else:
        textAddress, textCoredump = oIOSCoreDump.RegionTEXT()
        if textCoredump == None:
            returnString += (
                'Error extracting text region from coredump %s<br>' %
                coredumpFilename)
            return returnString
        sysdescrCoredump = ''
        dataAddress, dataCoredump = oIOSCoreDump.RegionDATA()
        if dataCoredump != None:
            oCWStrings = naft_impf.cCiscoCWStrings(dataCoredump)
            if oCWStrings.error == '' and 'CW_SYSDESCR' in oCWStrings.dCWStrings:
                sysdescrCoredump = oCWStrings.dCWStrings['CW_SYSDESCR']

    image = naft_uf.File2Data(imageFilename)
    if image == None:
        returnString += ('Error reading image %s' % imageFilename)
        return returnString

    oIOSImage = naft_iipf.cIOSImage(image)
    if oIOSImage.error != 0:
        return
    sysdescrImage = ''
    if oIOSImage.oCWStrings != None and oIOSImage.oCWStrings.error == '' and 'CW_SYSDESCR' in oIOSImage.oCWStrings.dCWStrings:
        sysdescrImage = oIOSImage.oCWStrings.dCWStrings['CW_SYSDESCR']
    if sysdescrCoredump != '' or sysdescrImage != '':
        if sysdescrCoredump == sysdescrImage:
            returnString += ('CW_SYSDESCR are identical:<br>')
            returnString += (sysdescrCoredump) + '<br>'
        elif sysdescrCoredump == sysdescrImage.replace('-MZ', '-M', 1):
            returnString += ('CW_SYSDESCR are equivalent:<br>')
            returnString += (sysdescrCoredump) + '<br>'
        else:
            returnString += ('CW_SYSDESCR are different:<br>')
            returnString += (sysdescrCoredump) + '<br>'
            returnString += '<br>'
            returnString += (sysdescrImage) + '<br>'
        returnString += '<br>'

    oELF = naft_iipf.cELF(oIOSImage.imageUncompressed)
    if oELF.error != 0:
        returnString += ('ELF parsing error %d.' % oELF.error)
        return returnString
    countSectionExecutableInstructions = 0
    countSectionSRELOC = 0
    for oSectionHeader in oELF.sections:
        if oSectionHeader.flags & 4:  # SHF_EXECINSTR executable instructions
            textSectionData = oSectionHeader.sectionData
            countSectionExecutableInstructions += 1
        if oSectionHeader.nameIndexString == 'sreloc':
            countSectionSRELOC += 1
    if countSectionExecutableInstructions != 1:
        returnString += (
            'Error executable sections in image: found %d sections, expected 1'
            % countSectionExecutableInstructions)
        return returnString
    if countSectionSRELOC != 0:
        returnString += (
            'Error found %d sreloc section in image: checktext command does not support relocation'
            % countSectionSRELOC)
        return returnString
    start = textAddress & 0xFF  # to be further researched
    textImage = textSectionData[start:start + len(textCoredump)]
    if len(textCoredump) != len(textImage):
        returnString += ('the text region is longer than the text section<br>')
        returnString += ('len(textCoredump) = %d<br>' % len(textCoredump))
        returnString += ('len(textImage) = %d<br>' % len(textImage))
    countBytesDifferent = 0
    shortestLength = min(len(textCoredump), len(textImage))
    for iIter in range(shortestLength):
        if textCoredump[iIter] != textImage[iIter]:
            if countBytesDifferent == 0:
                returnString += (
                    'text region and section are different starting 0x%08X in coredump (iter = 0x%08X)<br>'
                    % ((textAddress + iIter), iIter))
            countBytesDifferent += 1
    if countBytesDifferent == 0:
        returnString += ('text region and section are identical <br>')
    else:
        returnString += ('number of different bytes: %d (%.2f%%)<br>' %
                         (countBytesDifferent,
                          (countBytesDifferent * 100.0) / shortestLength))

    return returnString
Пример #7
0
def CiscoIOSImageFileScanner(filewildcard, options):
    if options.resume == None:
        filenames = GlobFilelist(filewildcard, options)
        countFilenames = len(filenames)
        counter = 1
        if options.log != None:
            f = open(options.log, 'w')
            f.close()
    else:
        fPickle = open(options.resume, 'rb')
        filenames, countFilenames, counter = pickle.load(fPickle)
        fPickle.close()
        print('Pickle file loaded')

    while len(filenames) > 0:
        filename = filenames[0]
        try:
            line = [str(counter), str(countFilenames), filename]
            image = naft_uf.File2Data(filename)
            if image == None:
                line.extend(['Error reading'])
            else:
                oIOSImage = naft_iipf.cIOSImage(image)
                if oIOSImage.oCWStrings != None and oIOSImage.oCWStrings.error == '':
                    line.extend([
                        naft_uf.cn(
                            vn(oIOSImage.oCWStrings.dCWStrings, 'CW_VERSION')),
                        naft_uf.cn(
                            vn(oIOSImage.oCWStrings.dCWStrings, 'CW_FAMILY'))
                    ])
                else:
                    line.extend([naft_uf.cn(None), naft_uf.cn(None)])
                line.extend([
                    str(len(image)),
                    '%.2f' % Entropy(image),
                    str(oIOSImage.error),
                    str(oIOSImage.oELF.error),
                    str(oIOSImage.oELF.countSections),
                    str(naft_uf.cn(oIOSImage.oELF.stringTableIndex)),
                    naft_uf.cn(oIOSImage.checksumCompressed, '0x%08X'),
                    str(oIOSImage.checksumCompressed != None
                        and oIOSImage.checksumCompressed
                        == oIOSImage.calculatedChecksumCompressed),
                    naft_uf.cn(oIOSImage.checksumUncompressed, '0x%08X'),
                    str(oIOSImage.checksumUncompressed != None
                        and oIOSImage.checksumUncompressed
                        == oIOSImage.calculatedChecksumUncompressed),
                    naft_uf.cn(oIOSImage.imageUncompressedName),
                    naft_uf.cn(oIOSImage.embeddedMD5)
                ])
                if options.md5db:
                    md5hash = hashlib.md5(image).hexdigest()
                    filenameCSV, filenameDB = oMD5Database.Find(md5hash)
                    line.extend([
                        md5hash,
                        naft_uf.cn(filenameCSV),
                        naft_uf.cn(filenameDB)
                    ])
            strLine = ';'.join(line)
            print(strLine)
            if options.log != None:
                f = open(options.log, 'a')
                f.write(strLine + '\n')
                f.close()
            counter += 1
            filenames = filenames[1:]
        except KeyboardInterrupt:
            print('KeyboardInterrupt')
            PickleData([filenames, countFilenames, counter])
            return
        except:
            traceback.print_exc()
            PickleData([filenames, countFilenames, counter])
            return