def __init__(self, binary):
     self.cLine = littleEndian.readShort(binary, 2)
     self.dxMin = littleEndian.readShort(binary, 4)
     self.str = XLUnicodeString(binary[6:])
     self.sizeInBytes = 6 + self.str.sizeInBytes
     if self.str.sizeInBytes % 2 != 0:
         self.sizeInBytes += 1
 def __init__(self, binary):
     self.ptg = ord(binary[0])
     if self.ptg != 0x02:
         print 'Error parsing a PtgTbl-structure'
         return None
     col = littleEndian.readShort(binary,1)
     row = littleEndian.readShort(binary,3)
 def __init__(self, binary):
     self.ft = littleEndian.readShort(binary, 0)
     cbFmla = littleEndian.readShort(binary, 2)
     if self.ft != 0x0004 or cbFmla % 2 != 0:
         self.ft = 0xFFFF
     self.fmla = binary[2:4+cbFmla]
     self.sizeInBytes = 4+cbFmla
 def __init__(self, binary):
     binary = binary[4:]
     self.vers =  littleEndian.readShort(binary, 0)
     self.dt =  littleEndian.readShort(binary, 2)
     self.rupBuild =  littleEndian.readShort(binary, 4)
     self.rupYear =  littleEndian.readShort(binary, 6)
     self.bitmap = (littleEndian.readInt(binary, 8)) & int('11111111111111111110000000000000',2)
     self.verLowestBiff = binary[12]
     self.bitmap2 = ord(binary[13]) & int('11110000',2)
 def __init__(self, binary):
     self.ft = littleEndian.readShort(binary, 0)
     self.cb = littleEndian.readShort(binary, 2)
     if self.ft != 0x0009:
         #print 'Error parsing a FtPictFmla-structure'
         return None
     self.fmla = ObjFmla(binary[4:])
     self.IposInCtlStm = littleEndian.readInt(binary, 6+self.fmla.cbFmla)
     self.cbBufInCtlStm = littleEndian.readInt(binary, 10+self.fmla.cbFmla)
Ejemplo n.º 6
0
def findExternalOleObjectStorageLocation(current_user_stream,
                                         ppt_document_stream):
    try:
        currentUserAtom = ppt_atom(current_user_stream)
        currentUserAtom.size = littleEndian.readInt(currentUserAtom.binaryData,
                                                    0)
        currentUserAtom.headerToken = currentUserAtom.binaryData[4:8]
        currentUserAtom.offsetToCurrentEdit = littleEndian.readInt(
            currentUserAtom.binaryData, 8)
    except:
        #print 'failed to parse currentUserAtom, file might be corrupted!'
        return None

    if len(ppt_document_stream[currentUserAtom.offsetToCurrentEdit:]) <= 0:
        #print 'end of stream?'
        return None

    #print [ppt_document_stream[currentUserAtom.offsetToCurrentEdit:]]

    userEditAtom = ppt_atom(
        ppt_document_stream[currentUserAtom.offsetToCurrentEdit:])
    userEditAtom.lastSlieIdRef = userEditAtom.binaryData[0:4]
    userEditAtom.version = littleEndian.readShort(userEditAtom.binaryData, 4)
    userEditAtom.minorVersion = userEditAtom.binaryData[6]
    userEditAtom.majorVersion = userEditAtom.binaryData[7]
    userEditAtom.offsetLastEdit = littleEndian.readInt(userEditAtom.binaryData,
                                                       8)
    userEditAtom.offestPersistDirectory = littleEndian.readInt(
        userEditAtom.binaryData, 12)

    if len(ppt_document_stream[userEditAtom.offestPersistDirectory:]) <= 0:
        #print 'end of stream'
        return None

    persistDirectoryAtom = ppt_atom(
        ppt_document_stream[userEditAtom.offestPersistDirectory:])
    persistId16bits = littleEndian.readShort(persistDirectoryAtom.binaryData,
                                             0)
    persistId4bits = (ord(persistDirectoryAtom.binaryData[2])
                      & 0b00001111) << (8 * 2)
    persistDirectoryAtom.persistId = persistId4bits + persistId16bits
    persistDirectoryAtom.cPersist = ((ord(persistDirectoryAtom.binaryData[2]) & 0b11110000) >> 4) +\
    (ord(persistDirectoryAtom.binaryData[3]) << 8)
    rgPersistOffset = [None] * persistDirectoryAtom.cPersist
    for PersistOffsetEntry in range(0, persistDirectoryAtom.cPersist):
        rgPersistOffset[PersistOffsetEntry] = littleEndian.readInt(
            persistDirectoryAtom.binaryData, 4 + PersistOffsetEntry * 4)

    persistDirectoryAtom.rgPersistOffset = rgPersistOffset

    externalOleObjectStorages = []
    for entry in rgPersistOffset:
        potentialExtOleObjectStg = ppt_atom(ppt_document_stream[entry:])
        if potentialExtOleObjectStg.head.recType == 0x1011:
            externalOleObjectStorages += [entry]
    return externalOleObjectStorages
 def __init__(self, binary):
     self.ft = littleEndian.readShort(binary, 0)
     self.cb = littleEndian.readShort(binary, 2)
     self.unused1 = littleEndian.readInt(binary, 4)
     self.iVal = littleEndian.readSignedShort(binary, 8)
     self.iMin = littleEndian.readSignedShort(binary, 10)
     self.iMax = littleEndian.readSignedShort(binary, 12)
     self.dInc = littleEndian.readSignedShort(binary, 14)
     self.dPage = littleEndian.readSignedShort(binary, 16)
     self.fHoriz = littleEndian.readShort(binary, 18)
     self.dxScroll = littleEndian.readSignedShort(binary, 20)
     self.flags = (ord(binary[22]) & 0xf0) >> 4
     self.unused2 = (ord(binary[22]) & 0x0f) << 8
     self.unused2 += ord(binary[23])
 def __init__(self, binary):
     if len(binary) != 22:
         print 'length doesn\'t match the length of a regular FtCmo structure'
         return
     self.ft = littleEndian.readShort(binary, 0)
     self.cb = littleEndian.readShort(binary, 2)
     self.ot = littleEndian.readShort(binary, 4)
     self.id = littleEndian.readShort(binary, 6)
     self.bitmap = littleEndian.readShort(binary, 8)
     self.unused8 = littleEndian.readInt(binary, 10)
     self.unused9 = littleEndian.readInt(binary, 14)
     self.unused10 = littleEndian.readInt(binary, 18)
     if self.ft != 0x15 or self.cb != 0x12:
         print 'Error parsing a FtCmo-structure'
         return None
 def __init__(self, binary):
     self.cbFmla = littleEndian.readShort(binary, 0)
     if self.cbFmla > 0 and self.cbFmla % 2 == 0:
         self.fmla = ObjectParsedFormula(binary[2:])
         if self.fmla.rgce.ptg == 0x02:
             #create embeded info-structure
             self.embededInfo = PictFmlaEmbededInfo(binary[8+self.fmla.cce:])
             pass
