def IOSCWStringsSub(data): oCWStrings = naft_impf.cCiscoCWStrings(data) if oCWStrings.error != '': print(oCWStrings.error) return keys = oCWStrings.dCWStrings.keys() keys.sort() for key in keys: if key == 'CW_SYSDESCR': print('%s:' % key) print(oCWStrings.dCWStrings[key]) else: print('%s:%s%s' % (key, ' ' * (22 - len(key)), oCWStrings.dCWStrings[key]))
def IOSCWStringsSub(data): returnString = '' oCWStrings = naft_impf.cCiscoCWStrings(data) if oCWStrings.error != '': returnString += (oCWStrings.error) return keys = oCWStrings.dCWStrings.keys() keys.sort() for key in keys: if key == 'CW_SYSDESCR': returnString += ('%s:<br>' % key) returnString += (oCWStrings.dCWStrings[key] + '<br>') else: returnString += ('%s:%s%s<br>' % (key, ' ' * (22 - len(key)), oCWStrings.dCWStrings[key])) return returnString
def Parse(self): self.error = 0 self.oELF = cELF(self.data) if self.oELF.error != 0: self.error = 1 print('ELF parsing error %d.' % self.oELF.error) if self.oELF.error <= 2: print('This is not an ELF file.') elif self.oELF.error < 5: print('This is probably not an ELF file/Cisco IOS image.') return self.oSectionHeaderCompressedImage, self.oSectionHeaderEmbeddedMD5, self.oSectionHeaderCWStrings = self.ExtractSections( self.oELF) if self.oSectionHeaderEmbeddedMD5 != None: self.embeddedMD5 = self.ExtractEmbeddedMD5( self.oSectionHeaderEmbeddedMD5.sectionData) if self.oSectionHeaderCWStrings != None: self.oCWStrings = naft_impf.cCiscoCWStrings( self.oSectionHeaderCWStrings.sectionData) md5 = hashlib.md5() index = 0 for oSectionHeader in self.oELF.sections: if index != 3 and index != 4: md5.update(oSectionHeader.sectionData) index += 1 self.calculatedMD5 = md5.hexdigest() if self.oSectionHeaderCompressedImage == None: print('MAGIC number FEEDFACE not found') self.error = 4 return self.sizeUncompressed, self.sizeCompressed, self.checksumCompressed, self.checksumUncompressed = struct.unpack( '>IIII', self.oSectionHeaderCompressedImage. sectionData[len(naft_impf.cCiscoMagic.STR_FEEDFACE ):len(naft_impf.cCiscoMagic.STR_FEEDFACE) + 4 * 4]) zipData = self.oSectionHeaderCompressedImage.sectionData[ len(naft_impf.cCiscoMagic.STR_FEEDFACE) + 4 * 4:len(naft_impf.cCiscoMagic.STR_FEEDFACE) + 4 * 4 + self.sizeCompressed] self.calculatedChecksumCompressed = cIOSImage.CalcChecksum(zipData) try: oZipFile = zipfile.ZipFile(cStringIO.StringIO(zipData)) try: names = oZipFile.namelist() except: self.error = 6 print('Error retrieving ZIP namelist') oZipFile = None except: self.error = 5 print('Error parsing ZIP section') oZipFile = None if oZipFile != None: if len(names) == 0: self.error = 7 print('Error: no file found in ZIP') elif len(names) == 1: self.imageUncompressedName = names[0] else: self.error = 8 print('More than one file found in ZIP') print(','.join(names)) if self.imageUncompressedName != None: try: self.imageUncompressed = oZipFile.open( self.imageUncompressedName).read() except: self.error = 9 print('Error decompressing ZIP section') if self.imageUncompressed != None: self.calculatedChecksumUncompressed = cIOSImage.CalcChecksum( self.imageUncompressed)
def IOSCheckText(coredumpFilename, imageFilename, options): oIOSCoreDump = naft_impf.cIOSCoreDump(coredumpFilename) if oIOSCoreDump.error != '': print(oIOSCoreDump.error) return else: textAddress, textCoredump = oIOSCoreDump.RegionTEXT() if textCoredump == None: print('Error extracting text region from coredump %s' % coredumpFilename) return 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: print('Error reading image %s' % imageFilename) return 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: print('CW_SYSDESCR are identical:\n') print(sysdescrCoredump) elif sysdescrCoredump == sysdescrImage.replace('-MZ', '-M', 1): print('CW_SYSDESCR are equivalent:\n') print(sysdescrCoredump) else: print('CW_SYSDESCR are different:\n') print(sysdescrCoredump) print print(sysdescrImage) print oELF = naft_iipf.cELF(oIOSImage.imageUncompressed) if oELF.error != 0: print('ELF parsing error %d.' % oELF.error) return countSectionExecutableInstructions = 0 for oSectionHeader in oELF.sections: if oSectionHeader.flags & 4: # SHF_EXECINSTR executable instructions textSectionData = oSectionHeader.sectionData countSectionExecutableInstructions += 1 if countSectionExecutableInstructions != 1: print('Error executable sections in image: found %d sections, expected 1' % countSectionExecutableInstructions) return start = textAddress & 0xFF # to be further researched textImage = textSectionData[start:start + len(textCoredump)] if len(textCoredump) != len(textImage): print('the text region is longer than the text section') countBytesDifferent = 0 shortestLength = min(len(textCoredump), len(textImage)) for iIter in range(shortestLength): if textCoredump[iIter] != textImage[iIter]: if countBytesDifferent == 0: print('text region and section are different starting 0x%08X in coredump (iter = 0x%08X)' % ((textAddress + iIter), iIter)) countBytesDifferent += 1 if countBytesDifferent == 0: print('text region and section are identical') else: print('number of different bytes: %d (%.2f%%)' % (countBytesDifferent, (countBytesDifferent * 100.0) / shortestLength))
def Parse(self): self.error = 0 self.oELF = cELF(self.data) if self.oELF.error != 0: self.error = 1 print('ELF parsing error %d.' % self.oELF.error) if self.oELF.error <= 2: print('This is not an ELF file.') elif self.oELF.error < 5: print('This is probably not an ELF file/Cisco IOS image.') return self.oSectionHeaderCompressedImage, self.oSectionHeaderEmbeddedMD5, self.oSectionHeaderCWStrings = self.ExtractSections(self.oELF) if self.oSectionHeaderEmbeddedMD5 != None: self.embeddedMD5 = self.ExtractEmbeddedMD5(self.oSectionHeaderEmbeddedMD5.sectionData) if self.oSectionHeaderCWStrings != None: self.oCWStrings = naft_impf.cCiscoCWStrings(self.oSectionHeaderCWStrings.sectionData) md5 = hashlib.md5() index = 0 for oSectionHeader in self.oELF.sections: if index != 3 and index != 4: md5.update(oSectionHeader.sectionData) index += 1 self.calculatedMD5 = md5.hexdigest() if self.oSectionHeaderCompressedImage == None: print('MAGIC number FEEDFACE not found') self.error = 4 return self.sizeUncompressed, self.sizeCompressed, self.checksumCompressed, self.checksumUncompressed = struct.unpack('>IIII', self.oSectionHeaderCompressedImage.sectionData[len(naft_impf.cCiscoMagic.STR_FEEDFACE):len(naft_impf.cCiscoMagic.STR_FEEDFACE) + 4*4]) zipData = self.oSectionHeaderCompressedImage.sectionData[len(naft_impf.cCiscoMagic.STR_FEEDFACE) + 4*4:len(naft_impf.cCiscoMagic.STR_FEEDFACE) + 4*4 + self.sizeCompressed] self.calculatedChecksumCompressed = cIOSImage.CalcChecksum(zipData) try: oZipFile = zipfile.ZipFile(cStringIO.StringIO(zipData)) try: names = oZipFile.namelist() except: self.error = 6 print('Error retrieving ZIP namelist') oZipFile = None except: self.error = 5 print('Error parsing ZIP section') oZipFile = None if oZipFile != None: if len(names) == 0: self.error = 7 print('Error: no file found in ZIP') elif len(names) == 1: self.imageUncompressedName = names[0] else: self.error = 8 print('More than one file found in ZIP') print(','.join(names)) if self.imageUncompressedName != None: try: self.imageUncompressed = oZipFile.open(self.imageUncompressedName).read() except: self.error = 9 print('Error decompressing ZIP section') if self.imageUncompressed != None: self.calculatedChecksumUncompressed = cIOSImage.CalcChecksum(self.imageUncompressed)
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