Exemple #1
0
 def __init__(self):
     self.datahandlers = {
         DataTypes.DATA: self.datahandler,
         DataTypes.DATE: self.datehandler,
         DataTypes.TEXT: self.texthandler
     }
     self.handlers = {
         ExtractStore.TYPE_TABLE: self._get_tablehtml,
         ExtractStore.TYPE_DATA: self._get_datahtml,
         ExtractStore.TYPE_XML: self._get_xmlhtml,
         ExtractStore.TYPE_IMAGE: self._get_imagehtml,
         ExtractStore.TYPE_STRING: self._get_asciistringhtml
     }
     self.mime = MimeGuesser()
Exemple #2
0
 def __init__(self,
              outqueue=None,
              extract_store=None,
              mountpoint=None,
              settings=None,
              versions=None):
     self.mimguess = MimeGuesser()
     self.outqueue = outqueue
     self.settings = settings
     self.versions = versions
     imp = Importer()
     app_modules = imp.get_package_modules("AndroidApps", IApp())
     for app in app_modules:
         name = app.get_packagename()
         if name in self.appstore:
             self.appstore[name].append(app)
         else:
             self.appstore[name] = [app]
     if extract_store != None:
         self.exstore = extract_store
     else:
         self.exstore = ExtractStore.ExtractStore()
Exemple #3
0
 def __init__(self):
     self.datahandlers = {
         DataTypes.DATA: self.datahandler,
         DataTypes.DATE: self.datehandler,
         DataTypes.TEXT: self.texthandler
     }
     self.handlers = { 
         ExtractStore.TYPE_TABLE: self._get_tablehtml,
         ExtractStore.TYPE_DATA: self._get_datahtml,
         ExtractStore.TYPE_XML: self._get_xmlhtml,
         ExtractStore.TYPE_IMAGE: self._get_imagehtml,
         ExtractStore.TYPE_STRING: self._get_asciistringhtml
     }
     self.mime = MimeGuesser()
 def __init__(self, outqueue=None, extract_store=None, mountpoint=None, 
              settings=None, versions=None ):
     self.mimguess = MimeGuesser()
     self.outqueue = outqueue
     self.settings = settings
     self.versions = versions
     imp = Importer()
     app_modules = imp.get_package_modules("AndroidApps", IApp())
     for app in app_modules:
         name = app.get_packagename()
         if name in self.appstore:
             self.appstore[name].append(app)
         else:
             self.appstore[name] = [app]
     if extract_store != None:
         self.exstore = extract_store
     else:
         self.exstore = ExtractStore.ExtractStore()
