예제 #1
0
def printDump(bupname, DumpFunction=IdentityFunction, allfiles=False):
    #
    #Print Hex dump/Hex-ASCII dump of first or all streams
    #
    if sys.platform == 'win32' and DumpFunction == IdentityFunction:
        import msvcrt
        msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
    try:
        if OleFileIO_PL.isOleFile(bupname) is not True:
            print('Error - %s is not a valid OLE file.' % bupname,
                  file=sys.stderr)
            sys.exit(1)

        ole = OleFileIO_PL.OleFileIO(bupname)
        printNewline = False
        for entry in ole.listdir():
            if entry[0] != "Details":
                if printNewline:
                    print()
                printNewline = True
                StdoutWriteChunked(
                    DumpFunction(decryptStream(
                        ole.openstream(entry[0]).read())))
                if not allfiles:
                    break
        ole.close()
    except Exception as e:
        print('Error - %s' % e, file=sys.stderr)
        sys.exit(1)
예제 #2
0
def checkFile(name):  
    try:  
        if not converter.isOleFile(name):
            sys.exit()       
    except:
        print "ERROR: %s is not a *.msg format file" % name
        sys.exit()
예제 #3
0
def extract(infile, dirname=None):
    if dirname is None:
        dirname = os.getcwd()
    try:
        if OleFileIO_PL.isOleFile(infile) is not True:
            print('Error - %s is not a valid OLE file.' % infile,
                  file=sys.stderr)
            sys.exit(1)

        ole = OleFileIO_PL.OleFileIO(infile)
        filelist = ole.listdir()
        for fname in filelist:
            if not ole.get_size(fname[0]):
                print(
                    'Warning: The "%s" stream reports a size of 0. Possibly a corrupt bup.'
                    % fname[0])
            data = ole.openstream(fname[0]).read()
            fp = open(os.path.join(dirname, fname[0]), 'wb')
            fp.write(data)
            fp.close()
        ole.close()
        return filelist
    except Exception as e:
        print('Error - %s' % e, file=sys.stderr)
        sys.exit(1)
예제 #4
0
파일: debup.py 프로젝트: lnmyshkin/viper
 def bupextract():
     # Check for valid OLE
     if not OleFileIO_PL.isOleFile(__sessions__.current.file.path):
         print_error("Not a valid BUP File")
         return
     ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
     # We know that BUPS are xor'd with 6A which is dec 106 for the decoder
     print_info("Switching Session to Embedded File")
     data = xordata(ole.openstream('File_0').read(), 106)
     # this is a lot of work jsut to get a filename.
     data2 = xordata(ole.openstream('Details').read(), 106)
     ole.close()
     lines = data2.split('\n')
     for line in lines:
         if line.startswith('OriginalName'):
             fullpath = line.split('=')[1]
             pathsplit = fullpath.split('\\')
             filename = str(pathsplit[-1][:-1])
     # now lets write the data out to a file and get a session on it
     if data:
         tempName = os.path.join('/tmp', filename)
         with open(tempName, 'w') as temp:
             temp.write(data)
         __sessions__.new(tempName)
         return
     else:
         print_error("Unble to Switch Session")
예제 #5
0
파일: debup.py 프로젝트: JeskeCode/viper
 def bupextract():
     # Check for valid OLE
     if not OleFileIO_PL.isOleFile(__sessions__.current.file.path):
         print_error("Not a valid BUP File")
         return
     ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
     # We know that BUPS are xor'd with 6A which is dec 106 for the decoder
     print_info("Switching Session to Embedded File")
     data = xordata(ole.openstream('File_0').read(), 106)
     # this is a lot of work jsut to get a filename.
     data2 = xordata(ole.openstream('Details').read(), 106)
     ole.close()
     lines = data2.split('\n')
     for line in lines:
         if line.startswith('OriginalName'):
             fullpath = line.split('=')[1]
             pathsplit = fullpath.split('\\')
             filename = str(pathsplit[-1][:-1])
     # now lets write the data out to a file and get a session on it
     if data:
         tempName = os.path.join('/tmp', filename)
         with open(tempName, 'w') as temp:
             temp.write(data)
         __sessions__.new(tempName)
         return
     else:
         print_error("Unble to Switch Session")
예제 #6
0
def printDump(bupname, DumpFunction=IdentityFunction, allfiles=False):
    #
    #Print Hex dump/Hex-ASCII dump of first or all streams
    #
    if sys.platform == 'win32' and DumpFunction == IdentityFunction:
        import msvcrt
        msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
    try:
        if OleFileIO_PL.isOleFile(bupname) is not True:
            print >>sys.stderr, 'Error - %s is not a valid OLE file.' % bupname
            sys.exit(1)

        ole = OleFileIO_PL.OleFileIO(bupname)
        printNewline = False
        for entry in ole.listdir():
            if entry[0] != "Details":
                if printNewline:
                    print
                printNewline = True
                StdoutWriteChunked(DumpFunction(decryptStream(ole.openstream(entry[0]).read())))
                if not allfiles:
                    break
        ole.close()
    except Exception as e:
        print >>sys.stderr, 'Error - %s' % e
        sys.exit(1)
예제 #7
0
def getHashes(bupname, htype):
    #
    #Return a dictionary of stream name and hash.
    #
    try:
        if OleFileIO_PL.isOleFile(bupname) is not True:
            print >> sys.stderr, 'Error - %s is not a valid OLE file.' % bupname
            sys.exit(1)

        ole = OleFileIO_PL.OleFileIO(bupname)
        hashes = {}
        for entry in ole.listdir():
            if entry[0] != "Details":
                fdata = ole.openstream(entry[0]).read()
                ptext = decryptStream(fdata)
                if htype == 'md5':
                    m = hashlib.md5()
                elif htype == 'sha1':
                    m = hashlib.sha1()
                elif htype == 'sha256':
                    m = hashlib.sha256()
                m.update(ptext)
                hashes[entry[0]] = m.hexdigest()
        ole.close()
        return hashes
    except Exception as e:
        print >> sys.stderr, 'Error - %s' % e
        sys.exit(1)
