コード例 #1
0
ファイル: graph.py プロジェクト: delta24/mobsec
    def addInvokePath(self, src, through, dst):
        src_class_name, src_method_name, src_descriptor = src
        dst_class_name, dst_method_name, dst_descriptor = dst
        through_class_name, through_method_name, through_descriptor = through
        key = "%s %s %s %s %s %s %s" % (src_class_name,
                                        src_method_name,
                                        src_descriptor,
                                        through_class_name,
                                        through_method_name,
                                        through_descriptor,
                                        POSTFIX_REFL_INVOKE)
        n1 = self._get_existed_node(key)
        if n1 is None:
            logger.warning("Something wrong has happened! Could not find invoke Node in Graph with key [%s]" % str(key))
            return

        n2 = self._get_node(NODE_METHOD, (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)

        # check if called method calls protected feature
        data = "%s-%s-%s" % (dst_class_name, dst_method_name, dst_descriptor)
        if data in DVM_PERMISSIONS_BY_API_CALLS:
            logger.info("BINGOOOOOOO! The protected method is called through reflection!")
            perm = DVM_PERMISSIONS_BY_API_CALLS[data]
            key1 = "%s %s %s %s %s %s %s %s" % \
                   (through_class_name,
                    through_method_name,
                    through_descriptor,
                    dst_class_name,
                    dst_method_name,
                    dst_descriptor,
                    POSTFIX_PERM,
                    perm)
            n3 = self._get_node(NODE_FAKE_PERMISSION, key1, perm, False)
            n3.set_attribute(ATTR_CLASS_NAME, dst_class_name)
            n3.set_attribute(ATTR_METHOD_NAME, dst_method_name)
            n3.set_attribute(ATTR_DESCRIPTOR, dst_descriptor)
            n3.set_attribute(ATTR_PERM_NAME, perm)
            n3.set_attribute(ATTR_PERM_LEVEL, MANIFEST_PERMISSIONS[perm][0])
            self.G.add_edge(n2.id, n3.id)
コード例 #2
0
ファイル: graph.py プロジェクト: delta24/mobsec
    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 is 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 is not None:
            for i in apk.get_activities():
                j = bytecode.FormatClassToJava(i)
                n1 = self._get_existed_node((j, "onCreate", "(Landroid/os/Bundle;)V"))
                if n1 is not 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 is not 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 is 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)
                # print 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 is 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)