Ejemplo n.º 10
0
def findExternalOleObjectStorageLocation(current_user_stream, ppt_document_stream):
    try:
        currentUserAtom = ppt_atom(current_user_stream)
        currentUserAtom.size = littleEndian.readInt(currentUserAtom.binaryData, 0)
        currentUserAtom.headerToken = currentUserAtom.binaryData[4:8]
        currentUserAtom.offsetToCurrentEdit = littleEndian.readInt(currentUserAtom.binaryData, 8)
    except:
        #print 'failed to parse currentUserAtom, file might be corrupted!'
        return None

    if len(ppt_document_stream[currentUserAtom.offsetToCurrentEdit:])<=0:
        #print 'end of stream?'
        return None

    #print [ppt_document_stream[currentUserAtom.offsetToCurrentEdit:]]

    userEditAtom = ppt_atom(ppt_document_stream[currentUserAtom.offsetToCurrentEdit:])
    userEditAtom.lastSlieIdRef = userEditAtom.binaryData[0:4]
    userEditAtom.version = littleEndian.readShort(userEditAtom.binaryData, 4)
    userEditAtom.minorVersion = userEditAtom.binaryData[6]
    userEditAtom.majorVersion = userEditAtom.binaryData[7]
    userEditAtom.offsetLastEdit = littleEndian.readInt(userEditAtom.binaryData, 8)
    userEditAtom.offestPersistDirectory = littleEndian.readInt(userEditAtom.binaryData, 12)

    if len(ppt_document_stream[userEditAtom.offestPersistDirectory:])<=0:
        #print 'end of stream'
        return None

    persistDirectoryAtom = ppt_atom(ppt_document_stream[userEditAtom.offestPersistDirectory:])
    persistId16bits = littleEndian.readShort(persistDirectoryAtom.binaryData, 0)
    persistId4bits = (ord(persistDirectoryAtom.binaryData[2]) & 0b00001111) << (8*2)
    persistDirectoryAtom.persistId = persistId4bits + persistId16bits
    persistDirectoryAtom.cPersist = ((ord(persistDirectoryAtom.binaryData[2]) & 0b11110000) >> 4) +\
    (ord(persistDirectoryAtom.binaryData[3]) << 8)
    rgPersistOffset = [None]*persistDirectoryAtom.cPersist
    for PersistOffsetEntry in range(0, persistDirectoryAtom.cPersist):
        rgPersistOffset[PersistOffsetEntry] = littleEndian.readInt(persistDirectoryAtom.binaryData, 4+PersistOffsetEntry*4)

    persistDirectoryAtom.rgPersistOffset = rgPersistOffset

    externalOleObjectStorages = []
    for entry in rgPersistOffset:
        potentialExtOleObjectStg = ppt_atom(ppt_document_stream[entry:])
        if potentialExtOleObjectStg.head.recType == 0x1011:
            externalOleObjectStorages += [entry]
    return externalOleObjectStorages
Ejemplo n.º 11
0
 def __init__(self, binary):
     self.sizeInBytes = 0
     self.cch = littleEndian.readShort(binary, 0)
     self.fHighByte = ord(binary[2])
     if self.fHighByte > 0x00:
         self.rgb = binary[3:3+(self.cch*2)]
         self.sizeInBytes = 3 + (self.cch * 2)
     else:
         self.rgb = binary[3:(3+self.cch)]
         self.sizeInBytes = 3 + self.cch
Ejemplo n.º 12
0
 def __init__(self, binary):
     self.ft = littleEndian.readShort(binary, 0)
     self.cb = littleEndian.readShort(binary, 2)
     self.ivtEdit = littleEndian.readShort(binary, 4)
     self.fMultiLine = littleEndian.readShort(binary, 6)
     self.fScroll = littleEndian.readShort(binary, 8)
     self.id = littleEndian.readShort(binary, 10)
Ejemplo n.º 13
0
    def __init__(self, binary, cmo_ot):
        self.dropData = None
        self.ft = littleEndian.readShort(binary, 0)
        self.cbFContinued = littleEndian.readShort(binary, 2)
        self.sizeInBytes = 4
        if self.cbFContinued != 0x0000:
            self.fmla = ObjFmla(binary[4:])
            firstByteOfCLines = self.fmla.cbFmla + 2 + 4
            self.cLines = littleEndian.readShort(binary, firstByteOfCLines)
            self.iSel = littleEndian.readShort(binary, firstByteOfCLines + 2)
            ########################
            self.flags = ord(binary[firstByteOfCLines + 4])
            self.lct = littleEndian.readShort(binary, firstByteOfCLines + 5)
            ########################
            #excel documentation is wrong about the combination of flags+lct (MS-XLS p. 717)
            #documentation says, that those two are combined into 2 bytes of data
            #in reality its 1 byte for flags and 2 bytes for lct
            self.idEdit = littleEndian.readShort(binary, firstByteOfCLines + 7)
            firstByteOfDropData = firstByteOfCLines + 9
            firstByteOfRgLines = firstByteOfCLines + 9

            if cmo_ot == 0x0014:
                self.dropData = LbsDropData(binary[firstByteOfDropData:])
                firstByteOfRgLines += self.dropData.sizeInBytes
                self.sizeInBytes = firstByteOfRgLines
            if self.flags & 0b01000000 == 0b01000000:
                self.rgLines = []
                offset = 0
                for element in range(0, self.cLines):
                    self.rgLines += [XLUnicodeString(binary[firstByteOfRgLines+offset:])]
                    if self.rgLines[-1].fHighByte != 0x00:
                        offset += (self.rgLines[-1].cch * 2) + 3
                    else:
                        offset += self.rgLines[-1].cch + 3
                firstByteOfBsels = firstByteOfRgLines + offset
                self.sizeInBytes = firstByteOfBsels
            if self.flags & 0b00001100 != 0x00:
                self.bsels = binary[firstByteOfBsels:firstByteOfBsels + self.cLines]