예제 #8
0
def getHashes(bupname,htype):
    #
    #Return a dictionary of stream name and hash. 
    #
    try:
        if OleFileIO_PL.isOleFile(bupname) is not True:
            print >>sys.stderr, 'Error - %s is not a valid OLE file.' % bupname
            sys.exit(1)

        ole = OleFileIO_PL.OleFileIO(bupname)                
        hashes = {}
        for entry in ole.listdir():
            if entry[0] != "Details":
                fdata = ole.openstream(entry[0]).read()
                ptext = decryptStream(fdata)
                if htype == 'md5':
                    m = hashlib.md5() 
                elif htype == 'sha1':
                    m = hashlib.sha1() 
                elif htype == 'sha256':
                    m = hashlib.sha256() 
                m.update(ptext)
                hashes[entry[0]] = m.hexdigest()                    
        ole.close()        
        return hashes
    except Exception as e:
        print >>sys.stderr, 'Error - %s' % e
        sys.exit(1)
예제 #9
0
def readRSF(filePath, fileName):
    '''Parses the information stored in the RecoveryStore file.
    Accepts single argument: the file name of the RecoveryStore file.'''
    fname = os.path.join(filePath, fileName)
    print("\n" + fileName + ":")
    try:
        #Check if file is the correct format
        if not (OleFileIO_PL.isOleFile(fname)):
            print("    Error: Unable to parse file '%s'. Incorrect format!" %
                  fname)
            return
        path = os.path.dirname(fname)
        rs = OleFileIO_PL.OleFileIO(fname)
        #Get list of streams
        streams = rs.listdir()
        sStreams = []
        for s in (streams):
            sStreams.append(s[0])
        p = rs.getproperties('\x05KjjaqfajN2c0uzgv1l4qy5nfWe')
        #Get session times
        closed = (buildTime(p[3]))
        opened = (buildTime(p[7]))
        print("    Opened:             " + opened + " UTC")
        if (opened != closed):
            print("    Closed:             " + closed + " UTC")
        else:
            print("    Closed:             N/A")
        #Check for InPrivate Browsing
        if (int("5") in p):
            print("    InPrivate Browsing: YES")
        else:
            print("    InPrivate Browsing: No")
        #Get all open tabs (TS#)
        print("\n    Open Tabs:")
        for s in streams:
            if ((s[0][:2] == "TS")):
                tempStream = rs.openstream(s[0])
                data = tempStream.read()
                tsStr = "".join("{:02x}".format(c) for c in data)
                b = 0
                while b < len(tsStr):
                    tdName = "{" + buildGUID(tsStr[b:b + 32]) + "}.dat"
                    readTDF(filePath, tdName, "        ")
                    b += 32
        #Get all closed tabs
        print("\n    Closed Tabs:")
        for s in streams:
            if (s[0] == "ClosedTabList"):
                tempStream = rs.openstream(s[0])
                data = tempStream.read()
                tempStream = rs.openstream(s[0])
                data = tempStream.read()
                tsStr = "".join("{:02x}".format(c) for c in data)
                b = 0
                while b < len(tsStr):
                    tdName = "{" + buildGUID(tsStr[b:b + 32]) + "}.dat"
                    readTDF(filePath, tdName, "        ")
                    b += 32
    except:
        print("\nError reading '" + fname + "': ", sys.exc_info()[1])
예제 #10
0
파일: parseRS.py 프로젝트: jtmoran/parseRS
def readRSF(filePath, fileName): 
    '''Parses the information stored in the RecoveryStore file.
    Accepts single argument: the file name of the RecoveryStore file.'''
    fname = os.path.join(filePath, fileName)
    print("\n" + fileName + ":")
    try:
        #Check if file is the correct format
        if not (OleFileIO_PL.isOleFile(fname)):
            print("    Error: Unable to parse file '%s'. Incorrect format!" % fname)
            return
        path = os.path.dirname(fname)
        rs = OleFileIO_PL.OleFileIO(fname)
        #Get list of streams
        streams = rs.listdir()
        sStreams = []
        for s in (streams):
            sStreams.append(s[0])
        p = rs.getproperties('\x05KjjaqfajN2c0uzgv1l4qy5nfWe')
        #Get session times
        closed = (buildTime(p[3]))
        opened = (buildTime(p[7]))
        print("    Opened:             " + opened + " UTC")
        if (opened != closed) :
            print("    Closed:             " + closed + " UTC")
        else:
            print("    Closed:             N/A")
        #Check for InPrivate Browsing
        if (int("5") in p):
            print("    InPrivate Browsing: YES") 
        else:
            print("    InPrivate Browsing: No") 
        #Get all open tabs (TS#)
        print("\n    Open Tabs:")
        for s in streams:
            if((s[0][:2] == "TS") ):
                tempStream = rs.openstream(s[0])
                data = tempStream.read()
                tsStr = "".join("{:02x}".format(c) for c in data)
                b = 0
                while b < len(tsStr):
                    tdName = "{" + buildGUID(tsStr[b:b + 32]) + "}.dat"
                    readTDF(filePath, tdName, "        ")
                    b += 32
        #Get all closed tabs
        print("\n    Closed Tabs:")
        for s in streams:
            if(s[0] == "ClosedTabList"):
                tempStream = rs.openstream(s[0])
                data = tempStream.read()
                tempStream = rs.openstream(s[0])
                data = tempStream.read()
                tsStr = "".join("{:02x}".format(c) for c in data)
                b = 0
                while b < len(tsStr):
                    tdName = "{" + buildGUID(tsStr[b:b + 32]) + "}.dat"
                    readTDF(filePath, tdName, "        ")
                    b += 32
    except:
        print("\nError reading '" + fname + "': ", sys.exc_info()[1])
예제 #11
0
def test_isOleFile_true():
    # Arrange
    ole_file = "Tests/images/test-ole-file.doc"

    # Act
    is_ole = OleFileIO.isOleFile(ole_file)

    # Assert
    assert_true(is_ole)
예제 #12
0
def test_isOleFile_false():
    # Arrange
    non_ole_file = "Tests/images/flower.jpg"

    # Act
    is_ole = OleFileIO.isOleFile(non_ole_file)

    # Assert
    assert_false(is_ole)
예제 #13
0
def OLEDump(filename):
    if OleFileIO_PL.isOleFile(filename) is not True:
        print >> sys.stderr, 'Error - %s is not a valid OLE file.' % infile
        sys.exit(1)
    ole = OleFileIO_PL.OleFileIO(filename)

    for fname in ole.listdir():
        stream = ole.openstream(fname).read()
        if '\x00Attribut' in stream:
            StdoutWriteChunked(SearchAndDecompress(stream))
    ole.close()
    return
