Android漏洞检测——模糊测试

前言

Android在目前的市场上占有率很高,用户数量庞大,而在该平台下的应用程序开发成本低,开发难度低,发布容易,缺少监管和审查,导致大量低质量App流入市场,这些App由于开发者缺乏安全编程技能或缺乏测试和审查,可能存在着一些严重的漏洞,对用户的隐私以及财产安全造成巨大风险。因此,移动应用尤其是Android平台下的应用的开发应该对此引起高度重视。

Android常见漏洞
  • 越权绕过:没有对调用activity的组件进行权限验证,就会造成验证的安全问题

  • 钓鱼欺诈:启动一个activity时,加入标志位FLAG_ACTIVITY_NEW_TASK,能够使被启动的activity立马呈现给用户,可用于钓鱼欺诈

  • 拒绝服务:本地组件启动时没有对Intent.getXXXExtra()获取或处理的数据进行异常捕获,从而导致攻击者可通过向受害者应用发送空数据、异常或者畸形数据来使该应用crash的目的

  • 权限提升:当一个具有高权限的service是被导出的时,如果没对调用这个Service进行权限限制和调用者的身份验证时,那么恶意的app将具有调用高权限的service的能力来执行高权限行为等

  • 权限泄露:主要存在于某些具有高权限操作的组件被导出,而系统没有进行严格的身份验证和权限控制而导致的其他应用可以利用该组件而产生越权操作的行为。

Android常见漏洞检测方法
  • 静态分析
    利用apktool、dex2jar、jd-gui、smali2dex等静态分析工具对应用进行反编译,并对反编译后的java文件、xml文件等文件静态扫描分析,通过关键词搜索等静态方式将具有安全隐患的代码进行摘录并存入到检测平台后台,为后续的安全检测报告提供数据依据。

  • 动态分析
    对应用软件安装、运行过程的行为监测和分析。检测的方式包括沙箱模型和虚拟机方式。虚拟机方式通过建立与Android手机终端软件运行环境几乎一样的虚拟执行环境,手机应用软件在其中独立运行,从外界观察应用程序的执行过程和动态,进而记录应用程序可能表现出来的恶意行为。

  • 人工分析
    专业安全人员对待检测应用,对其进行安装、运行和试用,通过在试用过程中,逐步掌握应用的特点,并通过专业经验,来圈定检测重点。人工专业检测在涵盖基础检测和深度检测的全部检测项的同时,兼顾侧重点检测,给予应用更全面、更专业、更贴合应用的量身打造的检测服务。

模糊测试
  • 简介
    模糊测试(Fuzzing),是一种通过向目标系统提供非预期的输入并监视异常结果来发现软件漏洞的方法。我个人理解,这是一种随机或伴随机的测试方法,与Monkey等随机测试工具有异曲同工之妙,只是其关注点不同。

  • 模糊测试的执行过程:
    1.测试工具通过随机或是半随机的方式生成大量数据;
    2.测试工具将生成的数据发送给被测试的系统(输入);
    3.测试工具检测被测系统的状态(如是否能够响应,响应是否正确等);
    4.根据被测系统的状态判断是否存在潜在的安全漏洞

模糊测试工具IntentFuzzer

本文将介绍一种模糊测试工具,IntentFuzzer。