Ejemplo n.º 14
0
 def __init__(self, binary):
     self.ft = littleEndian.readShort(binary, 0)
     self.cb = littleEndian.readShort(binary, 2)
     self.cf = littleEndian.readShort(binary, 4)
Ejemplo n.º 15
0
 def getCompressedChunkLength(self, blob):
     chunkLength = littleEndian.readShort(blob, 0)
     chunkLength = chunkLength & 0x0fff
     return chunkLength + 3
Ejemplo n.º 16
0
 def __init__(self, binary):
     binary = binary[4:]
     self.bitmap = littleEndian.readShort(binary, 0)
Ejemplo n.º 17
0
    def extractMacroCode(self):
        foundMacroCode = False
        fileName = self.fileName
        #prefix will vary by OLE or XML mode
        prefix = ''
        if self.mode == 0:
            if not os.path.exists(fileName + self.docType + '/vbaProject.bin'):
                print 'found no macro-code'
                return
            assert OleFileIO_PL.isOleFile(fileName + self.docType + '/vbaProject.bin')

            ole = OleFileIO_PL.OleFileIO(fileName + self.docType + '/vbaProject.bin')
            prefix = 'VBA/'
            oleFileList = [ole]

        else:
            assert OleFileIO_PL.isOleFile(fileName)

            ole = OleFileIO_PL.OleFileIO(fileName)
            oleFileList = [ole]
            if self.docType == '/xl':
                prefix = '_VBA_PROJECT_CUR/VBA/'
            elif self.docType == '/word':
                prefix = 'Macros/VBA/'
            elif self.docType == '/ppt':
                prefix = 'VBA/'
                print 'extracting VBA-Storage...'
                current_user_stream = ole.openstream('Current User').read()
                document_stream = ole.openstream('PowerPoint Document').read()
                ppt_structures = imp.load_source('ppt_structures', 'modules/OLE_parsing/ppt_structures.py')

                folderName = os.path.abspath(self.fileName.split('.')[0])
                if not os.path.exists(folderName):
                    os.makedirs(folderName)
                externalOleObjectStorages = ppt_structures.findExternalOleObjectStorageLocation(current_user_stream, document_stream)
                if externalOleObjectStorages != None:
                    decompressedStorageFiles = ppt_structures.decompressExternalOleObjectStorage(folderName, document_stream, externalOleObjectStorages)
                    ole.close()
                    oleFileList = []
                    for externalOleObjectStorage in decompressedStorageFiles:
                        openOleFile = OleFileIO_PL.OleFileIO(externalOleObjectStorage)
                        oleFileList += [openOleFile]


        for ole in oleFileList:

            if ole.exists(prefix+'dir'):
                    dir = ole.openstream(prefix+'dir')
                    content = dir.read()
                    dir.close()

            else:
                ole.close()
                continue

            moduleOffsetRecordIdentifier = '\x31\x00\x04\x00\x00\x00'
            moduleNameRecordIdentifier = '\x19\x00'

            decompressedDir = ''
            dirSequences = []

            dirSequences = macroDecoder.getSequences(content[1:])

            #decode dir-stream in order to find metadata about the macro streams
            for sequence in dirSequences:
                decompressedDir = macroDecoder.decodeSequence(decompressedDir, sequence)

            #find all Module Offset Records
            current = 0
            listModuleOffsetRecords = []
            while decompressedDir.find(moduleOffsetRecordIdentifier, current) != -1:
                foundAt = decompressedDir.find(moduleOffsetRecordIdentifier, current)
                listModuleOffsetRecords.append(foundAt)
                current = foundAt+1


            #find the name of the modules/streams corresponding to the found Module Offsets
            listModuleNames = []
            start = 0
            for count in range(0,len(listModuleOffsetRecords)):
                moduleName = ''
                index = decompressedDir.rfind(moduleNameRecordIdentifier, start, listModuleOffsetRecords[count])
                nameLength = ord(decompressedDir[index+5]) << 24
                nameLength += ord(decompressedDir[index+4]) << 16
                nameLength += ord(decompressedDir[index+3]) << 8
                nameLength += ord(decompressedDir[index+2])
                for nameCharacter in range(0,nameLength):
                    moduleName += decompressedDir[index + 6 + nameCharacter]
                listModuleNames.append(moduleName)
                start = listModuleOffsetRecords[count]


            #find the Offsets in the Module Streams, where the textual reprensentation of the macrocode starts
            listCodeOffsets = []
            for offsets in listModuleOffsetRecords:
                codeOffset = ord(decompressedDir[offsets+9]) << 24
                codeOffset += ord(decompressedDir[offsets+8]) << 16
                codeOffset += ord(decompressedDir[offsets+7]) << 8
                codeOffset += ord(decompressedDir[offsets+6])

                listCodeOffsets.append(codeOffset)


            listEncodedMacroCode = []
            current = 0
            for moduleName in listModuleNames:
                codeBuffer = ''
                path = prefix + moduleName

                if ole.exists(path):
                    print 'decoding module:', moduleName
                    oleStream = ole.openstream(path)
                    codeBuffer = oleStream.read()
                else:
                    print path, 'does\'t exist'

                codeBuffer = codeBuffer[listCodeOffsets[current]+1:]
                chunkList = []
                #find all chunks, which follow after each other
                #0x00 will be at the end of the last chunk
                while len(codeBuffer) > 0 and codeBuffer[0] != 0x00:
                    chunkLength = littleEndian.readShort(codeBuffer, 0)
                    chunkLength = (chunkLength & 0x0fff) + 3
                    currentChunk = codeBuffer[:chunkLength]
                    codeBuffer = codeBuffer[chunkLength:]
                    listEncodedMacroCode.append(currentChunk)

                    current += 1
                oleStream.close()

            folderName = self.fileName

            if self.mode == 1:
                #OLE case
                folderName = os.path.abspath(self.fileName.split('.')[0])
                if not os.path.exists(folderName):
                    os.makedirs(folderName)


            decodedMacroCode = open(os.path.abspath(folderName + '/macroCode.txt'), 'a')
            codeSequences = []
            for encodedSequences in listEncodedMacroCode:
                codeSequences = macroDecoder.getSequences(encodedSequences)


                decompressedMacroCode = ''
                for sequence in codeSequences:

                    decompressedMacroCode = macroDecoder.decodeSequence(decompressedMacroCode, sequence)
                decodedMacroCode.write(decompressedMacroCode)
                decodedMacroCode.write('\r\n\r\n\r\n\r\n')

            decodedMacroCode.close()
            print 'saved macrocode to file:', os.path.abspath(folderName + '/macroCode.txt')
            foundMacroCode = True

            '''blackList = ["kernel32" , "CreateThread", "VirtualAlloc", "RtlMoveMemory"]
            binaryFile = open("vbaProject.bin", "rb")   #open .bin-file in binary mode
            text = binaryFile.read()                    #and read into variable
            allBadWords = True

            for badword in blackList:                   #check if every 'badword' occurs in the vba-file
                #print(badword)
                if (badword.encode("cp1252")).lower() not in text.lower():      #we use cp1252 encoding, as it is the
                    #print("didn't find " + badword + " in the file")           #default encoding for windows systems
                    allBadWords = False
            if allBadWords == True:
                #print("found the whole badWord-List!")
                pass'''

            ole.close()

        if not foundMacroCode:
            print 'found no macro-code'