예제 #14
0
파일: office.py 프로젝트: Oneiroi/viper
    def run(self):
        if not __sessions__.is_set():
            print_error("No session opened")
            return

        if not HAVE_OLE:
            print_error("Missing dependency, install OleFileIO (`pip install OleFileIO_PL`)")
            return

        def usage():
            print("usage: office [-hmsoe:]")

        def help():
            usage()
            print("")
            print("Options:")
            print("\t--help (-h)\tShow this help message")
            print("\t--meta (-m)\tGet The Metadata")
            print("\t--struct (-s)\tShow The OLE Structure")
            print("\t--oleid (-o)\tGet The OLE Information")
            print("\t--export (-e)\tExport OLE Objects (specify destination folder)")
            print("")

        if not OleFileIO_PL.isOleFile(__sessions__.current.file.path):
            print_error('This is not a valid OLE File, abort')
            return

        ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)

        try:
            opts, argv = getopt.getopt(self.args[0:], 'hmsoe:', ['help', 'meta', 'struct', 'oleid', 'export:'])
        except getopt.GetoptError as e:
            print(e)
            return

        for opt, value in opts:
            if opt in ('-e', '--export'):
                self.export(ole, value)
                return
            if opt in ('-h', '--help'):
                help()
                return
            if opt in ('-m','--meta'):
                self.metadata(ole)
                return
            if opt in ('-s','--struct'):
                self.metatimes(ole)
                return
            if opt in ('-o','--oleid'):
                self.oleid(ole)
                return

        usage()
예제 #15
0
    def run(self):
        super(Office, self).run()
        if self.args is None:
            return

        if not __sessions__.is_set():
            self.log('error', "No session opened")
            return

        if not HAVE_OLE:
            self.log(
                'error',
                "Missing dependency, install OleFileIO (`pip install OleFileIO_PL`)"
            )
            return

        # Tests to check for valid Office structures.
        OLE_FILE = OleFileIO_PL.isOleFile(__sessions__.current.file.path)
        XML_FILE = zipfile.is_zipfile(__sessions__.current.file.path)
        if OLE_FILE:
            ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
        elif XML_FILE:
            zip_xml = zipfile.ZipFile(__sessions__.current.file.path, 'r')
        else:
            self.log('error', "Not a valid office document")
            return

        if self.args.export is not None:
            if OLE_FILE:
                self.export(ole, self.args.export)
            elif XML_FILE:
                self.xml_export(zip_xml, self.args.export)
        elif self.args.meta:
            if OLE_FILE:
                self.metadata(ole)
            elif XML_FILE:
                self.xmlmeta(zip_xml)
        elif self.args.streams:
            if OLE_FILE:
                self.metatimes(ole)
            elif XML_FILE:
                self.xmlstruct(zip_xml)
        elif self.args.oleid:
            if OLE_FILE:
                self.oleid(ole)
            else:
                self.log('error', "Not an OLE file")
        elif self.args.vba or self.args.code:
            self.parse_vba(self.args.code)
        else:
            self.log('error', 'At least one of the parameters is required')
            self.usage()
예제 #16
0
def OLEDump(filename):
    if OleFileIO_PL.isOleFile(filename) is not True:
          print >>sys.stderr, 'Error - %s is not a valid OLE file.' % infile
          sys.exit(1)
    ole = OleFileIO_PL.OleFileIO(filename)

    
    for fname in ole.listdir():
            stream = ole.openstream(fname).read()
            if '\x00Attribut' in stream:
                StdoutWriteChunked(SearchAndDecompress(stream))
    ole.close()
    return 
예제 #17
0
def OLEDump(filename, options):
    if options.raw:
        print SearchAndDecompress(File2String(filename))
        return

    if filename == '':
        IfWIN32SetBinary(sys.stdin)
        ole = OleFileIO_PL.OleFileIO(cStringIO.StringIO(sys.stdin.read()))
    elif IsZIPFile(filename):
        oZipfile = zipfile.ZipFile(filename, 'r')
        oZipContent = oZipfile.open(oZipfile.infolist()[0], 'r',
                                    C2BIP3(MALWARE_PASSWORD))
        ole = OleFileIO_PL.OleFileIO(cStringIO.StringIO(oZipContent.read()))
        oZipContent.close()
    else:
        if OleFileIO_PL.isOleFile(filename) is not True:
            print >> sys.stderr, 'Error - %s is not a valid OLE file.' % infile
            sys.exit(1)
        ole = OleFileIO_PL.OleFileIO(filename)

    if options.select == '':
        counter = 1
        for fname in ole.listdir():
            stream = ole.openstream(fname).read()
            print('%2d: %s %6d %s' %
                  (counter, IFF('\x00Attribut' in stream, 'M',
                                ' '), len(stream), PrintableName(fname)))
            counter += 1
    else:
        if options.dump:
            DumpFunction = lambda x: x
            IfWIN32SetBinary(sys.stdout)
        elif options.hexdump:
            DumpFunction = HexDump
        elif options.vbadecompress:
            DumpFunction = SearchAndDecompress
        elif options.extract:
            DumpFunction = Extract
            IfWIN32SetBinary(sys.stdout)
        elif options.info:
            DumpFunction = Info
        else:
            DumpFunction = HexAsciiDump
        counter = 1
        for fname in ole.listdir():
            if counter == int(options.select):
                StdoutWriteChunked(DumpFunction(ole.openstream(fname).read()))
                break
            counter += 1
    ole.close()
