Esempio n. 1
0
    def __init__(self, vmx, apk) :
        self.vmx = vmx
        self.vm = self.vmx.get_vm()

        self.nodes = {}
        self.nodes_id = {}
        self.entry_nodes = [] 
        self.G = DiGraph()

        for j in self.vmx.get_tainted_packages().get_internal_packages() :
            n1 = self._get_node( j.get_method().get_class_name(), j.get_method().get_name(), j.get_method().get_descriptor() )
            n2 = self._get_node( j.get_class_name(), j.get_name(), j.get_descriptor() )

            self.G.add_edge( n1.id, n2.id )
            n1.add_edge( n2, j )
        #    print "\t %s %s %s %x ---> %s %s %s" % (j.get_method().get_class_name(), j.get_method().get_name(), j.get_method().get_descriptor(), \
        #                                            j.get_bb().start + j.get_idx(), \
        #                                            j.get_class_name(), j.get_name(), j.get_descriptor())

        if apk != None :
            for i in apk.get_activities() :
                j = bytecode.FormatClassToJava(i)
                n1 = self._get_exist_node( j, "onCreate", "(Landroid/os/Bundle;)V" )
                if n1 != None : 
                    n1.set_attributes( { "type" : "activity" } )
                    n1.set_attributes( { "color" : ACTIVITY_COLOR } )
                    n2 = self._get_new_node_from( n1, "ACTIVITY" )
                    n2.set_attributes( { "color" : ACTIVITY_COLOR } )
                    self.G.add_edge( n2.id, n1.id )
                    self.entry_nodes.append( n1.id )
            for i in apk.get_services() :
                j = bytecode.FormatClassToJava(i)
                n1 = self._get_exist_node( j, "onCreate", "()V" )
                if n1 != None : 
                    n1.set_attributes( { "type" : "service" } )
                    n1.set_attributes( { "color" : SERVICE_COLOR } )
                    n2 = self._get_new_node_from( n1, "SERVICE" )
                    n2.set_attributes( { "color" : SERVICE_COLOR } )
                    self.G.add_edge( n2.id, n1.id )
                    self.entry_nodes.append( n1.id )
            for i in apk.get_receivers() :
                j = bytecode.FormatClassToJava(i)
                n1 = self._get_exist_node( j, "onReceive", "(Landroid/content/Context; Landroid/content/Intent;)V" )
                if n1 != None : 
                    n1.set_attributes( { "type" : "receiver" } )
                    n1.set_attributes( { "color" : RECEIVER_COLOR } )
                    n2 = self._get_new_node_from( n1, "RECEIVER" )
                    n2.set_attributes( { "color" : RECEIVER_COLOR } )
                    self.G.add_edge( n2.id, n1.id )
                    self.entry_nodes.append( n1.id )

        # Specific Java/Android library
        for c in self.vm.get_classes() :
            #if c.get_superclassname() == "Landroid/app/Service;" :
            #    n1 = self._get_node( c.get_name(), "<init>", "()V" )
            #    n2 = self._get_node( c.get_name(), "onCreate", "()V" )

            #    self.G.add_edge( n1.id, n2.id )
            if c.get_superclassname() == "Ljava/lang/Thread;" or c.get_superclassname() == "Ljava/util/TimerTask;" :
                for i in self.vm.get_method("run") :
                    if i.get_class_name() == c.get_name() :
                        n1 = self._get_node( i.get_class_name(), i.get_name(), i.get_descriptor() )
                        n2 = self._get_node( i.get_class_name(), "start", i.get_descriptor() ) 
                       
                        # link from start to run
                        self.G.add_edge( n2.id, n1.id )
                        n2.add_edge( n1, {} )

                        # link from init to start
                        for init in self.vm.get_method("<init>") :
                            if init.get_class_name() == c.get_name() :
                                n3 = self._get_node( init.get_class_name(), "<init>", init.get_descriptor() )
                                #n3 = self._get_node( i.get_class_name(), "<init>", i.get_descriptor() )
                                self.G.add_edge( n3.id, n2.id )
                                n3.add_edge( n2, {} )

            #elif c.get_superclassname() == "Landroid/os/AsyncTask;" :
            #    for i in self.vm.get_method("doInBackground") :
            #        if i.get_class_name() == c.get_name() :
            #            n1 = self._get_node( i.get_class_name(), i.get_name(), i.get_descriptor() )
            #            n2 = self._get_exist_node( i.get_class_name(), "execute", i.get_descriptor() )
            #            print n1, n2, i.get_descriptor()
                        #for j in self.vm.get_method("doInBackground") :
                        #    n2 = self._get_exist_node( i.get_class_name(), j.get_name(), j.get_descriptor() )
                        #    print n1, n2
                        # n2 = self._get_node( i.get_class_name(), "
            #    raise("ooo")

        #for j in self.vmx.tainted_packages.get_internal_new_packages() :
        #    print "\t %s %s %s %x ---> %s %s %s" % (j.get_method().get_class_name(), j.get_method().get_name(), j.get_method().get_descriptor(), \
        #                                            j.get_bb().start + j.get_idx(), \
        #                                            j.get_class_name(), j.get_name(), j.get_descriptor())


        list_permissions = self.vmx.get_permissions( [] ) 
        for x in list_permissions :
            for j in list_permissions[ x ] :
                #print "\t %s %s %s %x ---> %s %s %s" % (j.get_method().get_class_name(), j.get_method().get_name(), j.get_method().get_descriptor(), \
                #                                    j.get_bb().start + j.get_idx(), \
                #                                    j.get_class_name(), j.get_name(), j.get_descriptor())
                n1 = self._get_exist_node( j.get_method().get_class_name(), j.get_method().get_name(), j.get_method().get_descriptor() )

                if n1 == None :
                    continue

                n1.set_attributes( { "permissions" : 1 } )
                n1.set_attributes( { "permissions_level" : DVM_PERMISSIONS[ "MANIFEST_PERMISSION" ][ x ][0] } )
                n1.set_attributes( { "permissions_details" : x } )

                try :
                    for tmp_perm in PERMISSIONS_RISK[ x ] :
                        if tmp_perm in DEFAULT_RISKS :
                            n2 = self._get_new_node( j.get_method().get_class_name(), j.get_method().get_name(), j.get_method().get_descriptor() + " " + DEFAULT_RISKS[ tmp_perm ][0],
                                                     DEFAULT_RISKS[ tmp_perm ][0] )
                            n2.set_attributes( { "color" : DEFAULT_RISKS[ tmp_perm ][1] } )
                            self.G.add_edge( n2.id, n1.id )

                            n1.add_risk( DEFAULT_RISKS[ tmp_perm ][0] )
                            n1.add_api( x, j.get_class_name() + "-" + j.get_name() + "-" + j.get_descriptor() )
                except KeyError :
                    pass

        # Tag DexClassLoader
        for m, _ in self.vmx.get_tainted_packages().get_packages() :
            if m.get_info() == "Ldalvik/system/DexClassLoader;" :
                for path in m.get_paths() :
                    if path.get_access_flag() == TAINTED_PACKAGE_CREATE :
                        n1 = self._get_exist_node( path.get_method().get_class_name(), path.get_method().get_name(), path.get_method().get_descriptor() )    
                        n2 = self._get_new_node( path.get_method().get_class_name(), path.get_method().get_name(), path.get_method().get_descriptor() + " " + "DEXCLASSLOADER",
                                                 "DEXCLASSLOADER" )

                        n1.set_attributes( { "dynamic_code" : "true" } )
                        n2.set_attributes( { "color" : DEXCLASSLOADER_COLOR } )
                        self.G.add_edge( n2.id, n1.id )
                        
                        n1.add_risk( "DEXCLASSLOADER" )