主界面
应用列表
测试组件列表
  • 简介
    这个工具是针对Intent的Fuzzer。它通常可以发现能够导致系统崩溃的bug,部分安全漏洞,以及设备、应用程序或者是定制平台的运行中的问题。该工具能够针对一个简单组件或者是所有安装组件进行fuzz测试。它也适用于BroadcastReceiver,但针对Service只有较少的覆盖,Service通常更加广泛地应用Binder接口而不是针对IPC的Intent。原版的工具只能针对一个Activity进行fuzz测试,一次不能针对所有的Activity进行测试。另外,也能应用这个接口来启动Instrumentation,虽然列出了ContentProvider,但是它们不是一个基于Intent的IPC机制,因此并不能应用该工具进行fuzz测试。MindMac在此基础上进行了一些修改,使其能够针对一个应用的一个简单组件或者是所有组件进行fuzz测试,同时具有区分系统应用和非系统应用的能力。MindMac修改后的版本仅针对Activity、BroadcastReceiver、Service。

  • 原理
    列举出系统上所有公开的、能够从应用获取到的Activity、BroadcastReceiver、Service、Instrumentation、ContentProvider。工具将通过Intent尝试启动所有可以获取到的组件,从而触发某些难以发掘的漏洞。触发一般有两类漏洞,一类是拒绝服务,一类的权限提升。拒绝服务危害性比较低,更多的只是影响应用服务质量;而权限提升将使得没有该权限的应用可以通过Intent触发拥有该权限的应用,从而帮助其完成越权行为。如果该工具能够轻易从外部启动特定应用的内部组件,尤其是有较高权限的组件时,很可能在此处发现漏洞。

  • 功能
    对某个组件或某个应用的某类组件发起Fuzz,分为Null Fuzz和Serialize
    Fuzz,即在Intent中不携带参数和携带序列化对象参数,然后尝试使用该Intent启动Activity、BroadcastReceiver、Service。

  • 代码
    获取所有应用及其组件

    public static List<AppInfo> getPackageInfo(Context context, int type){
        List<AppInfo> pkgInfoList = new ArrayList<AppInfo>();
        List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(
//              PackageManager.GET_DISABLED_COMPONENTS |
                        PackageManager.GET_ACTIVITIES
                | PackageManager.GET_RECEIVERS
                | PackageManager.GET_INSTRUMENTATION
                | PackageManager.GET_SERVICES); 
        
        for(int i=0;i<packages.size();i++) {   
            PackageInfo packageInfo = packages.get(i);
            if (type == SYSTEM_APPS) {
                if((packageInfo.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 1) {
                    pkgInfoList.add(fillAppInfo(packageInfo, context));   
                }
            }else if(type == NONSYSTEM_APPS){
                if((packageInfo.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
                    pkgInfoList.add(fillAppInfo(packageInfo, context));   
                }
            }else {
                pkgInfoList.add(fillAppInfo(packageInfo, context)); 
            }
        }

构建Intent

    private void initView(){
        typeSpinner = (Spinner) findViewById(R.id.type_select);
        cmpListView = (ListView) findViewById(R.id.cmp_listview);
        fuzzAllNullBtn = (Button) findViewById(R.id.fuzz_all_null);
        fuzzAllSeBtn = (Button) findViewById(R.id.fuzz_all_se);
        cmpListView.setOnItemClickListener(new OnItemClickListener(){

                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    ComponentName toSend = null;
                    Intent intent = new Intent();
                    String className =  cmpAdapter.getItem(position).toString();
                    for (ComponentName cmpName : components) {
                        if (cmpName.getClassName().equals(className)) {
                            toSend = cmpName;
                            break;
                        }
                    }
                    intent.setComponent(toSend);
                    if (sendIntentByType(intent, currentType)) {
                        Toast.makeText(FuzzerActivity.this, "Sent Null " + intent, Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(FuzzerActivity.this, "Send " + intent + " Failed!", Toast.LENGTH_LONG).show();
                    }
                }
            
           });
        cmpListView.setOnItemLongClickListener(new OnItemLongClickListener(){

            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                // TODO Auto-generated method stub
                ComponentName toSend = null;
                Intent intent = new Intent();
                String className =  cmpAdapter.getItem(position).toString();
                for (ComponentName cmpName : components) {
                    if (cmpName.getClassName().equals(className)) {
                        toSend = cmpName;
                        break;
                    }
                }
                intent.setComponent(toSend);
                intent.putExtra("test", new SerializableTest());
                if (sendIntentByType(intent, currentType)) {
                    Toast.makeText(FuzzerActivity.this, "Sent Serializeable " + intent, Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(FuzzerActivity.this, "Send " + intent + " Failed!", Toast.LENGTH_LONG).show();
                }
                return true;
            }
        
       });
        fuzzAllNullBtn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                for(ComponentName cmpName : components){
                    Intent intent = new Intent();
                    intent.setComponent(cmpName);
                    if (sendIntentByType(intent, currentType)) {
                        Toast.makeText(FuzzerActivity.this, "Sent Null " + intent, Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(FuzzerActivity.this, R.string.send_faild, Toast.LENGTH_LONG).show();
                    }
                }
            }
            
        });
        fuzzAllSeBtn.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                for(ComponentName cmpName : components){
                    Intent intent = new Intent();
                    intent.setComponent(cmpName);
                    intent.putExtra("test", new SerializableTest());
                    if (sendIntentByType(intent, currentType)) {
                        Toast.makeText(FuzzerActivity.this, "Sent Serializeable " + intent, Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(FuzzerActivity.this, R.string.send_faild, Toast.LENGTH_LONG).show();
                    }
                }
            }
            
        });
    }

发送请求

    private boolean sendIntentByType(Intent intent, String type) {
        try {
                switch (ipcNamesToTypes.get(type)) {
                case Utils.ACTIVITIES:
                    startActivity(intent);
                    return true;
                case Utils.RECEIVERS:
                    sendBroadcast(intent);
                    return true;
                case Utils.SERVICES:
                    startService(intent); 
                    return true;
                default:
                    return true;
                }
        } catch (Exception e) {
            //e.printStackTrace();
            return false;
        }
        
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容

  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,419评论 0 17
  • 2017年5月17日 Kylin_Wu 标注(★☆)为考纲明确给出考点(必考) 常见手机系统(★☆) And...
    Azur_wxj阅读 1,813评论 0 10
  • Day1: 在代码中通过R.string.hello_world可以获得该字符串的引用; 在XML中通过@stri...
    冰凝雪国阅读 1,403评论 0 5
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,133评论 25 707
  • 旅行人家有些人是为了烦恼而选择旅行,有些人为了憧憬而旅行,我的则是为了我的梦想,一个游遍中国大好河山的梦想,和别人...
    Suily07阅读 264评论 0 1