예제 #18
0
파일: office.py 프로젝트: jorik041/viper
    def run(self):
        super(Office, self).run()
        if self.args is None:
            return

        if not __sessions__.is_set():
            self.log('error', "No session opened")
            return

        if not HAVE_OLE:
            self.log('error', "Missing dependency, install OleFileIO (`pip install OleFileIO_PL`)")
            return

        # Tests to check for valid Office structures.
        OLE_FILE = OleFileIO_PL.isOleFile(__sessions__.current.file.path)
        XML_FILE = zipfile.is_zipfile(__sessions__.current.file.path)
        if OLE_FILE:
            ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
        elif XML_FILE:
            zip_xml = zipfile.ZipFile(__sessions__.current.file.path, 'r')
        else:
            self.log('error', "Not a valid office document")
            return

        if self.args.export is not None:
            if OLE_FILE:
                self.export(ole, self.args.export)
            elif XML_FILE:
                self.xml_export(zip_xml, self.args.export)
        elif self.args.meta:
            if OLE_FILE:
                self.metadata(ole)
            elif XML_FILE:
                self.xmlmeta(zip_xml)
        elif self.args.streams:
            if OLE_FILE:
                self.metatimes(ole)
            elif XML_FILE:
                self.xmlstruct(zip_xml)
        elif self.args.oleid:
            if OLE_FILE:
                self.oleid(ole)
            else:
                self.log('error', "Not an OLE file")
        elif self.args.vba or self.args.code:
            self.parse_vba(self.args.code)
        else:
            self.log('error', 'At least one of the parameters is required')
            self.usage()
예제 #19
0
def getDetails(bupname):
    try:
        if OleFileIO_PL.isOleFile(bupname) is not True:
            print >> sys.stderr, 'Error - %s is not a valid OLE file.' % bupname
            sys.exit(1)

        ole = OleFileIO_PL.OleFileIO(bupname)
        #clean this up later by catching exception
        data = ole.openstream("Details").read()
        ptext = decryptStream(data)
        ole.close()
        return ptext
    except Exception as e:
        print >> sys.stderr, 'Error - %s' % e
        sys.exit(1)
예제 #20
0
def getDetails(bupname):
    try:
        if OleFileIO_PL.isOleFile(bupname) is not True:
            print >>sys.stderr, 'Error - %s is not a valid OLE file.' % bupname
            sys.exit(1)

        ole = OleFileIO_PL.OleFileIO(bupname)
        #clean this up later by catching exception
        data = ole.openstream("Details").read()
        ptext=decryptStream(data)
        ole.close()
        return ptext
    except Exception as e:
        print >>sys.stderr, 'Error - %s' % e
        sys.exit(1)
예제 #21
0
def OLEDump(filename):
    if OleFileIO_PL.isOleFile(filename) is not True:
          print >>sys.stderr, 'Error - %s is not a valid OLE file.' % infile
          sys.exit(1)
    ole = OleFileIO_PL.OleFileIO(filename)

    
    for fname in ole.listdir():
            stream = ole.openstream(fname).read()
            if '\x00Attribut' in stream:
                line = SearchAndDecompress(stream)
 		line = re.sub (r'[cC][hH][rR][wW\$]*\(([\d+\+\-\s\.]*)\)', do_chr, line)
		line = re.sub (" & ", "", line)
		line = re.sub ("& ", "", line)
		line = line.replace("\"","")
		line = re.sub (r'[sS][tT][rR][rR][eE][vV][eE][rR][sS][eE]\(([^)]*)\)', do_strme, line)
		line = line.rstrip ()        
                StdoutWriteChunked(line)
    ole.close()
    return 
예제 #22
0
def extract(infile, dirname=None):
    if dirname is None:
        dirname = os.getcwd()
    try:
        if OleFileIO_PL.isOleFile(infile) is not True:
            print >>sys.stderr, 'Error - %s is not a valid OLE file.' % infile
            sys.exit(1)
        
        ole = OleFileIO_PL.OleFileIO(infile)
        filelist = ole.listdir()
        for fname in filelist:
            data = ole.openstream(fname[0]).read()
            fp = open(os.path.join(dirname, fname[0]),'wb')
            fp.write(data)
            fp.close()
        ole.close()
        return filelist
    except Exception as e:
        print >>sys.stderr, 'Error - %s' % e
        sys.exit(1)
예제 #23
0
def extract(infile, dirname=None):
    if dirname is None:
        dirname = os.getcwd()
    try:
        if OleFileIO_PL.isOleFile(infile) is not True:
            print >> sys.stderr, 'Error - %s is not a valid OLE file.' % infile
            sys.exit(1)

        ole = OleFileIO_PL.OleFileIO(infile)
        filelist = ole.listdir()
        for fname in filelist:
            data = ole.openstream(fname[0]).read()
            fp = open(os.path.join(dirname, fname[0]), 'wb')
            fp.write(data)
            fp.close()
        ole.close()
        return filelist
    except Exception as e:
        print >> sys.stderr, 'Error - %s' % e
        sys.exit(1)
예제 #24
0
def analysisMax(filePath, resultPath):
    fileError=0
    settingsPath = resultPath + "/analysis.log"
    settingsFile = open(settingsPath, "w")
    if os.path.exists(filePath):
        if olefile.isOleFile(filePath):
            try:
                maxOle = olefile.OleFileIO(filePath)
            except:
                print "file is error"
                fileError = 1
        else:
            print "file is not a ole2 file"
            fileError = 1
    else:
        print "file is not exist"
        fileError = 1
    if fileError==1:
        settingsFile.write("{\"applications\":{\"fileError\":\"1\"}}")
        settingsFile.close()
        sys.exit(1)
    print "setting info. analyze is start"
    # 配置信息解析
    try:
        summary = maxOle.openstream("\x05DocumentSummaryInformation")
    except:
        fileError=1
        settingsFile.write("{\"applications\":{\"fileError\":\"1\"}}")
        settingsFile.close()
        sys.exit(1)
    rawData = summary.read()
    maxOle.close()
    docSummaryInfo = oleDocumentSummaryInfo(rawData)
    docSummaryInfo.analysisDocSummaryString()
    if not docSummaryInfo.dataDocSummaryDict["applications"]["softwareconfig"].has_key('version'):
        docSummaryInfo.dataDocSummaryDict["applications"]["softwareconfig"]["version"] = 2007
    if not docSummaryInfo.dataDocSummaryDict["applications"]["softwareconfig"].has_key('realVersion'):
        docSummaryInfo.dataDocSummaryDict["applications"]["softwareconfig"]["realVersion"] = 2007
    settingsFile.write(json.dumps(docSummaryInfo.dataDocSummaryDict))
    settingsFile.close()
    print "setting info. analyze is over"
