Exemple #1
0
 def get_cert(self):
     try:
         pinfo("开始获取签名文件")
         files = [
             f for f in os.listdir(self.cert_file)
             if os.path.isfile(os.path.join(self.cert_file, f))
         ]
         for file_name in files:
             if file_name.lower().split('.')[-1] in ['rsa', 'dsa']:
                 args = [
                     ToolSettings.JAVA_PATH, '-jar',
                     ToolSettings.TOOL_CERTPRINT,
                     os.path.join(self.cert_file, file_name)
                 ]
                 issued = 'good'
                 dat = subprocess.check_output(args)
                 if re.findall(
                         r"Issuer: CN=Android Debug|Subject: CN=Android Debug",
                         dat):
                     issued = 'bad'
                 if re.findall(r"\[SHA1withRSA\]", dat):
                     issued = 'bad hash'
                 result = {
                     'cert_file': file_name,
                     'cert_info': dat,
                     'issued': issued
                 }
                 return result
     except:
         einfo("签名获取异常")
def elf_analysis(app_dir, typ):
    """Perform the elf analysis."""
    try:
        print "[INFO] Static Android Binary Analysis Started"
        elf_desc = {
            'elf_no_pi':
            (u'Found elf built without Position Independent Executable (PIE) flag',
             u'high',
             u'In order to prevent an attacker from reliably jumping to, for example, a particular'
             u' exploited function in memory, Address space layout randomization (ASLR) randomly '
             u'arranges the address space positions of key data areas of a process, including the '
             u'base of the executable and the positions of the stack, heap and libraries. Built with'
             u' option <strong>-pie</strong>.'),
            'elf_no_sp':
            (u'Found elf built without Stack Protection', u'high',
             u'Stack canaries can greatly increase the difficulty of exploiting a stack buffer '
             u'overflow because it forces the attacker to gain control of the instruction pointer'
             u' by some non-traditional means such as corrupting other important variables on the'
             u' stack. Built with option <strong>-fstack-protector</strong>.'),
        }
        elf_an_dic = {}
        for k in elf_desc.keys():
            elf_an_dic[k] = []
        libdir = os.path.join(app_dir, "lib")
        if os.path.exists(libdir):
            for pdir, dirl, filel in os.walk(libdir):
                for filename in filel:
                    if filename.endswith(".so"):
                        try:
                            filepath = os.path.join(pdir, filename)
                            f = io.open(filepath, mode='rb')
                            has_pie, has_sg = check_elf_built(f)
                            f.close()
                            if has_pie == False:
                                if "nopie" in filename or "nonpie" in filename or "no-pie" in filename:
                                    pass
                                else:
                                    elf_an_dic['elf_no_pi'].append(
                                        filepath.replace(libdir, "lib"))
                            if has_sg == False:
                                elf_an_dic['elf_no_sp'].append(
                                    filepath.replace(libdir, "lib"))
                        except Exception as e:
                            pass
        res = []
        for k, filelist in elf_an_dic.items():
            if len(filelist):
                descs = elf_desc.get(k)
                res.append({
                    'title': descs[0],
                    'stat': descs[1],
                    'desc': descs[2],
                    'file': " ".join(filelist),
                })
        return res

    except:
        pinfo("[ERROR] Performing Binary Analysis")
Exemple #3
0
 def dex_to_smali(self):
     pinfo("DEX -> SMALI")
     output = os.path.join(self.extract_path, 'smali_source')
     for dex in self.dex_path:
         args = [
             ToolSettings.JAVA_PATH, '-jar', ToolSettings.TOOL_BAKSAMLI,
             dex, '-o', output
         ]
         exec_command_silence(args)
Exemple #4
0
 def jar_to_java(self):
     pinfo("JAR -> JAVA")
     jar_path = [dex.replace('dex', 'jar') for dex in self.dex_path]
     output = os.path.join(self.extract_path, 'java_source')
     for jar in jar_path:
         args = [
             ToolSettings.JAVA_PATH, '-jar', ToolSettings.TOOL_JDCORE, jar,
             output
         ]
         exec_command_silence(args)