Ejemplo n.º 18
0
	def __init__(self, binary):
		self.rt = littleEndian.readShort(binary, 0) #MUST be 0x0813
		self.grbitFrt = littleEndian.readShort(binary, 2) #MUST be 0x0000
		self.reserved1 = littleEndian.readInt(binary, 4) #MUST be 0x00000000
		self.reserved2 = littleEndian.readInt(binary, 8) #MUST be 0x00000000
Ejemplo n.º 19
0
    def extractMacroCode(self):
        foundMacroCode = False
        fileName = self.fileName
        #prefix will vary by OLE or XML mode
        prefix = ''
        if self.mode == 0:
            if not os.path.exists(fileName + self.docType + '/vbaProject.bin'):
                if not self.args.quiet and not self.args.json:
                    print 'no macro-code'
                return
            assert OleFileIO_PL.isOleFile(fileName + self.docType +
                                          '/vbaProject.bin')

            ole = OleFileIO_PL.OleFileIO(fileName + self.docType +
                                         '/vbaProject.bin')
            prefix = 'VBA/'
            oleFileList = [ole]

        else:
            assert OleFileIO_PL.isOleFile(fileName)

            ole = OleFileIO_PL.OleFileIO(fileName)
            oleFileList = [ole]
            if self.docType == '/xl':
                prefix = '_VBA_PROJECT_CUR/VBA/'
            elif self.docType == '/word':
                prefix = 'Macros/VBA/'
            elif self.docType == '/ppt':
                prefix = 'VBA/'
                if not self.args.quiet and not self.args.json:
                    print 'extracting VBA-Storage...'
                current_user_stream = ole.openstream('Current User').read()
                document_stream = ole.openstream('PowerPoint Document').read()
                ppt_structures = imp.load_source(
                    'ppt_structures', 'modules/OLE_parsing/ppt_structures.py')

                folderName = os.path.abspath(self.fileName.split('.')[0])
                if not os.path.exists(folderName):
                    os.makedirs(folderName)
                externalOleObjectStorages = ppt_structures.findExternalOleObjectStorageLocation(
                    current_user_stream, document_stream)
                if externalOleObjectStorages != None:
                    decompressedStorageFiles = ppt_structures.decompressExternalOleObjectStorage(
                        folderName, document_stream, externalOleObjectStorages)
                    ole.close()
                    oleFileList = []
                    for externalOleObjectStorage in decompressedStorageFiles:
                        openOleFile = OleFileIO_PL.OleFileIO(
                            externalOleObjectStorage)
                        oleFileList += [openOleFile]

        for ole in oleFileList:

            if ole.exists(prefix + 'dir'):
                dir = ole.openstream(prefix + 'dir')
                content = dir.read()
                dir.close()
            else:
                ole.close()
                continue

            moduleOffsetRecordIdentifier = '\x31\x00\x04\x00\x00\x00'
            moduleNameRecordIdentifier = '\x19\x00'

            decompressedDir = ''
            dirSequences = []

            dirSequences = macroDecoder.getSequences(content[1:])

            #decode dir-stream in order to find metadata about the macro streams
            for sequence in dirSequences:
                decompressedDir = macroDecoder.decodeSequence(
                    decompressedDir, sequence)

            #find all Module Offset Records
            current = 0
            listModuleOffsetRecords = []
            while decompressedDir.find(moduleOffsetRecordIdentifier,
                                       current) != -1:
                foundAt = decompressedDir.find(moduleOffsetRecordIdentifier,
                                               current)
                listModuleOffsetRecords.append(foundAt)
                current = foundAt + 1

            #find the name of the modules/streams corresponding to the found Module Offsets
            listModuleNames = []
            start = 0
            for count in range(0, len(listModuleOffsetRecords)):
                moduleName = ''
                index = decompressedDir.rfind(moduleNameRecordIdentifier,
                                              start,
                                              listModuleOffsetRecords[count])
                nameLength = ord(decompressedDir[index + 5]) << 24
                nameLength += ord(decompressedDir[index + 4]) << 16
                nameLength += ord(decompressedDir[index + 3]) << 8
                nameLength += ord(decompressedDir[index + 2])
                for nameCharacter in range(0, nameLength):
                    moduleName += decompressedDir[index + 6 + nameCharacter]
                listModuleNames.append(moduleName)
                start = listModuleOffsetRecords[count]

            #find the Offsets in the Module Streams, where the textual reprensentation of the macrocode starts
            listCodeOffsets = []
            for offsets in listModuleOffsetRecords:
                try:
                    codeOffset = ord(decompressedDir[offsets + 9]) << 24
                    codeOffset += ord(decompressedDir[offsets + 8]) << 16
                    codeOffset += ord(decompressedDir[offsets + 7]) << 8
                    codeOffset += ord(decompressedDir[offsets + 6])
                except:
                    continue

                listCodeOffsets.append(codeOffset)

            listEncodedMacroCode = []
            current = 0
            for moduleName in listModuleNames:
                codeBuffer = ''
                path = prefix + moduleName

                if ole.exists(path):
                    if not self.args.quiet and not self.args.json:
                        print 'decoding module:', moduleName
                    oleStream = ole.openstream(path)
                    codeBuffer = oleStream.read()
                else:
                    oleStream = None
                    if not self.args.quiet and not self.args.json:
                        print path, 'doesn\'t exist'

                try:
                    codeBuffer = codeBuffer[listCodeOffsets[current] + 1:]
                except IndexError:
                    continue
                chunkList = []
                #find all chunks, which follow after each other
                #0x00 will be at the end of the last chunk
                while len(codeBuffer) > 0 and codeBuffer[0] != 0x00:
                    chunkLength = littleEndian.readShort(codeBuffer, 0)
                    chunkLength = (chunkLength & 0x0fff) + 3
                    currentChunk = codeBuffer[:chunkLength]
                    codeBuffer = codeBuffer[chunkLength:]
                    listEncodedMacroCode.append(currentChunk)

                    current += 1
                if oleStream:
                    oleStream.close()

            if not self.extractionFolder:
                folderName1 = self.fileName.rsplit('.', 1)[0]
            elif self.extractionFolder == '.':
                folderName1 = self.fileName.rsplit('/', 1)[1].split('.')[0]
            else:
                folderName1 = os.path.join(
                    self.extractionFolder,
                    self.fileName.rsplit('/', 1)[1].split('.')[0])

            if self.mode == 1:
                #OLE case
                folderName = os.path.abspath(folderName1)
                if not os.path.exists(folderName):
                    os.makedirs(folderName)
            else:
                folderName = folderName1

            decodedMacroCode = open(
                os.path.abspath(folderName + '/macroCode.txt'), 'a')
            codeSequences = []
            for encodedSequences in listEncodedMacroCode:
                codeSequences = macroDecoder.getSequences(encodedSequences)

                decompressedMacroCode = ''
                for sequence in codeSequences:

                    decompressedMacroCode = macroDecoder.decodeSequence(
                        decompressedMacroCode, sequence)
                decodedMacroCode.write(decompressedMacroCode)
                decodedMacroCode.write('\r\n\r\n\r\n\r\n')

            decodedMacroCode.close()
            macro_save_location = os.path.abspath(folderName +
                                                  '/macroCode.txt')
            if not self.args.quiet:
                if self.args.json:
                    self.json_result['debug'].append(
                        'saved macrocode to file: %s' % (macro_save_location))
                else:
                    print 'saved macrocode to file: %s' % (macro_save_location)
            foundMacroCode = True
            '''blackList = ["kernel32" , "CreateThread", "VirtualAlloc", "RtlMoveMemory"]
            binaryFile = open("vbaProject.bin", "rb")   #open .bin-file in binary mode
            text = binaryFile.read()                    #and read into variable
            allBadWords = True

            for badword in blackList:                   #check if every 'badword' occurs in the vba-file
                #print(badword)
                if (badword.encode("cp1252")).lower() not in text.lower():      #we use cp1252 encoding, as it is the
                    #print("didn't find " + badword + " in the file")           #default encoding for windows systems
                    allBadWords = False
            if allBadWords == True:
                #print("found the whole badWord-List!")
                pass'''

            ole.close()

        if not foundMacroCode and not self.args.quiet and not self.args.json:
            print 'no macro-code'
        elif foundMacroCode:
            if self.args.json:
                self.json_result['detections'].append({
                    'type':
                    'macro code',
                    'location':
                    macro_save_location
                })
            else:
                print '>> macro code detected!'
            self.checkMacroCode(macro_save_location)