예제 #25
0
def extract(infile, dirname=None):
    if dirname is None:
        dirname = os.getcwd()
    try:
        if OleFileIO_PL.isOleFile(infile) is not True:
            print >>sys.stderr, 'Error - %s is not a valid OLE file.' % infile
            sys.exit(1)
        
        ole = OleFileIO_PL.OleFileIO(infile)
        filelist = ole.listdir()
        for fname in filelist:
            if not ole.get_size(fname[0]):
                print 'Warning: The "%s" stream reports a size of 0. Possibly a corrupt bup.' % fname[0]
            data = ole.openstream(fname[0]).read()
            fp = open(os.path.join(dirname, fname[0]),'wb')
            fp.write(data)
            fp.close()
        ole.close()
        return filelist
    except Exception as e:
        print >>sys.stderr, 'Error - %s' % e
        sys.exit(1)
예제 #26
0
    def parse(self, f):
        doc = {'filename': f, 'words': []}
        fn, ext = os.path.splitext(f)

        # file_props(f)
        if os.path.isfile(f):
            if OleFileIO_PL.isOleFile(f):
                doc = self.addto(doc, self.is_ole(f))

            doc = self.addto(doc, self.get_exif(f))

            if ext == '.pdf':
                doc = self.addto(doc, self.pdf(f))

            else:
                try:
                    doc = self.addto(doc, self.decompress(f))

                except zipfile.BadZipfile:
                    pass

        with open(f, 'rb') as dat:
            fdat = dat.read()
            doc = self.addto(doc, self.mod_checks(fdat))

        doc['words'].append(f.split('/')[-1])
        # All prop values into wordlist
        for k in doc.keys():
            if not k in ('filename', 'words'):
                if type(doc[k]) == list:
                    doc['words'] += doc[k]

                else:
                    doc['words'].append(doc[k])

        doc['words'] = list(set(doc['words']))

        return doc
    def __initOleFile(self):

        if OleFileIO_PL.isOleFile(self.docFile) == False:
            self.metaData["Error"] = "Isn't an Ole File"
        else:
            self.oleFile = OleFileIO_PL.OleFileIO(self.docFile)
예제 #28
0
import sys
import OleFileIO_PL

filename = sys.argv[1]

assert OleFileIO_PL.isOleFile(filename)
# Open OLE file:
ole = OleFileIO_PL.OleFileIO(filename)
# Get list of streams:
#print ole.listdir()
# Test if known streams/storages exist:
if ole.exists('worddocument'):
    print "This is a Word document."
    print "size :", ole.get_size('worddocument')
    if ole.exists('macros/vba'):
         print "This document seems to contain VBA macros."

def get_stream(name):
	result = ole.openstream(name).read()
	try:
		result = result.decode('utf-16')
	except Exception:
		print "Could not decode", name
	return result

names = ole.listdir()
names = map('/'.join, names)
streams = dict(zip(names, map(get_stream, ole.listdir())))
예제 #29
0
    def run(self):
        if not __sessions__.is_set():
            print_error("No session opened")
            return

        if not HAVE_OLE:
            print_error("Missing dependency, install OleFileIO (`pip install OleFileIO_PL`)")
            return

        def usage():
            print("usage: office [-hmsoe:]")

        def help():
            usage()
            print("")
            print("Options:")
            print("\t--help (-h)\tShow this help message")
            print("\t--meta (-m)\tGet the metadata")
            print("\t--oleid (-o)\tGet the OLE information")
            print("\t--streams (-s)\tShow the document streams")
            print("\t--export (-e)\tExport all objects (specify destination folder)")
            print("")

        # Tests to check for valid Office structures.
        OLE_FILE = OleFileIO_PL.isOleFile(__sessions__.current.file.path)
        XML_FILE = zipfile.is_zipfile(__sessions__.current.file.path)
        if OLE_FILE:
            ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
        elif XML_FILE:
            zip_xml = zipfile.ZipFile(__sessions__.current.file.path, 'r')
        else:
            print_error("Not a valid office document")
            return

        try:
            opts, argv = getopt.getopt(self.args[0:], 'hmsoe:', ['help', 'meta', 'streams', 'oleid', 'export='])
        except getopt.GetoptError as e:
            print(e)
            return

        for opt, value in opts:
            if opt in ('-e', '--export'):
                if OLE_FILE:
                    self.export(ole, value)
                    return
                elif XML_FILE:
                    self.xml_export(zip_xml, value)
                    return
            if opt in ('-h', '--help'):
                help()
                return
            if opt in ('-m','--meta'):
                if OLE_FILE:
                    self.metadata(ole)
                    return
                elif XML_FILE:
                    self.xmlmeta(zip_xml)
                    return
            if opt in ('-s','--streams'):
                if OLE_FILE:
                    self.metatimes(ole)
                    return
                elif XML_FILE:
                    self.xmlstruct(zip_xml)
                    return
            if opt in ('-o','--oleid'):
                if OLE_FILE:
                    self.oleid(ole)
                    return
                else:
                    return

        usage()
예제 #30
0
파일: debup.py 프로젝트: JeskeCode/viper
    def run(self):
        if not __sessions__.is_set():
            print_error("No session opened")
            return

        if not HAVE_OLE:
            print_error("Missing dependency, install OleFileIO (`pip install OleFileIO_PL`)")
            return
        
        def xordata(data, key):
            encoded = bytearray(data)
            for i in range(len(encoded)):
                encoded[i] ^= key
            return encoded

        def bupextract():
            # Check for valid OLE
            if not OleFileIO_PL.isOleFile(__sessions__.current.file.path):
                print_error("Not a valid BUP File")
                return
            ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
            # We know that BUPS are xor'd with 6A which is dec 106 for the decoder
            print_info("Switching Session to Embedded File")
            data = xordata(ole.openstream('File_0').read(), 106)
            # this is a lot of work jsut to get a filename.
            data2 = xordata(ole.openstream('Details').read(), 106)
            ole.close()
            lines = data2.split('\n')
            for line in lines:
                if line.startswith('OriginalName'):
                    fullpath = line.split('=')[1]
                    pathsplit = fullpath.split('\\')
                    filename = str(pathsplit[-1][:-1])
            # now lets write the data out to a file and get a session on it
            if data:
                tempName = os.path.join('/tmp', filename)
                with open(tempName, 'w') as temp:
                    temp.write(data)
                __sessions__.new(tempName)
                return
            else:
                print_error("Unble to Switch Session")

        # Run Functions
        try:
            opts, argv = getopt.getopt(self.args[0:], 'hs', ['help', 'session'])
        except getopt.GetoptError as e:
            print(e)
            return

        for opt, value in opts:
            if opt in ('-h', '--help'):
                help()
                return
            if opt in ('-s','--session'):
                bupextract()
                return

        # Check for valid OLE
        if not OleFileIO_PL.isOleFile(__sessions__.current.file.path):
            print_error("Not a valid BUP File")
            return

        ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
        # We know that BUPS are xor'd with 6A which is dec 106 for the decoder
        details = xordata(ole.openstream('Details').read(), 106)
        # the rest of this is just formating
        lines = details.split('\n')
        rows = []

        for line in lines:
            try:
                k,v = line.split('=')
                rows.append([k,v[:-1]]) #Strip the \r from v
            except:
                pass

        print_info("BUP Details:")
        print(table(header=['Description', 'Value'], rows=rows))

        ole.close()