Exemple #5
0
 def dex_to_jar(self):
     pinfo("DEX -> JAR")
     # files = os.walk(self.extract_path).next()[2]
     self.dex_path = [
         os.path.join(self.extract_path, f) for f in self.files
         if '.' in f and f.split('.')[-1] == 'dex'
     ]
     for dex in self.dex_path:
         args = [
             ToolSettings.TOOL_DEX2JAR, dex, '-o',
             dex.replace('dex', 'jar')
         ]
         exec_command_silence(args)
def find_redundancy_permissions(self):
    redundancy_permissions = []
    pinfo("Now finding the redundancy permissions...")
    try:
        apk, d, dx = AnalyzeAPK(self.APP_PATH, decompiler="dad")
        used_permissions = show_Permissions(dx)
        for perm in self.PERMISSIONS:
            if perm not in used_permissions.keys():
                redundancy_permissions.append(perm)
    except Exception as e:
        einfo("Find redundancy permissions occured error: " + str(e))
    finally:
        return redundancy_permissions
def res_analysis(app_dir, typ):
    """Perform the elf analysis."""
    try:
        print "[INFO] Static Android Resourse Analysis Started"
        elf_desc = {
            'html_infected':
            (u'Found html files infected by malware.', u'high',
             u'The built environment was probably infected by malware, The html file '
             u'used in this APK is infected.'),
        }
        html_an_dic = {}
        for k in elf_desc.keys():
            html_an_dic[k] = []
        resraw = os.path.join(app_dir, "res", "raw")
        assets = os.path.join(app_dir, "assets")
        for resdir in (resraw, assets):
            if os.path.exists(resdir) and os.path.isdir(resdir):
                for pdir, dirl, filel in os.walk(resdir):
                    for filename in filel:
                        if filename.endswith(".htm") or filename.endswith(
                                ".html"):
                            try:
                                filepath = os.path.join(pdir, filename)
                                buf = ""
                                with io.open(filepath, mode='rb') as filp:
                                    buf = filp.read()
                                if "svchost.exe" in buf:
                                    html_an_dic['html_infected'].append(
                                        filepath.replace(app_dir, ""))
                            except Exception as e:
                                pass
        res = []
        for k, filelist in html_an_dic.items():
            if len(filelist):
                descs = elf_desc.get(k)
                res.append({
                    'title': descs[0],
                    'stat': descs[1],
                    'desc': descs[2],
                    'file': " ".join(filelist),
                })
        return res

    except:
        pinfo("[ERROR] Performing Resourse Analysis")
Exemple #8
0
    def is_protected(self):
        # 获得加固状态
        app = open(self.apk_path, 'rb')
        data = app.read()
        app.close()

        protected = False
        enterprise = 'None'

        for key, value in AndroidFeature.protect_dic.items():
            if key in data:
                protected = True
                enterprise = value
                break

        if protected:
            pinfo('%s被%s加固了' % (self.base_context[2], enterprise))
        else:
            pinfo('%s没有被加固!' % self.base_context[2])
        context = {'protected': protected, 'enterprise': enterprise}
        self.static_context.update(context)
Exemple #9
0
    def calc_score(self):
        score_weight = {
            'Bug': 0.8,
            'Threat': 0.3,
            'Sensitive': 0.2,
        }
        score = 100.0
        check_result = self.aobj.checkresult_set.all()
        for result in check_result:
            if result.number == 0:
                continue
            else:
                vunl_db = result.vulnerability
                weight = vunl_db.knowledge.rank
                v_type = getattr(vunl_db, 'v_type')

                # 如果是敏感信息,则按个数计算分数
                if v_type == 'Sensitive':
                    weight = weight * result.number
                    if weight >= 100:
                        weight = 100
                # 若判断条件为‘存在则安全’,则表示其为加分项目
                # 此时判断检测结果表中该项对应的漏洞数目是否为0
                # 若为0,则表示通过检查,应该加分。否则减分
                if vunl_db.judge_reverse and result.number == 0:
                    score += weight * score_weight.get(v_type)
                elif result.number != 0:
                    pinfo('subtract %s cause %s' % (weight, str(vunl_db.name)))
                    score -= weight * score_weight.get(v_type)
        # 控制分数在10-90的区间内
        if score < 10:
            score = 10
        elif score > 90:
            score = 90
        if self.aobj is not None:
            self.aobj.Score = score
            self.aobj.save()
        return score