Exemple #5
0
class HtmlExtract(object):

    def __init__(self):
        self.datahandlers = {
            DataTypes.DATA: self.datahandler,
            DataTypes.DATE: self.datehandler,
            DataTypes.TEXT: self.texthandler
        }
        self.handlers = { 
            ExtractStore.TYPE_TABLE: self._get_tablehtml,
            ExtractStore.TYPE_DATA: self._get_datahtml,
            ExtractStore.TYPE_XML: self._get_xmlhtml,
            ExtractStore.TYPE_IMAGE: self._get_imagehtml,
            ExtractStore.TYPE_STRING: self._get_asciistringhtml
        }
        self.mime = MimeGuesser()
        
    def dump_file(self, appfile):
        html = ""
        if appfile.ftype == ExtractStore.TYPE_MULTI:
            navhead = """
            <div class="panel-heading">
                <ul class="nav nav-tabs">
            """
            navbody = """<div class="panel-body"><div class="tab-content">"""
            for contents in appfile.content:
                navhead += """<li><a data-toggle="tab" href="#{name}">{name}</a></li>""".format(name=contents.name)
                navbody += """<div id={name} class="tab-pane">""".format(name=contents.name)
                handler = None
                try:
                    handler=self.handlers[contents.ctype]
                except:
                    navbody += "No Handler Implemented"
                    #print "Bad Handler: " + appfile.name
                if handler != None:
                    navbody+=handler(contents.content,contents.tbl_info,contents.knowninfo)
                navbody += "</div>"
            navhead += "</ul></div>" #ul and panel-heading
            navbody += "</div></div>"
            html += """<div class="panel with-nav-tabs panel-default">
                    """ + navhead + navbody + """</div>"""
            #do the nav-tabs init here and add items
        else:
            handler = None
            try:
                handler = self.handlers[appfile.ftype]
            except:
                #print "No Handler: " + appfile.name
                html += "Error No Handler Implemented"
            if handler != None:
                html += handler(appfile.content, appfile.tbl_info)
        #html = html.encode("UTF-8")
        return html
    
    def dump_hex(self,appfile):
        if appfile.ftype == ExtractStore.TYPE_MULTI:
            if appfile.filepath == None:
                return "<p>Unexpected Error: no filepath specified</p>"
            try:
                f = open(appfile.filepath, "rb")
                content = f.read()
            except:
                return """
                <p>File {} not found. Please make sure that you haven't
                unmounted any images regarding this case
                """.format(cgi.escape(appfile.filepath))
            return self._get_datahtml(content)
        else:
            return self._get_datahtml(appfile.content)
    
    def dump_strings(self, appfile):
        if appfile.ftype == ExtractStore.TYPE_MULTI:
            if appfile.filepath == None:
                return "<p>Unexpected Error: no filepath specified</p>"
            try:
                f = open(appfile.filepath, "rb")
                content = f.read()
            except:
                return """
                <p>File {} not found. Please make sure that you haven't
                unmounted any images regarding this case
                """.format(cgi.escape(appfile.filepath))
            return self._get_stringshtml( self.restringsdump(content))
        else:
            return self._get_stringshtml(self.restringsdump(appfile.content))
    
    def datahandler(self, value):
        return """
                <button class="btn btn-primary btn-sm" onclick="hideshow(this);">
                Show Data <span class="glyphicon glyphicon-chevron-down"></span>
                </button>
                <pre style="display:none;">{hexdump}</pre>
        """.format(hexdump=self.hexdump(value))
        
    def datehandler(self, value):
        return """<span class="date">{value}</span>""".format(value=value)
    
    def texthandler(self,value):
        print "TEXTHANDLER CALLED"
        return "Unimplemented"
    
    def hexdump(self, src, length=16):
        if src == None:
            return "None"
        FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)])
        lines = []
        for c in xrange(0, len(src), length):
            chars = src[c:c+length]
            mhex = ' '.join(["%02x" % ord(x) for x in chars])
            printable = cgi.escape(''.join(["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.') for x in chars]))
            lines.append("%04x %-*s %s\n" % (c, length*3, mhex, printable))
        return ''.join(lines)
    
    def restringsdump(self, content):
        for match in re.finditer("[^\x00-\x1F\x7F-\xFF]{4,}", content):
            yield( match.start(), cgi.escape(match.group()) )
        
    def stringsdump(self, content, minlen=4):
        result = ""
        loc = 0
        for c in content:
            loc += 1
            if c in string.printable:
                result += c
                continue
            elif len(result) >= minlen:
                yield (loc, cgi.escape(result))
            result = ""
    def _parse_column(self, colname, value, tblinfo=None,knowntable=None,notd=False):
        ret = u""
        if isinstance( value, StringIO.StringIO ):
            value = value.buf
        if notd:
            valwrap = u"{value}"
        else:
            valwrap = u"<td>{value}</td>"
        knownfields = None
        if knowntable != None:
            knownfields = knowntable.knownfields
        if tblinfo != None:
            if colname in tblinfo:
                if tblinfo[colname] == "BLOB":
                    if value == None:
                        return valwrap.format(value="None")
                    mimetype = self.mime.get_buffermimetype(str(value), True)
                    if mimetype != None:
                        if mimetype.startswith("image/"):
                            return valwrap.format(value=self._get_imagehtml(value, {"mime":mimetype}))
                        elif mimetype.startswith("bplist"):
                            return valwrap.format(value=self._get_bplisthtml(value))
                    return valwrap.format(value=self.datahandler(value))
        try:
            if knownfields != None:
                if colname in knownfields:
                    return valwrap.format(value=self.datahandlers[knownfields[colname]](value))
            return valwrap.format(value=value)
        except Exception, e:
            if type(value) == StringIO:
                value = value.buf
            
            print traceback.format_exc()
            print "colname: {colname}".format(colname=colname)
            sys.stderr.write(repr(e) + "\n")
            # <button type="button" class="btn btn-primary btn-sm">Small button</button>
            return valwrap.format(value=self.datahandler(value))
        return ret
Exemple #6
0
class ApplicationParser(object):

    parser_name = "Android Application Parser"
    appstore = {}
    exstore = None

    def __init__(self,
                 outqueue=None,
                 extract_store=None,
                 mountpoint=None,
                 settings=None,
                 versions=None):
        self.mimguess = MimeGuesser()
        self.outqueue = outqueue
        self.settings = settings
        self.versions = versions
        imp = Importer()
        app_modules = imp.get_package_modules("AndroidApps", IApp())
        for app in app_modules:
            name = app.get_packagename()
            if name in self.appstore:
                self.appstore[name].append(app)
            else:
                self.appstore[name] = [app]
        if extract_store != None:
            self.exstore = extract_store
        else:
            self.exstore = ExtractStore.ExtractStore()

    def get_extractedstore(self):
        return self.exstore

    def get_package_list(self):
        return self.appstore.keys()

    def get_package(self, name):
        if name not in self.appstore:
            return None
        if len(self.appstore[name]) == 1:
            if self.appstore[name][0].has_defaultversion() == False:
                self.outqueue.put("Package {} is not default".format(name))
            return self.appstore[name][0]
        """
        If multiple entries for the same package exist, then we need to decide
        which one we should use
        """
        default = None
        appversion = self.versions.get_application_version(name)
        if appversion == None or appversion == "N/A":
            self.outqueue.put(
                "{} could not determine App version".format(name))
        else:
            try:
                appversion = int(appversion)
            except:
                pass
        for defn in self.appstore[name]:
            if defn.has_defaultversion:
                if default != None:
                    self.outqueue.put(
                        "{} has more than one default".format(name))
                default = defn
            if defn.has_version(appversion):
                return defn
        return default

    def handle_file(self, filename, dirpath, app):
        filepath = join(dirpath, filename)
        handler = self.mimguess.get_handler(filepath)
        knowninfo = app.get_file_info(filename)
        fobject = None
        if handler != None:
            fobject = handler(filename, filepath, knowninfo, self.outqueue,
                              self.settings)
        else:
            """
            This is a remote case where no handler can handle the file.
            However, the default handler for unknown files should always be the
            raw data handler
            """
            fobject = ExtractStore.ApplicationFile(filename,
                                                   ExtractStore.TYPE_NONE)
        fobject.set_mime(self.mimguess.get_filemime(filepath))
        fobject.add_sig(genfilesig(filepath, DEFAULT_HASHER))
        fobject.add_stats(os.stat(filepath))
        return fobject

    def scan_single_app_dir(self, dirroot, app, dirobject, store_app):
        for f in listdir(dirroot):
            filepath = join(dirroot, f)
            if isdir(filepath):
                subdirobject = dirobject.add_dir(f)
                self.scan_single_app_dir(filepath, app, subdirobject,
                                         store_app)
            elif islink(filepath):
                """Skip for now"""
                continue
            elif isfile(filepath):
                try:
                    dirobject.add_file(self.handle_file(f, dirroot, app))
                    store_app.totalfiles += 1
                except:
                    print("Error handling file %(fname)s" %
                          {'fname': join(dirroot, f)})
        return

    def read_link(self, linkpath):
        target_path = os.readlink(linkpath)
        if os.path.isabs(target_path):
            return target_path
        return join(dirname(linkpath), target_path)

    def scan_single_app(self, approot_path, app):
        #print "[APP]: " + app.get_packagename()
        if self.outqueue != None:
            self.outqueue.put("[APP]: " + app.get_packagename())
        store_app = self.exstore.create_application(app.get_packagename(),
                                                    app.get_canonicalname())
        rootdir = store_app.add_directory(approot_path)
        store_app.add_root_stats(os.stat(approot_path))
        for f in listdir(approot_path):
            filepath = join(approot_path, f)
            if isdir(filepath):
                dirobject = rootdir.add_dir(f)
                self.scan_single_app_dir(filepath, app, dirobject, store_app)
            elif islink(filepath):
                if filepath.endswith("lib"):
                    store_app.set_library_path(self.read_link(filepath))
            elif isfile(filepath):
                store_app.totalfiles += 1
                rootdir.add_file(self.handle_file(f, approot_path, app))
        return

    def scan_directory(self, root):
        for dfile in os.listdir(root):
            fqname = join(root, dfile)
            if isdir(fqname):
                app = self.get_package(dfile)
                if app == None:
                    app = IApp()
                    app.set_packagename(dfile)
                self.scan_single_app(fqname, app)
            else:
                print "Stray file found: " + fqname
                #self.handle_file(fqname, None)
        if self.outqueue != None:
            self.outqueue.put("Scanned Total Apps: " +
                              str(len(self.exstore.store)))
Exemple #7
0
class HtmlExtract(object):
    def __init__(self):
        self.datahandlers = {
            DataTypes.DATA: self.datahandler,
            DataTypes.DATE: self.datehandler,
            DataTypes.TEXT: self.texthandler
        }
        self.handlers = {
            ExtractStore.TYPE_TABLE: self._get_tablehtml,
            ExtractStore.TYPE_DATA: self._get_datahtml,
            ExtractStore.TYPE_XML: self._get_xmlhtml,
            ExtractStore.TYPE_IMAGE: self._get_imagehtml,
            ExtractStore.TYPE_STRING: self._get_asciistringhtml
        }
        self.mime = MimeGuesser()

    def dump_file(self, appfile):
        html = ""
        if appfile.ftype == ExtractStore.TYPE_MULTI:
            navhead = """
            <div class="panel-heading">
                <ul class="nav nav-tabs">
            """
            navbody = """<div class="panel-body"><div class="tab-content">"""
            for contents in appfile.content:
                navhead += """<li><a data-toggle="tab" href="#{name}">{name}</a></li>""".format(
                    name=contents.name)
                navbody += """<div id={name} class="tab-pane">""".format(
                    name=contents.name)
                handler = None
                try:
                    handler = self.handlers[contents.ctype]
                except:
                    navbody += "No Handler Implemented"
                    #print "Bad Handler: " + appfile.name
                if handler != None:
                    navbody += handler(contents.content, contents.tbl_info,
                                       contents.knowninfo)
                navbody += "</div>"
            navhead += "</ul></div>"  #ul and panel-heading
            navbody += "</div></div>"
            html += """<div class="panel with-nav-tabs panel-default">
                    """ + navhead + navbody + """</div>"""
            #do the nav-tabs init here and add items
        else:
            handler = None
            try:
                handler = self.handlers[appfile.ftype]
            except:
                #print "No Handler: " + appfile.name
                html += "Error No Handler Implemented"
            if handler != None:
                html += handler(appfile.content, appfile.tbl_info)
        #html = html.encode("UTF-8")
        return html

    def dump_hex(self, appfile):
        if appfile.ftype == ExtractStore.TYPE_MULTI:
            if appfile.filepath == None:
                return "<p>Unexpected Error: no filepath specified</p>"
            try:
                f = open(appfile.filepath, "rb")
                content = f.read()
            except:
                return """
                <p>File {} not found. Please make sure that you haven't
                unmounted any images regarding this case
                """.format(cgi.escape(appfile.filepath))
            return self._get_datahtml(content)
        else:
            return self._get_datahtml(appfile.content)

    def dump_strings(self, appfile):
        if appfile.ftype == ExtractStore.TYPE_MULTI:
            if appfile.filepath == None:
                return "<p>Unexpected Error: no filepath specified</p>"
            try:
                f = open(appfile.filepath, "rb")
                content = f.read()
            except:
                return """
                <p>File {} not found. Please make sure that you haven't
                unmounted any images regarding this case
                """.format(cgi.escape(appfile.filepath))
            return self._get_stringshtml(self.restringsdump(content))
        else:
            return self._get_stringshtml(self.restringsdump(appfile.content))

    def datahandler(self, value):
        return """
                <button class="btn btn-primary btn-sm" onclick="hideshow(this);">
                Show Data <span class="glyphicon glyphicon-chevron-down"></span>
                </button>
                <pre style="display:none;">{hexdump}</pre>
        """.format(hexdump=self.hexdump(value))

    def datehandler(self, value):
        return """<span class="date">{value}</span>""".format(value=value)

    def texthandler(self, value):
        print "TEXTHANDLER CALLED"
        return "Unimplemented"

    def hexdump(self, src, length=16):
        if src == None:
            return "None"
        FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.'
                          for x in range(256)])
        lines = []
        for c in xrange(0, len(src), length):
            chars = src[c:c + length]
            mhex = ' '.join(["%02x" % ord(x) for x in chars])
            printable = cgi.escape(''.join([
                "%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.')
                for x in chars
            ]))
            lines.append("%04x %-*s %s\n" % (c, length * 3, mhex, printable))
        return ''.join(lines)

    def restringsdump(self, content):
        for match in re.finditer("[^\x00-\x1F\x7F-\xFF]{4,}", content):
            yield (match.start(), cgi.escape(match.group()))

    def stringsdump(self, content, minlen=4):
        result = ""
        loc = 0
        for c in content:
            loc += 1
            if c in string.printable:
                result += c
                continue
            elif len(result) >= minlen:
                yield (loc, cgi.escape(result))
            result = ""

    def _parse_column(self,
                      colname,
                      value,
                      tblinfo=None,
                      knowntable=None,
                      notd=False):
        ret = u""
        if isinstance(value, StringIO.StringIO):
            value = value.buf
        if notd:
            valwrap = u"{value}"
        else:
            valwrap = u"<td>{value}</td>"
        knownfields = None
        if knowntable != None:
            knownfields = knowntable.knownfields
        if tblinfo != None:
            if colname in tblinfo:
                if tblinfo[colname] == "BLOB":
                    if value == None:
                        return valwrap.format(value="None")
                    mimetype = self.mime.get_buffermimetype(str(value), True)
                    if mimetype != None:
                        if mimetype.startswith("image/"):
                            return valwrap.format(value=self._get_imagehtml(
                                value, {"mime": mimetype}))
                        elif mimetype.startswith("bplist"):
                            return valwrap.format(
                                value=self._get_bplisthtml(value))
                    return valwrap.format(value=self.datahandler(value))
        try:
            if knownfields != None:
                if colname in knownfields:
                    return valwrap.format(
                        value=self.datahandlers[knownfields[colname]](value))
            return valwrap.format(value=value)
        except Exception, e:
            if type(value) == StringIO:
                value = value.buf

            print traceback.format_exc()
            print "colname: {colname}".format(colname=colname)
            sys.stderr.write(repr(e) + "\n")
            # <button type="button" class="btn btn-primary btn-sm">Small button</button>
            return valwrap.format(value=self.datahandler(value))
        return ret
class ApplicationParser(object):
    
    parser_name = "Android Application Parser"
    appstore = {}
    exstore = None        
    def __init__(self, outqueue=None, extract_store=None, mountpoint=None, 
                 settings=None, versions=None ):
        self.mimguess = MimeGuesser()
        self.outqueue = outqueue
        self.settings = settings
        self.versions = versions
        imp = Importer()
        app_modules = imp.get_package_modules("AndroidApps", IApp())
        for app in app_modules:
            name = app.get_packagename()
            if name in self.appstore:
                self.appstore[name].append(app)
            else:
                self.appstore[name] = [app]
        if extract_store != None:
            self.exstore = extract_store
        else:
            self.exstore = ExtractStore.ExtractStore()
           
    def get_extractedstore(self):
            return self.exstore
        
    def get_package_list(self):
        return self.appstore.keys()
    
    def get_package(self, name):
        if name not in self.appstore:
            return None
        if len(self.appstore[name]) == 1:
            if self.appstore[name][0].has_defaultversion() == False:
                self.outqueue.put("Package {} is not default".format(name))
            return self.appstore[name][0]
        
        """
        If multiple entries for the same package exist, then we need to decide
        which one we should use
        """
        default = None
        appversion = self.versions.get_application_version(name)
        if appversion == None or appversion == "N/A":
            self.outqueue.put("{} could not determine App version".format(name))
        else:
            try:
                appversion = int(appversion)
            except:
                pass
        for defn in self.appstore[name]:
            if defn.has_defaultversion:
                if default != None: 
                    self.outqueue.put("{} has more than one default".format(name))
                default = defn
            if defn.has_version(appversion):
                return defn
        return default
    
    def handle_file(self, filename, dirpath, app):
        filepath = join(dirpath,filename)
        handler = self.mimguess.get_handler(filepath)
        knowninfo = app.get_file_info(filename)
        fobject = None
        if handler != None:
            fobject = handler(filename,filepath,knowninfo,self.outqueue,
                              self.settings)
        else:
            """
            This is a remote case where no handler can handle the file.
            However, the default handler for unknown files should always be the
            raw data handler
            """
            fobject = ExtractStore.ApplicationFile(filename,
                                                   ExtractStore.TYPE_NONE)
        fobject.set_mime(self.mimguess.get_filemime(filepath))
        fobject.add_sig(genfilesig(filepath, DEFAULT_HASHER))
        fobject.add_stats(os.stat(filepath))
        return fobject
        
        
    
    def scan_single_app_dir(self, dirroot, app, dirobject, store_app):
        for f in listdir(dirroot):
            filepath = join(dirroot,f)
            if isdir(filepath): 
                subdirobject = dirobject.add_dir(f)
                self.scan_single_app_dir(filepath, app, subdirobject, store_app)
            elif islink(filepath):
                """Skip for now"""
                continue
            elif isfile(filepath):
                store_app.totalfiles += 1
                dirobject.add_file(self.handle_file(f, dirroot, app))
        return
    
    
    def read_link(self, linkpath):
        target_path = os.readlink(linkpath)
        if os.path.isabs(target_path):
            return target_path
        return join(dirname(linkpath),target_path)
    
    def scan_single_app(self, approot_path, app):
        #print "[APP]: " + app.get_packagename()
        if self.outqueue != None:
            self.outqueue.put("[APP]: " + app.get_packagename())
        store_app = self.exstore.create_application(
                                app.get_packagename(), app.get_canonicalname())
        rootdir = store_app.add_directory(approot_path)
        store_app.add_root_stats( os.stat(approot_path) )
        for f in listdir(approot_path):
            filepath = join(approot_path,f)
            if isdir(filepath):
                dirobject = rootdir.add_dir(f)
                self.scan_single_app_dir(filepath, app, dirobject, store_app)
            elif islink(filepath):
                if filepath.endswith("lib"):
                    store_app.set_library_path(self.read_link(filepath))
            elif isfile(filepath):
                store_app.totalfiles += 1
                rootdir.add_file(self.handle_file(f,approot_path,app))
        return
    
    def scan_directory(self, root):
        for dfile in os.listdir(root):
            fqname = join(root,dfile)
            if isdir( fqname ):
                app = self.get_package( dfile )
                if app == None:
                    app = IApp()
                    app.set_packagename( dfile )
                self.scan_single_app( fqname, app )
            else:
                print "Stray file found: " + fqname
                #self.handle_file(fqname, None)
        if self.outqueue != None:
            self.outqueue.put("Scanned Total Apps: " + str(len(self.exstore.store)) )