예제 #31
0
파일: office.py 프로젝트: AresTao/viper
    def run(self):
        if not __sessions__.is_set():
            print_error("No session opened")
            return

        if not HAVE_OLE:
            print_error("Missing dependency, install OleFileIO (`pip install OleFileIO_PL`)")
            return

        def usage():
            print("usage: office [-hmsoe:]")

        def help():
            usage()
            print("")
            print("Options:")
            print("\t--help (-h)\tShow this help message")
            print("\t--meta (-m)\tGet the metadata")
            print("\t--oleid (-o)\tGet the OLE information")
            print("\t--streams (-s)\tShow the document streams")
            print("\t--export (-e)\tExport all objects (specify destination folder)")
            print("")

        # Tests to check for valid Office structures.
        OLE_FILE = OleFileIO_PL.isOleFile(__sessions__.current.file.path)
        XML_FILE = zipfile.is_zipfile(__sessions__.current.file.path)
        if OLE_FILE:
            ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
        elif XML_FILE:
            zip_xml = zipfile.ZipFile(__sessions__.current.file.path, 'r')
        else:
            print_error("Not a valid office document")
            return

        try:
            opts, argv = getopt.getopt(self.args[0:], 'hmsoe:', ['help', 'meta', 'streams', 'oleid', 'export:'])
        except getopt.GetoptError as e:
            print(e)
            return

        for opt, value in opts:
            if opt in ('-e', '--export'):
                if OLE_FILE:
                    self.export(ole, value)
                    return
                elif XML_FILE:
                    self.xml_export(zip_xml, value)
                    return
            if opt in ('-h', '--help'):
                help()
                return
            if opt in ('-m','--meta'):
                if OLE_FILE:
                    self.metadata(ole)
                    return
                elif XML_FILE:
                    self.xmlmeta(zip_xml)
                    return
            if opt in ('-s','--streams'):
                if OLE_FILE:
                    self.metatimes(ole)
                    return
                elif XML_FILE:
                    self.xmlstruct(zip_xml)
                    return
            if opt in ('-o','--oleid'):
                if OLE_FILE:
                    self.oleid(ole)
                    return
                else:
                    return

        usage()
예제 #32
0
 def test_isOleFile_true(self):
     is_ole = OleFileIO.isOleFile(self.ole_file)
     self.assertTrue(is_ole)
예제 #33
0
 def test_isOleFile_false(self):
     is_ole = OleFileIO.isOleFile(self.non_ole_file)
     self.assertFalse(is_ole)
예제 #34
0
파일: parseRS.py 프로젝트: jtmoran/parseRS
def readTDF(filePath, fileName, pad): 
    '''Parses the information stored in the tab data file.
    Accepts single argument: the file name of the tab data file.'''
    if fileName == "{00000000-0000-0000-0000-000000000000}.dat":
        return
    tdName = os.path.join(filePath, fileName)
    print(pad + fileName + ":")
    try:
        #Check if file is the correct format
        if not (OleFileIO_PL.isOleFile(tdName)):
            print("Unable to parse file '%s'. Incorrect format!" % tdname)
            return
        rs = OleFileIO_PL.OleFileIO(tdName)
        #Get list of streams
        streams = rs.listdir()
        #Get tab created time
        tGuid = fileName.replace("{", "").replace("}.dat", "")
        print(pad + "    Tab Created:  " + buildTime(tGuid) + " UTC")
        #Get travel order
        for s in streams:
            if(s[0] == "TravelLog"):
                tempStream = rs.openstream(s[0])
                data = tempStream.read()
                pos = 0
                travel = []
                while (pos < len(data)):
                    travel.append(struct.unpack('B', data[pos:pos+1])[0])
                    pos = pos + 4
                print(pad + "    Page Order:   " + '%s' % ', '.join(map(str, travel)))
        #Get all pages (TL#)
        sStreams = []
        for s in (streams):
            sStreams.append(s[0])
        p = rs.getproperties('\x05KjjaqfajN2c0uzgv1l4qy5nfWe')    
        print(pad + "    Current Page: " + p[3].rstrip('\0'))
        for s in (natural_sort(sStreams)):
            if((s[:2] == "TL") and (len(s[0]) < 6)):
                #Get page number
                tabNo = re.findall(r'\d+', s)
                tempStream = rs.openstream(s)
                data = tempStream.read()
                #Get URL info
                data_sub = bytes()
                i = 0
                while(i < len(data)) :
                    if (i % 2 == 0) :
                        data_sub += (data[i:i+1]) 
                    i = i + 1
                pattern = re.compile(b"[A-Za-z0-9/\-+:.,_$%?'()[\]=<> &]{5,500}")
                strings = pattern.findall(data_sub, 4)
                if (len(strings) > 0) :
                    print(pad + "    Page " + tabNo[0] + ":")
                    print(pad + "        URL:      " + strings[0].decode("ascii"))
                    print(pad + "        Title:    " + strings[1].decode("ascii"))
                    global verbose
                    if (verbose == 1):
                        ustrings = set(strings)
                        ustrings = list(ustrings)
                        print (pad + "        Strings:  " + ustrings[0].decode("ascii"))
                        n = 1
                        while n < len(ustrings):
                            print(pad + "                  " + ustrings[n].decode("ascii"))
                            n += 1
    except:
        print(pad + "Error reading '" + tdName + "': ", sys.exc_info()[1])