Exemple #10
0
    def get_hardcoded_cert_keystore(self):
        pinfo('开始获取硬编码Certificates/Keystores')
        certz = []
        key_store = []
        try:
            for file_name in self.files:
                ext = file_name.split('.')[-1]
                if re.search("cer|pem|cert|crt|pub|key|pfx|p12", ext):
                    pinfo('获取到硬编码证书文件')
                    certz.append(file_name)
                if re.search("jks|bks", ext):
                    pinfo('获取到硬编码keystore文件')
                    key_store.append(file_name)
        except:
            einfo("获取硬编码Certificates/Keystores错误")

        result = {'certz': certz, 'key_store': key_store}
        return result
Exemple #11
0
    def get_info_from_xml(self):
        context = {}
        if self.AAPT_XML:
            pinfo("应用XML数据获取成功!")
        a_xml = self.AAPT_XML['manifest']
        version_code = None
        version_name = None
        package_name = None
        min_sdk = None
        target_sdk = None
        mainact = None
        permissions = []
        activities = []
        receivers = []
        providers = []
        services = []

        exp_activities = []
        exp_receivers = []
        exp_services = []
        exp_providers = []

        version_code_regx = '\)(?P<version>0x\w+)'
        version_name_regx = '\(Raw: "(?P<vname>.+)"\)'
        package_name_regx = '\(Raw: "(?P<package>.+)"\)'
        min_sdk_regx = '\)(?P<min_sdk>0x\w+)'
        target_sdk_regx = '\)(?P<target_sdk>0x\w+)'
        permission_regx = '\(Raw: "(?P<permission>.+)"\)'
        component_regx = '\(Raw: "(?P<comp>.+)"\)'

        for node in a_xml:
            if 'android:versionCode' in node['line'] and not version_code:
                version_re = re.compile(version_code_regx)
                version_code = version_re.findall(node['line'])
                if len(version_code) > 0:
                    version_code = version_code[0]
                    print "Found version code : %s" % version_code
                else:
                    version_code = 'unknown'
                    # a_xml.remove(node)

            if 'android:versionName' in node['line'] and not version_name:
                # (Raw: "5.5.365")
                version_name_re = re.compile(version_name_regx)
                version_name = version_name_re.findall(node['line'])
                if len(version_name) > 0:
                    version_name = version_name[0]
                    print "Found version name : %s" % version_name
                else:
                    version_name = 'unknown'
                    # a_xml.remove(node)

            if 'package="' in node['line'] and not package_name:
                # package="com.SvADK8.s6lFYYB" (Raw: "com.SvADK8.s6lFYYB")
                package_name_re = re.compile(package_name_regx)
                package_name = package_name_re.findall(node['line'])
                if len(package_name) > 0:
                    package_name = package_name[0]
                    print "Found package name : %s" % package_name
                else:
                    package_name = 'unknown'
                    # a_xml.remove(node)

            if 'uses-sdk' in node['line']:
                for node_attr in node['attr']:
                    if 'android:minSdkVersion' in node_attr[
                            'line'] and not min_sdk:
                        # android:minSdkVersion(0x0101020c)=(type 0x10)0x8
                        min_sdk_re = re.compile(min_sdk_regx)
                        min_sdk = min_sdk_re.findall(node_attr['line'])
                        if len(min_sdk) > 0:
                            min_sdk = min_sdk[0]
                            print "Found min_sdk version : %s" % min_sdk
                        else:
                            min_sdk = 'unknown'
                            # node['attr'].remove(node_attr)

                    if 'android:targetSdkVersion' in node_attr[
                            'line'] and not target_sdk:
                        # android:targetSdkVersion(0x01010270)=(type 0x10)0x13
                        target_sdk_re = re.compile(target_sdk_regx)
                        target_sdk = target_sdk_re.findall(node_attr['line'])
                        if len(target_sdk) > 0:
                            target_sdk = target_sdk[0]
                            print "Found target_sdk version : %s" % target_sdk
                        else:
                            target_sdk = 'unknown'
                            # node['attr'].remove(node_attr)

            if 'uses-permission' in node['line']:
                for node_attr in node['attr']:
                    permission_re = re.compile(permission_regx)
                    t_perm = permission_re.findall(node_attr['line'])
                    if len(t_perm) > 0:
                        print "Found permission : %s" % t_perm[0]
                        permissions = permissions.__add__(t_perm)

            if 'application' in node['line']:
                component_re = re.compile(component_regx)
                for app_node in node['attr']:
                    if app_node['feature'].lower() == 'activity':
                        exported = True
                        is_intent = False
                        for app_node_node in app_node['attr']:
                            if 'android:name' in app_node_node['line']:
                                activity = component_re.findall(
                                    app_node_node['line'])
                                if len(activity) > 0:
                                    # print "Found activity : %s" % activity[0]
                                    activities = activities.__add__(activity)

                            if 'android:exported' in app_node_node[
                                    'line'] and '0xffffffff' in app_node_node[
                                        'line'].lower():
                                exported = False

                            if 'intent-filter' in app_node_node[
                                    'line'] and exported:
                                is_intent = True

                                for compo_attr in app_node_node['attr']:
                                    if 'action' in compo_attr['line']:
                                        # exclude main activity
                                        for action in compo_attr['attr']:
                                            if 'android.intent.action.MAIN' in action[
                                                    'line']:
                                                exported = False
                                                mainact = activity[0]

                            if exported and is_intent:
                                exp_activities.append(activity[0])
                                # print "<--!-->Found exported activity : %s" %
                                # activity[0]

                    if app_node['feature'].lower() == 'receiver':
                        exported = True
                        is_intent = False
                        for app_node_node in app_node['attr']:
                            if 'android:name' in app_node_node['line']:
                                receiver = component_re.findall(
                                    app_node_node['line'])
                                if len(receiver) > 0:
                                    print "Found receiver : %s" % receiver[0]
                                    receivers.__add__(receiver)

                            if 'android:exported' in app_node_node[
                                    'line'] and '0xffffffff' in app_node_node[
                                        'line'].lower():
                                exported = False

                            if 'intent-filter' in app_node_node['line']:
                                is_intent = True

                            if exported and is_intent:
                                exp_receivers.append(receiver[0])
                                # print "<--!-->Found exported receiver : %s" %
                                # receiver[0]

                    if app_node['feature'].lower() == 'service':
                        exported = True
                        is_intent = False
                        for app_node_node in app_node['attr']:
                            if 'android:name' in app_node_node['line']:
                                service = component_re.findall(
                                    app_node_node['line'])
                                if len(service) > 0:
                                    # print "Found service : %s" % service[0]
                                    services.__add__(service)

                            if 'android:exported' in app_node_node[
                                    'line'] and '0xffffffff' in app_node_node[
                                        'line'].lower():
                                exported = False

                            if 'intent-filter' in app_node_node['line']:
                                is_intent = True

                            if exported and is_intent:
                                exp_services.append(service[0])
                                # print "<--!-->Found exported service : %s" %
                                # service[0]

                    if app_node['feature'].lower() == 'provider':
                        exported = True
                        is_intent = False
                        for app_node_node in app_node['attr']:
                            if 'android:name' in app_node_node['line']:
                                provider = component_re.findall(
                                    app_node_node['line'])
                                if len(provider) > 0:
                                    # print "Found provider : %s" % provider[0]
                                    providers.__add__(provider)

                            if 'android:exported' in app_node_node[
                                    'line'] and '0xffffffff' in app_node_node[
                                        'line'].lower():
                                exported = False

                            if 'intent-filter' in app_node_node['line']:
                                is_intent = True

                            if exported and is_intent:
                                exp_providers.append(provider[0])
                                # print "<--!-->Found exported provider : %s" %
                                # provider[0]

        if not mainact:
            mainact = activities[0]

        context.update({
            'Permissions': permissions,
            'Package_Name': package_name,
            'Version_Code': version_code,
            'Version': version_name,
            'Min_SDK': min_sdk,
            'Target_SDK': target_sdk,
            'Main_Activity': mainact,
            'Activitys': activities,
            'Services': services,
            'Receivers': receivers,
            'Providers': providers,
            'Act_count': len(activities),
            'Ser_count': len(services),
            'Rec_count': len(receivers),
            'Pro_count': len(providers),
        })

        return context