Ejemplo n.º 20
0
 def __init__(self, binary):
     self.type = littleEndian.readShort(binary, 0)
     self.length = littleEndian.readShort(binary, 2)
Ejemplo n.º 21
0
 def __init__(self, binary):
     self.ft = littleEndian.readShort(binary, 0)
     self.cb = littleEndian.readShort(binary, 2)
     self.guid = binary[4:20]
     self.fSharedNote = littleEndian.readShort(binary, 20)
     self.unused = littleEndian.readInt(binary, 22)
Ejemplo n.º 22
0
 def __init__(self, binary):
     self.ft = littleEndian.readShort(binary, 0)
     self.cb = littleEndian.readShort(binary, 2)
     self.accel = littleEndian.readShort(binary, 4)
     self.reserved = littleEndian.readShort(binary, 6)
Ejemplo n.º 23
0
 def __init__(self, binary, cmo_ot):
     self.cmo_ot = cmo_ot
     self.ft = littleEndian.readShort(binary, 0)
     self.fmla = ObjFmla(binary[2:])
     self.sizeInBytes = self.fmla.cbFmla+4
Ejemplo n.º 24
0
 def __init__(self, binary):
     self.ft = littleEndian.readShort(binary, 0)
     self.cb = littleEndian.readShort(binary, 2)
     self.unused1 = littleEndian.readInt(binary, 4)
     self.unused2 = littleEndian.readShort(binary, 8)
Ejemplo n.º 25
0
 def __init__(self, binaryString):
     temp = littleEndian.readShort(binaryString, 0)
     self.recVer = temp & 0x000f
     self.recInstance = temp >> 4
     self.recType = (ord(binaryString[3]) << 8) + ord(binaryString[2])
     self.recLen = littleEndian.readInt(binaryString, 4)
Ejemplo n.º 26
0
 def __init__(self, binary):
     self.cce = (littleEndian.readShort(binary, 0))
     self.rgce = PtgTbl(binary[6:6+self.cce])
Ejemplo n.º 27
0
 def getCompressedChunkLength(self, blob):
     chunkLength = littleEndian.readShort(blob, 0)
     chunkLength = chunkLength & 0x0fff
     return chunkLength + 3