예제 #35
0
 def is_valid_format(cls, filename):
     return OleFile.isOleFile(filename)
	key = hashlib.md5(real_key + '\x00\x00\x00\x00').digest()
	dec = rc4_crypt(key, verifier + verifierHash)
	if hashlib.md5(dec[:16]).digest() == dec[16:]:
		print "valid pass"
	else:
		print "invalid pass"

	
if len(sys.argv) != 3:
	print "Usage: %s <xls file> <password>" % sys.argv[0]
	sys.exit(1)
	
xlsfile = sys.argv[1]

# Test if a file is an OLE container:
if not OleFileIO_PL.isOleFile(xlsfile):
	print "Invalid XLS file"
	sys.exit(1)

# Open OLE file:
ole = OleFileIO_PL.OleFileIO(xlsfile)

workbookStream = ole.openstream('Workbook')
if workbookStream == None:
	print "Invalid XLS file"
	sys.exit(1)
	
passinfo = find_rc4_passinfo(workbookStream)
if passinfo == None:
	print "Cannot find RC4 pass info"
else:
예제 #37
0
파일: debup.py 프로젝트: lnmyshkin/viper
    def run(self):
        if not __sessions__.is_set():
            print_error("No session opened")
            return

        if not HAVE_OLE:
            print_error(
                "Missing dependency, install OleFileIO (`pip install OleFileIO_PL`)"
            )
            return

        def xordata(data, key):
            encoded = bytearray(data)
            for i in range(len(encoded)):
                encoded[i] ^= key
            return encoded

        def bupextract():
            # Check for valid OLE
            if not OleFileIO_PL.isOleFile(__sessions__.current.file.path):
                print_error("Not a valid BUP File")
                return
            ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
            # We know that BUPS are xor'd with 6A which is dec 106 for the decoder
            print_info("Switching Session to Embedded File")
            data = xordata(ole.openstream('File_0').read(), 106)
            # this is a lot of work jsut to get a filename.
            data2 = xordata(ole.openstream('Details').read(), 106)
            ole.close()
            lines = data2.split('\n')
            for line in lines:
                if line.startswith('OriginalName'):
                    fullpath = line.split('=')[1]
                    pathsplit = fullpath.split('\\')
                    filename = str(pathsplit[-1][:-1])
            # now lets write the data out to a file and get a session on it
            if data:
                tempName = os.path.join('/tmp', filename)
                with open(tempName, 'w') as temp:
                    temp.write(data)
                __sessions__.new(tempName)
                return
            else:
                print_error("Unble to Switch Session")

        # Run Functions
        try:
            opts, argv = getopt.getopt(self.args[0:], 'hs',
                                       ['help', 'session'])
        except getopt.GetoptError as e:
            print(e)
            return

        for opt, value in opts:
            if opt in ('-h', '--help'):
                help()
                return
            if opt in ('-s', '--session'):
                bupextract()
                return

        # Check for valid OLE
        if not OleFileIO_PL.isOleFile(__sessions__.current.file.path):
            print_error("Not a valid BUP File")
            return

        ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
        # We know that BUPS are xor'd with 6A which is dec 106 for the decoder
        details = xordata(ole.openstream('Details').read(), 106)
        # the rest of this is just formating
        lines = details.split('\n')
        rows = []

        for line in lines:
            try:
                k, v = line.split('=')
                rows.append([k, v[:-1]])  #Strip the \r from v
            except:
                pass

        print_info("BUP Details:")
        print(table(header=['Description', 'Value'], rows=rows))

        ole.close()
예제 #38
0
파일: office.py 프로젝트: JeskeCode/viper
    def run(self):
        if not __sessions__.is_set():
            print_error("No session opened")
            return

        if not HAVE_OLE:
            print_error("Missing dependency, install OleFileIO (`pip install OleFileIO_PL`)")
            return

        def usage():
            print("usage: office [-hmsoe:]")

        def help():
            usage()
            print("")
            print("Options:")
            print("\t--help (-h)\tShow this help message")
            print("\t--meta (-m)\tGet The Metadata")
            print("\t--struct (-s)\tShow The Document Structure")
            print("\t--oleid (-o)\tGet The OLE Information")
            print("\t--export (-e)\tExport All Objects (specify destination folder)")
            print("")

        # Tests to check for valid Office structures
        OLE_FILE = OleFileIO_PL.isOleFile(__sessions__.current.file.path)
        XML_FILE = zipfile.is_zipfile(__sessions__.current.file.path)
        if OLE_FILE:
            ole = OleFileIO_PL.OleFileIO(__sessions__.current.file.path)
        elif XML_FILE:
            zip_xml = zipfile.ZipFile(__sessions__.current.file.path, "r")
        else:
            print_error("Not A Valid Office Document")
            return

        try:
            opts, argv = getopt.getopt(self.args[0:], "hmsoe:", ["help", "meta", "struct", "oleid", "export:"])
        except getopt.GetoptError as e:
            print(e)
            return

        for opt, value in opts:
            if opt in ("-e", "--export"):
                if OLE_FILE:
                    self.export(ole, value)
                    return
                elif XML_FILE:
                    self.xml_export(zip_xml, value)
                    return
            if opt in ("-h", "--help"):
                help()
                return
            if opt in ("-m", "--meta"):
                if OLE_FILE:
                    self.metadata(ole)
                    return
                elif XML_FILE:
                    self.xmlmeta(zip_xml)
                    return
            if opt in ("-s", "--struct"):
                if OLE_FILE:
                    self.metatimes(ole)
                    return
                elif XML_FILE:
                    self.xmlstruct(zip_xml)
                    return
            if opt in ("-o", "--oleid"):
                if OLE_FILE:
                    self.oleid(ole)
                    return
                else:
                    return

        usage()
예제 #39
0
import OleFileIO_PL as stickyread
import re
from os.path import expanduser


home = expanduser("~")
home = home + "\\AppData\\Roaming\\Microsoft\\Sticky Notes\\StickyNotes.snt"
assert stickyread.isOleFile(home)
ole = stickyread.OleFileIO(home)
print'Root mtime=%s ctime=%s' % (ole.root.getmtime(), ole.root.getctime())
i=0
for obj in ole.listdir(streams=True, storages=False):
    if(len(obj) == 2 and obj[1] == '0'):
        strm = ole.openstream(obj)
        print "obj %d" % i
        note =  strm.read()
        note = note.replace("\n", "")
        note = note.replace("\\par", "\n")
        note = note[note.find("\\fs22 ")+6:]
        note = note[:note.find("}")]
        note = re.sub(r"\\.*\s", "", note)
        print note #re.search(r'\\fs22[\s.]*', note).group(0)
        i+=1