Exemple #12
0
    def analysis_code(self):
        column = []
        code_vul_db = []
        for vul_item in code_vul_db:
            column.append(vul_item.flag)

        context = {key: [] for key in column}

        urllist = []
        emaillist = []

        JS = os.path.join(self.extract_path, 'java_source')

        url_reg = re.compile(
            ur'((?:https?://|s?ftps?://|file://|javascript:|data:|www\d{0,3}[.])[\w().=/;,#:@?&~*+!$%\'{}-]+)',
            re.UNICODE)
        email_reg = re.compile("[\w.-]+@[\w-]+\.[\w.]+")

        pinfo("Code Analysis Started on - " + JS)
        for dirName, subDir, files in os.walk(JS):
            for jfile in files:
                jfile_path = os.path.join(JS, dirName, jfile)
                if "+" in jfile:
                    p2 = os.path.join(JS, dirName, jfile.replace("+", "x"))
                    shutil.move(jfile_path, p2)
                    jfile_path = p2
                repath = jfile_path.replace(JS, '')

                # 排除分析默认框架的源码 及 第三方SDK源码
                if not self.init_blacklist(repath):
                    with io.open(jfile_path,
                                 mode='r',
                                 encoding="utf8",
                                 errors="ignore") as f:
                        dat = f.read()
                        f.close()

                    for vul in code_vul_db:
                        result = False
                        features = getattr(vul, 'check_feature')
                        for feature in features:
                            is_found = True
                            if isinstance(feature, list):
                                # pinfo('Now checking %s' % feature)
                                for i in feature:
                                    try:
                                        t_reg = re.compile(i)
                                        if not t_reg.findall(dat):
                                            is_found = False
                                    except Exception as e:
                                        einfo('Code analysis error! ' + str(e))
                            else:
                                try:
                                    t_reg = re.compile(feature)
                                    if not t_reg.findall(dat):
                                        is_found = False
                                except Exception as e:
                                    einfo('Code analysis error! ' + str(e))
                            result = result or is_found

                        if result:
                            t_column = getattr(vul, 'flag')
                            context[t_column].append(jfile_path.replace(
                                JS, ''))

                    # URLs My Custom regex
                    for url in re.findall(url_reg, dat.lower()):
                        urllist.append(url)
                    # Email Etraction Regex
                    for email in email_reg.findall(dat.lower()):
                        emaillist.append(email)

        context['URLs'] = list(set(urllist))
        context['Emails'] = []

        for email in list(set(emaillist)):
            if not email.startswith('//'):
                context['Emails'].append(email)

        print "[INFO] Finished Code Analysis, Email and URL Extraction"
        return context
def read_manifest(self, manifest):
    # 要求安装Androguard的androaxml.py
    pinfo('Now Getting AndroidManifest.xml from Androguard module')
    ap = apk.AXMLPrinter(read(manifest))
    buff = ap.get_buff()
    return buff