Ejemplo n.º 28
0
    def locateFlashObjects(self):
        pathToActiveX = self.pathToActiveX
        fileName = self.fileName
        docType = self.docType
        foundFlashObject = False

        if self.mode == 0:
            #this is an XML-based document
            activeXContainers = []

            fileNames = []

            for dirname, dirnames, filenames in os.walk(pathToActiveX):
                for filename in filenames:
                    fileNames.append(os.path.join(dirname, filename))

            filtered = fnmatch.filter(fileNames, '*activeX*.xml')

            for activeXcontrol in filtered:
                currentControl = open(activeXcontrol, 'r')
                controlText = currentControl.read()

                #the Class-ID: D27CDB6E-AE6D-11CF-96B8-444553540000 identifies an activeX-control as flash-object
                if self.ShockwaveFlashClassID in controlText:
                    if not self.args.quiet and not self.args.json:
                        print activeXcontrol + " is a FlashObject!"
                    foundFlashObject = True
                    activeXBinFileName = activeXcontrol[:-3]
                    activeXBinFileName += 'bin'
                    activeXContainers.append(activeXBinFileName)

                currentControl.close()

            #starting to determine the origin of the .swf file
            if self.docType == '/xl':
                for activeXBinFileName in activeXContainers:
                    acitveXStream = open(activeXBinFileName, 'rb').read()
                    currentOffset = acitveXStream.find('.swf')
                    if currentOffset == -1:
                        currentOffset = acitveXStream.find('.\x00s\x00w\x00f')
                    if currentOffset != -1:
                        pathLength = 5
                        path = '.swf'
                        #reading the path from back to front, since we don't know the length of the path yet
                        while acitveXStream[currentOffset -
                                            3:currentOffset] != '\x00\x00\x00':
                            path = acitveXStream[currentOffset - 2] + path
                            currentOffset = currentOffset - 2
                            pathLength = pathLength + 1
                        bytesForPath = littleEndian.readInt(
                            acitveXStream, currentOffset - 4)
                        #check if the length of our extracted path matches the 4 bytes in front
                        #of it, (interpreting the 4 bytes as a unsigned integer in littleendian)
                        if bytesForPath == pathLength * 2 and not self.args.quiet:
                            print 'path to .swf: ' + path
                if not foundFlashObject and not self.args.quiet and not self.args.json:
                    print 'found no Flash-Objects'
                if foundFlashObject:
                    if self.args.json:
                        self.json_result['detections'].append({
                            'type': 'flash',
                            'location': None
                        })
                    else:
                        print "found flash object"
                return
            for activeXBinFileName in activeXContainers:
                #make sure that our .bin files are actually OLE-files
                assert OleFileIO_PL.isOleFile(activeXBinFileName)

                ole = OleFileIO_PL.OleFileIO(activeXBinFileName)

                if ole.exists('Contents'):
                    #Flash-files are embedded via activeX-controls, which are located in the "Contens" folder of the OLE-file
                    Contents = ole.openstream('Contents')
                    content = Contents.read()
                    Contents.close()
                else:
                    if not self.args.quiet and not self.args.json:
                        print('Contents doesn\'t exsit')
                    ole.close()

                if littleEndian.readShort(content, 24) == 8:
                    #this means the next 4 bytes (little-endian) will tell the length of an unicode string,
                    #which will follow right after the length field
                    pathLength = littleEndian.readInt(content, 26)

                    pathToSWFfile = ''
                    for iterator in range(30, 30 + pathLength):
                        if iterator % 2 == 0:
                            #every second byte will be 0x00. Office doesn't allow characters, which would have to use this second byte
                            pathToSWFfile += content[iterator]
                    #print as a hex string, if you need to search manually in the .bin file
                    #print (':'.join(x.encode('hex') for x in pathToSWFfile))
                    if not self.args.quiet and not self.args.json:
                        print 'path to swf-file: ' + pathToSWFfile
                else:
                    if not self.args.quiet and not self.args.json:
                        print 'this doesn\'t seem to be an unicode string'

                ole.close()
            if not foundFlashObject and not self.args.quiet and not self.args.json:
                print 'found no Flash-Objects'
            if foundFlashObject:
                if self.args.json:
                    self.json_result['detections'].append({
                        'type': 'flash',
                        'location': None
                    })
                else:
                    print "found flash object"
        else:
            #this is a OLE-formated document
            assert OleFileIO_PL.isOleFile(fileName)

            ole = OleFileIO_PL.OleFileIO(fileName)
            if docType == '/word':
                wordDocStream = ole.openstream('WordDocument')
                wordDocBuffer = wordDocStream.read()
                if 'CONTROL ShockwaveFlash.ShockwaveFlash' in wordDocBuffer:
                    if not self.args.quiet and not self.args.json:
                        print 'use of Shockwafe Flash detected'
                    foundFlashObject = True
                else:
                    if not foundFlashObject and not self.args.quiet and not self.args.json:
                        print 'found no Flash-Objects'
                    return
                listOCXContents = []
                listOLEPaths = ole.listdir()
                #print ole.listdir()
                #find all OCXNAME streams in the word file
                for path in listOLEPaths:
                    if path[len(path) - 1] == 'Contents':
                        #print ('/'.join(x for x in path))
                        listOCXContents.append('/'.join(x for x in path))
                for content in listOCXContents:
                    OCXStream = ole.openstream(content)
                    contentBuffer = OCXStream.read()
                    #print contentBuffer
                    currentOffset = contentBuffer.find('.swf')
                    if currentOffset == -1:
                        currentOffset = contentBuffer.find('.\x00s\x00w\x00f')
                    if currentOffset != -1:
                        pathLength = 5
                        path = '.swf'
                        #reading the path from back to front, since we don't know the length of the path yet
                        while contentBuffer[currentOffset -
                                            3:currentOffset] != '\x00\x00\x00':
                            path = contentBuffer[currentOffset - 2] + path
                            currentOffset = currentOffset - 2
                            pathLength = pathLength + 1
                        bytesForPath = littleEndian.readInt(
                            contentBuffer, currentOffset - 4)
                        #check if the length of our extracted path matches the 4 bytes in front
                        #of it, (interpreting the 4 bytes as a unsigned integer in littleendian)
                        if bytesForPath == pathLength * 2:
                            #print 'length does match!'
                            pass
                        if not self.args.quiet and not self.args.json:
                            print 'path to .swf: ' + path
                    else:
                        if not self.args.quiet and not self.args.json:
                            print 'no .swf found in contents'
                    OCXStream.close()

            elif docType == '/xl':
                excel_structures = imp.load_source(
                    'excel_structures',
                    'modules/OLE_parsing/excel_structures.py')
                #import excel_structures
                ws = excel_structures.workbook(ole)
                foundFlashObject = ws.findFlashObjects()
                pass
            elif docType == '/ppt':
                ppt_structures = imp.load_source(
                    'ppt_structures', 'modules/OLE_parsing/ppt_structures.py')
                #import ppt_structures
                ppt_document_stream = ole.openstream(
                    'PowerPoint Document').read()
                current_user_stream = ole.openstream('Current User').read()
                ppt_flash = ppt_structures.ppt_container(ppt_document_stream)
                #find externalOleObjectStorage-Ids, which point to a source of Flash
                foundFlashObject = ppt_structures.findShockwaveFlash(ppt_flash)
                folderName = os.path.abspath(self.fileName.split('.')[0])
                if not os.path.exists(folderName):
                    os.makedirs(folderName)

                externalOleObjectStorages = ppt_structures.findExternalOleObjectStorageLocation(
                    current_user_stream, ppt_document_stream)
                if not externalOleObjectStorages:
                    return
                decompressedStorageFiles = ppt_structures.decompressExternalOleObjectStorage(
                    folderName, ppt_document_stream, externalOleObjectStorages)
                #extract paths to Flash-Objects
                currentPersistId = 0
                for oleStorageFile in decompressedStorageFiles:
                    currentStorage = OleFileIO_PL.OleFileIO(oleStorageFile)
                    if not currentStorage.exists('Contents'):
                        currentPersistId += 1
                        continue
                    contentBuffer = currentStorage.openstream(
                        'Contents').read()

                    currentOffset = contentBuffer.find('.swf')
                    if currentOffset == -1:
                        currentOffset = contentBuffer.find('.\x00s\x00w\x00f')
                    if currentOffset != -1:
                        pathLength = 5
                        path = '.swf'
                        #reading the path from back to front, since we don't know the length of the path yet
                        while contentBuffer[currentOffset -
                                            3:currentOffset] != '\x00\x00\x00':
                            path = contentBuffer[currentOffset - 2] + path
                            currentOffset = currentOffset - 2
                            pathLength = pathLength + 1
                        if not self.args.quiet and not self.args.json:
                            print 'path to .swf: ' + path
                    else:
                        if not self.args.quiet and not self.args.json:
                            print 'no .swf found in contents'
                    currentStorage.close()
                    currentPersistId += 1
            else:
                if not self.args.quiet and not self.args.json:
                    print 'No document type was given'

            if not foundFlashObject and not self.args.quiet and not self.args.json:
                print 'found no Flash-Objects'
            if foundFlashObject:
                if self.args.json:
                    self.json_result['detections'].append({
                        'type': 'flash',
                        'location': None
                    })
                else:
                    print "found flash object"
            ole.close()