Esempio n. 2
0
    def analyseFile(self, vmx, apk):
        vm = vmx.get_vm()
        self.androGuardObjects.append((apk, vm, vmx))

        #         self.internal_methods.extend(vm.get_methods())

        #creating real internal nodes
        internal_called_methods = vmx.get_tainted_packages(
        ).stadyna_get_internal_called_methods()
        for method in internal_called_methods:
            class_name, method_name, descriptor = method

            nodeType = None
            if method_name == "<clinit>":
                nodeType = NODE_STATIC_INIT
            elif method_name == "<init>":
                nodeType = NODE_CONSTRUCTOR
            else:
                nodeType = NODE_METHOD
            n = self._get_node(nodeType, (class_name, method_name, descriptor))
            n.set_attribute(ATTR_CLASS_NAME, class_name)
            n.set_attribute(ATTR_METHOD_NAME, method_name)
            n.set_attribute(ATTR_DESCRIPTOR, descriptor)
            self.G.add_node(n.id)

        #creating real edges (nodes are already there)
        #currently we are working only with internal packages.
        for j in vmx.get_tainted_packages().get_internal_packages():
            src_class_name, src_method_name, src_descriptor = j.get_src(
                vm.get_class_manager())
            dst_class_name, dst_method_name, dst_descriptor = j.get_dst(
                vm.get_class_manager())

            n1 = self._get_existed_node(
                (src_class_name, src_method_name, src_descriptor))
            #             n1.set_attribute(ATTR_CLASS_NAME, src_class_name)
            #             n1.set_attribute(ATTR_METHOD_NAME, src_method_name)
            #             n1.set_attribute(ATTR_DESCRIPTOR, src_descriptor)

            n2 = self._get_existed_node(
                (dst_class_name, dst_method_name, dst_descriptor))
            #             n2.set_attribute(ATTR_CLASS_NAME, dst_class_name)
            #             n2.set_attribute(ATTR_METHOD_NAME, dst_method_name)
            #             n2.set_attribute(ATTR_DESCRIPTOR, dst_descriptor)
            self.G.add_edge(n1.id, n2.id)

        #adding fake class nodes
        for method in internal_called_methods:
            src_class_name, src_method_name, src_descriptor = method
            if src_method_name == "<init>" or src_method_name == "<clinit>":
                n1 = self._get_existed_node(
                    (src_class_name, src_method_name, src_descriptor))
                n2 = self._get_node(NODE_FAKE_CLASS, src_class_name, None,
                                    False)
                n2.set_attribute(ATTR_CLASS_NAME, src_class_name)
                if src_method_name == "<clinit>":
                    self.G.add_edge(n1.id, n2.id)
                elif src_method_name == "<init>":
                    self.G.add_edge(n2.id, n1.id)

        #real (external) reflection invoke nodes
        reflection_invoke_paths = analysis.seccon_get_invoke_method_paths(vmx)
        for j in reflection_invoke_paths:
            src_class_name, src_method_name, src_descriptor = j.get_src(
                vm.get_class_manager())
            dst_class_name, dst_method_name, dst_descriptor = j.get_dst(
                vm.get_class_manager())

            n1 = self._get_existed_node(
                (src_class_name, src_method_name, src_descriptor))
            if n1 == None:
                logger.warning(
                    "Cannot find the node [%s], where reflection invoke is called!"
                    % (src_class_name, src_method_name, src_descriptor))
                continue

            key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name,
                                            src_descriptor, dst_class_name,
                                            dst_method_name, dst_descriptor,
                                            POSTFIX_REFL_INVOKE)
            n2 = self._get_node(NODE_REFL_INVOKE, key, LABEL_REFL_INVOKE, True)
            n2.set_attribute(ATTR_CLASS_NAME, src_class_name)
            n2.set_attribute(ATTR_METHOD_NAME, src_method_name)
            n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor)

            self.G.add_edge(n1.id, n2.id)

        #real (external) reflection new instance nodes
        reflection_newInstance_paths = analysis.seccon_get_newInstance_method_paths(
            vmx)
        for j in reflection_newInstance_paths:
            src_class_name, src_method_name, src_descriptor = j.get_src(
                vm.get_class_manager())
            dst_class_name, dst_method_name, dst_descriptor = j.get_dst(
                vm.get_class_manager())

            n1 = self._get_existed_node(
                (src_class_name, src_method_name, src_descriptor))
            if n1 == None:
                logger.warning(
                    "Cannot find the node [%s], where reflection new instance is called!"
                    % (src_class_name, src_method_name, src_descriptor))
                continue

            key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name,
                                            src_descriptor, dst_class_name,
                                            dst_method_name, dst_descriptor,
                                            POSTFIX_REFL_NEWINSTANCE)
            n2 = self._get_node(NODE_REFL_NEWINSTANCE, key,
                                LABEL_REFL_NEWINSTANCE, True)
            n2.set_attribute(ATTR_CLASS_NAME, src_class_name)
            n2.set_attribute(ATTR_METHOD_NAME, src_method_name)
            n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor)

            self.G.add_edge(n1.id, n2.id)

        #adding fake entry points
        if apk != None:
            for i in apk.get_activities():
                j = bytecode.FormatClassToJava(i)
                n1 = self._get_existed_node(
                    (j, "onCreate", "(Landroid/os/Bundle;)V"))
                if n1 != None:
                    key = "%s %s %s %s" % (j, "onCreate",
                                           "(Landroid/os/Bundle;)V",
                                           POSTFIX_ACTIVITY)
                    n2 = self._get_node(NODE_FAKE_ACTIVITY, key,
                                        LABEL_ACTIVITY, False)
                    self.G.add_edge(n2.id, n1.id)
                    self.entry_nodes.append(n1.id)

            for i in apk.get_services():
                j = bytecode.FormatClassToJava(i)
                n1 = self._get_existed_node((j, "onCreate", "()V"))
                if n1 != None:
                    key = "%s %s %s %s" % (j, "onCreate", "()V",
                                           POSTFIX_SERVICE)
                    n2 = self._get_node(NODE_FAKE_SERVICE, key, LABEL_SERVICE,
                                        False)
                    self.G.add_edge(n2.id, n1.id)
                    self.entry_nodes.append(n1.id)

            for i in apk.get_receivers():
                j = bytecode.FormatClassToJava(i)
                n1 = self._get_existed_node(
                    (j, "onReceive",
                     "(Landroid/content/Context;Landroid/content/Intent;)V"))
                if n1 != None:
                    key = "%s %s %s %s" % (
                        j, "onReceive",
                        "(Landroid/content/Context;Landroid/content/Intent;)V",
                        POSTFIX_RECEIVER)
                    n2 = self._get_node(NODE_FAKE_SERVICE, key, LABEL_RECEIVER,
                                        False)
                    self.G.add_edge(n2.id, n1.id)
                    self.entry_nodes.append(n1.id)

        #fake permissions
        list_permissions = vmx.stadyna_get_permissions([])
        for x in list_permissions:
            for j in list_permissions[x]:
                if isinstance(j, PathVar):
                    continue

                src_class_name, src_method_name, src_descriptor = j.get_src(
                    vm.get_class_manager())
                dst_class_name, dst_method_name, dst_descriptor = j.get_dst(
                    vm.get_class_manager())

                n1 = self._get_existed_node(
                    (src_class_name, src_method_name, src_descriptor))
                if n1 == None:
                    logger.warning(
                        "Cannot find node [%s %s %s] for permission [%s]!" %
                        (src_class_name, src_method_name, src_descriptor, x))
                    continue

                #SOURCE, DEST, POSTFIX, PERMISSION_NAME
                key = "%s %s %s %s %s %s %s %s" % (
                    src_class_name, src_method_name, src_descriptor,
                    dst_class_name, dst_method_name, dst_descriptor,
                    POSTFIX_PERM, x)
                n2 = self._get_node(NODE_FAKE_PERMISSION, key, x, False)
                n2.set_attribute(ATTR_CLASS_NAME, dst_class_name)
                n2.set_attribute(ATTR_METHOD_NAME, dst_method_name)
                n2.set_attribute(ATTR_DESCRIPTOR, dst_descriptor)
                n2.set_attribute(ATTR_PERM_NAME, x)
                n2.set_attribute(ATTR_PERM_LEVEL, MANIFEST_PERMISSIONS[x][0])

                self.G.add_edge(n1.id, n2.id)

        #fake DexClassLoader nodes
        dyn_code_loading = analysis.seccon_get_dyncode_loading_paths(vmx)
        for j in dyn_code_loading:
            src_class_name, src_method_name, src_descriptor = j.get_src(
                vm.get_class_manager())
            dst_class_name, dst_method_name, dst_descriptor = j.get_dst(
                vm.get_class_manager())

            n1 = self._get_existed_node(
                (src_class_name, src_method_name, src_descriptor))
            if n1 == None:
                logger.warning(
                    "Cannot find dexload node [%s]!" %
                    (src_class_name, src_method_name, src_descriptor))
                continue

            key = "%s %s %s %s %s %s %s" % (src_class_name, src_method_name,
                                            src_descriptor, dst_class_name,
                                            dst_method_name, dst_descriptor,
                                            POSTFIX_DEXLOAD)
            n2 = self._get_node(NODE_FAKE_DEXLOAD, key, LABEL_DEXLOAD, False)
            n2.set_attribute(ATTR_CLASS_NAME, src_class_name)
            n2.set_attribute(ATTR_METHOD_NAME, src_method_name)
            n2.set_attribute(ATTR_DESCRIPTOR, src_descriptor)

            self.G.add_edge(n1.id, n2.id)

        # Specific Java/Android library
        for c in vm.get_classes():
            #if c.get_superclassname() == "Landroid/app/Service;" :
            #    n1 = self._get_node( c.get_name(), "<init>", "()V" )
            #    n2 = self._get_node( c.get_name(), "onCreate", "()V" )

            #    self.G.add_edge( n1.id, n2.id )
            if c.get_superclassname(
            ) == "Ljava/lang/Thread;" or c.get_superclassname(
            ) == "Ljava/util/TimerTask;":
                for i in vm.get_method("run"):
                    if i.get_class_name() == c.get_name():
                        n1 = self._get_node(NODE_METHOD,
                                            (i.get_class_name(), i.get_name(),
                                             i.get_descriptor()))
                        n2 = self._get_node(
                            NODE_METHOD,
                            (i.get_class_name(), "start", i.get_descriptor()))

                        # link from start to run
                        self.G.add_edge(n2.id, n1.id)
                        #n2.add_edge( n1, {} )

                        # link from init to start
                        for init in vm.get_method("<init>"):
                            if init.get_class_name() == c.get_name():
                                #TODO: Leaving _get_existed_node to check if all the nodes are included
                                #It is possible that internal_packages does not contain this node. Leaving _get_existed_node to check this
                                n3 = self._get_node(
                                    NODE_CONSTRUCTOR,
                                    (init.get_class_name(), "<init>",
                                     init.get_descriptor()))
                                self.G.add_edge(n3.id, n2.id)