# Close the OLE file:
ole.close()
예제 #40
0
 def is_valid_format(cls, filename):
     return OleFile.isOleFile(filename)
예제 #41
0
def readTDF(filePath, fileName, pad):
    '''Parses the information stored in the tab data file.
    Accepts single argument: the file name of the tab data file.'''
    if fileName == "{00000000-0000-0000-0000-000000000000}.dat":
        return
    tdName = os.path.join(filePath, fileName)
    print(pad + fileName + ":")
    try:
        #Check if file is the correct format
        if not (OleFileIO_PL.isOleFile(tdName)):
            print("Unable to parse file '%s'. Incorrect format!" % tdname)
            return
        rs = OleFileIO_PL.OleFileIO(tdName)
        #Get list of streams
        streams = rs.listdir()
        #Get tab created time
        tGuid = fileName.replace("{", "").replace("}.dat", "")
        print(pad + "    Tab Created:  " + buildTime(tGuid) + " UTC")
        #Get travel order
        for s in streams:
            if (s[0] == "TravelLog"):
                tempStream = rs.openstream(s[0])
                data = tempStream.read()
                pos = 0
                travel = []
                while (pos < len(data)):
                    travel.append(struct.unpack('B', data[pos:pos + 1])[0])
                    pos = pos + 4
                print(pad + "    Page Order:   " +
                      '%s' % ', '.join(map(str, travel)))
        #Get all pages (TL#)
        sStreams = []
        for s in (streams):
            sStreams.append(s[0])
        p = rs.getproperties('\x05KjjaqfajN2c0uzgv1l4qy5nfWe')
        print(pad + "    Current Page: " + p[3].rstrip('\0'))
        for s in (natural_sort(sStreams)):
            if ((s[:2] == "TL") and (len(s[0]) < 6)):
                #Get page number
                tabNo = re.findall(r'\d+', s)
                tempStream = rs.openstream(s)
                data = tempStream.read()
                #Get URL info
                data_sub = bytes()
                i = 0
                while (i < len(data)):
                    if (i % 2 == 0):
                        data_sub += (data[i:i + 1])
                    i = i + 1
                pattern = re.compile(
                    b"[A-Za-z0-9/\-+:.,_$%?'()[\]=<> &]{5,500}")
                strings = pattern.findall(data_sub, 4)
                if (len(strings) > 0):
                    print(pad + "    Page " + tabNo[0] + ":")
                    print(pad + "        URL:      " +
                          strings[0].decode("ascii"))
                    print(pad + "        Title:    " +
                          strings[1].decode("ascii"))
                    global verbose
                    if (verbose == 1):
                        ustrings = set(strings)
                        ustrings = list(ustrings)
                        print(pad + "        Strings:  " +
                              ustrings[0].decode("ascii"))
                        n = 1
                        while n < len(ustrings):
                            print(pad + "                  " +
                                  ustrings[n].decode("ascii"))
                            n += 1
    except:
        print(pad + "Error reading '" + tdName + "': ", sys.exc_info()[1])
예제 #42
0
 def test_isOleFile_false(self):
     is_ole = OleFileIO.isOleFile(self.non_ole_file)
     self.assertFalse(is_ole)
예제 #43
0
        elif o == "-o":
            outputFile = a
        elif o == "-v":
            verbose = True
        elif o == "-d":
            OleFileIO_PL.set_debug_mode(True)
        elif o == "-X":
            extractOLE = True
        else:
            usage(sys.argv[0])

    if not fName:
        usage(sys.argv[0])

    # Test if a file is an OLE container:
    if not OleFileIO_PL.isOleFile(fName):
        print "File %s is not an OLE file" % (fName)
        sys.exit(1)

    print "[*]Opening file %s" % (fName)

    # Open OLE file:
    ole = OleFileIO_PL.OleFileIO(fName)

    # Get list of storages/streams
    objs = ole.listdir()
    print "[*]Listing streams/storages:\n"
    ole.dumpdirectory()

    #
    if extractStream is not None:
예제 #44
0
 def test_isOleFile_true(self):
     is_ole = OleFileIO.isOleFile(self.ole_file)
     self.assertTrue(is_ole)
예제 #45
0
        elif o == "-o":
            outputFile = a
        elif o == "-v":
            verbose = True
        elif o == "-d":
            OleFileIO_PL.set_debug_mode(True)
        elif o == "-X":
            extractOLE = True
        else:
            usage(sys.argv[0])

    if not fName:
        usage(sys.argv[0])

    # Test if a file is an OLE container:
    if not OleFileIO_PL.isOleFile(fName):
        print "File %s is not an OLE file" % (fName)
        sys.exit(1)

    print "[*]Opening file %s" % (fName)

    # Open OLE file:
    ole = OleFileIO_PL.OleFileIO(fName)

    # Get list of storages/streams
    objs = ole.listdir()
    print "[*]Listing streams/storages:\n"
    ole.dumpdirectory()

    #
    if extractStream is not None:
예제 #46
0
import OleFileIO_PL

oleFile = "C:\\Users\\morrj140\\Dev\\GitRepository\\DirCrawler\\Introduction to GBTS - v1.1.pptx"

# Test if a file is an OLE container:
assert OleFileIO_PL.isOleFile(oleFile)

# Open an OLE file:
ole = OleFileIO_PL.OleFileIO(oleFile)

# Get list of streams:
print ole.listdir()

# Test if known streams/storages exist:
if ole.exists('worddocument'):
    print "This is a Word document."
    print "size :", ole.get_size('worddocument')
    if ole.exists('macros/vba'):
         print "This document seems to contain VBA macros."

# Extract the "Pictures" stream from a PPT file:
if ole.exists('Pictures'):
    pics = ole.openstream('Pictures')
    data = pics.read()
    f = open('Pictures.bin', 'w')
    f.write(data)
    f.close()

# Extract metadata (new in v0.24) - see source code for all attributes: meta = ole.get_metadata()
print 'Author:', meta.author
print 'Title:', meta.title