Ejemplo n.º 29
0
 def __init__(self, binaryString):
     temp = littleEndian.readShort(binaryString, 0)
     self.recVer = temp & 0x000f
     self.recInstance = temp >> 4
     self.recType = (ord(binaryString[3]) << 8) + ord(binaryString[2])
     self.recLen = littleEndian.readInt(binaryString, 4)
Ejemplo n.º 30
0
 def __init__(self, binary):
     self.ft = littleEndian.readShort(binary, 0)
     self.cb = littleEndian.readShort(binary, 2)
     self.idRadNext = littleEndian.readShort(binary, 4)
     self.fFirstBtn = littleEndian.readShort(binary, 6)
Ejemplo n.º 31
0
    def locateFlashObjects(self):
        pathToActiveX = self.pathToActiveX
        fileName = self.fileName
        docType = self.docType
        foundFlashObject = False

        if self.mode == 0:
            #this is an XML-based document
            activeXContainers = []

            fileNames = []

            for dirname, dirnames, filenames in os.walk(pathToActiveX):
                for filename in filenames:
                    fileNames.append(os.path.join(dirname, filename))

            filtered = fnmatch.filter(fileNames, '*activeX*.xml')

            for activeXcontrol in filtered:
                currentControl = open(activeXcontrol, 'r')
                controlText = currentControl.read()

                #the Class-ID: D27CDB6E-AE6D-11CF-96B8-444553540000 identifies an activeX-control as flash-object
                if self.ShockwaveFlashClassID in controlText:
                    if not self.args.quiet and not self.args.json:
                        print activeXcontrol + " is a FlashObject!"
                    foundFlashObject = True
                    activeXBinFileName = activeXcontrol[:-3]
                    activeXBinFileName += 'bin'
                    activeXContainers.append(activeXBinFileName)

                currentControl.close()

            #starting to determine the origin of the .swf file
            if self.docType == '/xl':
                for activeXBinFileName in activeXContainers:
                    acitveXStream = open(activeXBinFileName, 'rb').read()
                    currentOffset = acitveXStream.find('.swf')
                    if currentOffset == -1:
                        currentOffset = acitveXStream.find('.\x00s\x00w\x00f')
                    if currentOffset != -1:
                        pathLength = 5
                        path = '.swf'
                        #reading the path from back to front, since we don't know the length of the path yet
                        while acitveXStream[currentOffset-3:currentOffset] != '\x00\x00\x00':
                            path = acitveXStream[currentOffset-2] + path
                            currentOffset = currentOffset -2
                            pathLength = pathLength+1
                        bytesForPath = littleEndian.readInt(acitveXStream, currentOffset-4)
                        #check if the length of our extracted path matches the 4 bytes in front
                        #of it, (interpreting the 4 bytes as a unsigned integer in littleendian)
                        if bytesForPath == pathLength*2 and not self.args.quiet:
                            print 'path to .swf: ' + path
                if not foundFlashObject and not self.args.quiet and not self.args.json:
                    print 'found no Flash-Objects'
                if foundFlashObject:
                    if self.args.json:
                        self.json_result['detections'].append({'type': 'flash', 'location': None})
                    else:
                        print "found flash object"
                return
            for activeXBinFileName in activeXContainers:
                #make sure that our .bin files are actually OLE-files
                assert OleFileIO_PL.isOleFile(activeXBinFileName)

                ole = OleFileIO_PL.OleFileIO(activeXBinFileName)

                if ole.exists('Contents'):
                    #Flash-files are embedded via activeX-controls, which are located in the "Contens" folder of the OLE-file
                    Contents = ole.openstream('Contents')
                    content = Contents.read()
                    Contents.close()
                else:
                    if not self.args.quiet and not self.args.json:
                        print('Contents doesn\'t exsit')
                    ole.close()

                if littleEndian.readShort(content, 24) == 8:
                    #this means the next 4 bytes (little-endian) will tell the length of an unicode string,
                    #which will follow right after the length field
                    pathLength = littleEndian.readInt(content, 26)

                    pathToSWFfile = ''
                    for iterator in range(30, 30+pathLength):
                        if iterator % 2 == 0:
                            #every second byte will be 0x00. Office doesn't allow characters, which would have to use this second byte
                            pathToSWFfile += content[iterator]
                    #print as a hex string, if you need to search manually in the .bin file
                    #print (':'.join(x.encode('hex') for x in pathToSWFfile))
                    if not self.args.quiet and not self.args.json:
                        print 'path to swf-file: ' + pathToSWFfile
                else:
                    if not self.args.quiet and not self.args.json:
                        print 'this doesn\'t seem to be an unicode string'

                ole.close()
            if not foundFlashObject and not self.args.quiet and not self.args.json:
                print 'found no Flash-Objects'
            if foundFlashObject:
                if self.args.json:
                    self.json_result['detections'].append({'type': 'flash', 'location': None})
                else:
                    print "found flash object"
        else:
            #this is a OLE-formated document
            assert OleFileIO_PL.isOleFile(fileName)

            ole = OleFileIO_PL.OleFileIO(fileName)
            if docType == '/word':
                wordDocStream = ole.openstream('WordDocument')
                wordDocBuffer = wordDocStream.read()
                if 'CONTROL ShockwaveFlash.ShockwaveFlash' in wordDocBuffer:
                    if not self.args.quiet and not self.args.json:
                        print 'use of Shockwafe Flash detected'
                    foundFlashObject = True
                else:
                    if not foundFlashObject and not self.args.quiet and not self.args.json:
                        print 'found no Flash-Objects'
                    return
                listOCXContents = []
                listOLEPaths = ole.listdir()
                #print ole.listdir()
                #find all OCXNAME streams in the word file
                for path in listOLEPaths:
                    if path[len(path)-1] == 'Contents':
                        #print ('/'.join(x for x in path))
                        listOCXContents.append('/'.join(x for x in path))
                for content in listOCXContents:
                    OCXStream = ole.openstream(content)
                    contentBuffer = OCXStream.read()
                    #print contentBuffer
                    currentOffset = contentBuffer.find('.swf')
                    if currentOffset == -1:
                        currentOffset = contentBuffer.find('.\x00s\x00w\x00f')
                    if currentOffset != -1:
                        pathLength = 5
                        path = '.swf'
                        #reading the path from back to front, since we don't know the length of the path yet
                        while contentBuffer[currentOffset-3:currentOffset] != '\x00\x00\x00':
                            path = contentBuffer[currentOffset-2] + path
                            currentOffset = currentOffset -2
                            pathLength = pathLength+1
                        bytesForPath = littleEndian.readInt(contentBuffer, currentOffset-4)
                        #check if the length of our extracted path matches the 4 bytes in front
                        #of it, (interpreting the 4 bytes as a unsigned integer in littleendian)
                        if bytesForPath == pathLength*2:
                            #print 'length does match!'
                            pass
                        if not self.args.quiet and not self.args.json:
                            print 'path to .swf: ' + path
                    else:
                        if not self.args.quiet and not self.args.json:
                            print 'no .swf found in contents'
                    OCXStream.close()

            elif docType == '/xl':
                excel_structures = imp.load_source('excel_structures', 'modules/OLE_parsing/excel_structures.py')
                #import excel_structures
                ws = excel_structures.workbook(ole)
                foundFlashObject = ws.findFlashObjects()
                pass
            elif docType == '/ppt':
                ppt_structures = imp.load_source('ppt_structures', 'modules/OLE_parsing/ppt_structures.py')
                #import ppt_structures
                ppt_document_stream = ole.openstream('PowerPoint Document').read()
                current_user_stream = ole.openstream('Current User').read()
                ppt_flash = ppt_structures.ppt_container(ppt_document_stream)
                #find externalOleObjectStorage-Ids, which point to a source of Flash
                foundFlashObject = ppt_structures.findShockwaveFlash(ppt_flash)
                folderName = os.path.abspath(self.fileName.split('.')[0])
                if not os.path.exists(folderName):
                    os.makedirs(folderName)

                externalOleObjectStorages = ppt_structures.findExternalOleObjectStorageLocation(current_user_stream, ppt_document_stream)
                if not externalOleObjectStorages:
                    return
                decompressedStorageFiles = ppt_structures.decompressExternalOleObjectStorage(folderName, ppt_document_stream, externalOleObjectStorages)
                #extract paths to Flash-Objects
                currentPersistId = 0
                for oleStorageFile in decompressedStorageFiles:
                    currentStorage = OleFileIO_PL.OleFileIO(oleStorageFile)
                    if not currentStorage.exists('Contents'):
                        currentPersistId += 1
                        continue
                    contentBuffer = currentStorage.openstream('Contents').read()

                    currentOffset = contentBuffer.find('.swf')
                    if currentOffset == -1:
                        currentOffset = contentBuffer.find('.\x00s\x00w\x00f')
                    if currentOffset != -1:
                        pathLength = 5
                        path = '.swf'
                        #reading the path from back to front, since we don't know the length of the path yet
                        while contentBuffer[currentOffset-3:currentOffset] != '\x00\x00\x00':
                            path = contentBuffer[currentOffset-2] + path
                            currentOffset = currentOffset -2
                            pathLength = pathLength+1
                        if not self.args.quiet and not self.args.json:
                            print 'path to .swf: ' + path
                    else:
                        if not self.args.quiet and not self.args.json:
                            print 'no .swf found in contents'
                    currentStorage.close()
                    currentPersistId += 1
            else:
                if not self.args.quiet and not self.args.json:
                    print 'No document type was given'

            if not foundFlashObject and not self.args.quiet and not self.args.json:
                    print 'found no Flash-Objects'
            if foundFlashObject:
                if self.args.json:
                    self.json_result['detections'].append({'type': 'flash', 'location': None})
                else:
                    print "found flash object"
            ole.close()
Ejemplo n.º 32
0
 def __init__(self, binary):
     self.rt = littleEndian.readShort(binary, 0)  #MUST be 0x0813
     self.grbitFrt = littleEndian.readShort(binary, 2)  #MUST be 0x0000
     self.reserved1 = littleEndian.readInt(binary, 4)  #MUST be 0x00000000
     self.reserved2 = littleEndian.readInt(binary, 8)  #MUST be 0x00000000