首页> 中国专利> 一种安卓应用动态Receiver组件本地拒绝服务漏洞检测方法

一种安卓应用动态Receiver组件本地拒绝服务漏洞检测方法

摘要

本发明公开了一种安卓应用动态Receiver组件本地拒绝服务漏洞检测方法,包括以下步骤:通过静态分析获得应用中动态Receiver组件的信息;根据所述动态Receiver组件信息构造注册函数并将构造的注册函数和注册函数的调用插入到注册组件中;构造数据启动该注册组件完成对动态Receiver组件注册并进行测试;分析所述动态Receiver组件运行日志来判断是否存在本地拒绝服务漏洞。本发明克服了现有检测方法只能对安卓配置文件中的暴露组件进行检测的问题,能针对动态Receiver组件进行本地拒绝服务漏洞的检测。

著录项

  • 公开/公告号CN108491327A

    专利类型发明专利

  • 公开/公告日2018-09-04

    原文格式PDF

  • 申请/专利权人 中南大学;

    申请/专利号CN201810251831.4

  • 发明设计人 王伟平;吴洪磊;宋虹;王建新;

    申请日2018-03-26

  • 分类号G06F11/36(20060101);

  • 代理机构43114 长沙市融智专利事务所;

  • 代理人杨萍

  • 地址 410083 湖南省长沙市岳麓区麓山南路932号

  • 入库时间 2023-06-19 06:24:22

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2020-08-25

    授权

    授权

  • 2018-09-28

    实质审查的生效 IPC(主分类):G06F11/36 申请日:20180326

    实质审查的生效

  • 2018-09-04

    公开

    公开

说明书

技术领域

本发明涉及移动应用程序漏洞检测领域,具体而言,一种安卓应用动态Receiver组件本 地拒绝服务漏洞检测方法。

背景技术

安卓应用组件的本地拒绝服务漏洞是指安卓应用中的暴露组件在实现中没有对外来数据 进行很好的过滤,导致当特定的外来数据传递给该暴露组件时,会导致组件运行出现异常, 从而造成应用崩溃或者系统重启。本地拒绝服务漏洞的存在可能被恶意应用利用来攻击安装 含有漏洞应用的系统。

现有本地拒绝服务漏洞检测方法在应用程序启动后,直接通过构造测试数据发送给暴露 组件进行测试,这要求待测的暴露组件在应用程序启动后就能正常接收数据,在安卓配置文 件Manifest中声明的暴露组件在应用程序启动时完成注册,可以满足上述测试要求。

与安卓配置文件中声明的暴露组件不同,安卓应用中的动态Receiver组件(通过动态方 式注册的BroadcastReceiver组件)全都属于暴露组件,在应用运行过程中通过registerReceiver 注册函数注册。当该注册函数还没被执行时,即便应用程序已经启动,该组件也无法正常接 收外来组件数据,因此现有的检测方法无法直接针对这种组件进行检测。

因此,有必要针对现有技术的不足,提供一种安卓应用中动态Receiver组件的本地拒绝 服务漏洞检测方法。

发明内容

本发明所解决的技术问题是,针对现有技术的不足,提供一种安卓应用动态Receiver组 件本地拒绝服务漏洞检测方法,克服了现有检测方法只能对安卓配置文件中声明的暴露组件 进行检测的问题。

本发明的技术方案如下:

一种安卓应用动态Receiver组件本地拒绝服务漏洞检测方法,包括以下步骤:

步骤1、分析安卓应用中动态Receiver组件信息;

a)输入一个待检测的安卓应用,获得该应用中动态Receiver组件的名称以及该组件的 intent-filter【意图过滤器,用来指明启动该组件需要的条件,包含操作动作、动作分类和动作 涉及数据(URI形式)】信息;

b)获得该动态Receiver组件的intentextra项数据格式信息,如果intentextra项数据格式 为空,表示该动态Receiver组件没有从外部获取数据的通路,则直接判定该动态Receiver组 件不含本地拒绝服务漏洞,退出检测;

c)分析该动态Receiver组件的smali代码,获得调用registerReceiver方法完成该动态 Receiver组件注册的组件,即注册组件的信息,包括注册组件的名称、类型以及是否暴露;

步骤2、构造该动态Receiver组件的注册函数,并插入到注册组件中,完成应用重打包 并安装;

根据步骤1中得到的动态Receiver组件的名称以及intent-filter信息构造注册函数,具体 为:在构造注册函数的定义时分别创建Receiver以及IntentFilter对象,设置IntentFilter对象 的action、category和data属性,并将这两个对象作为参数传递给registerReceiver方法进行调 用;将构造的注册函数和注册函数的调用插入到注册组件的生命周期方法中,使得该注册组 件一启动就能直接触发registerReceiver方法,自动注册该动态Receiver组件(注:未修改前 的注册组件启动后,可能需要满足一定的程序逻辑条件,才能触发registerReceiver方法,完 成该动态Receiver组件的注册);对修改后的应用进行重打包和签名,安装至安卓设备上;

步骤3、构造启动数据和测试数据;

根据步骤1c)中获得的注册组件的信息,构造用于启动该注册组件的数据;

根据步骤1a)和1b)中获得的intent-filter信息和intent extra项数据格式信息,构造针 对该动态Receiver组件的测试数据;

步骤4、启动注册组件,并发送测试数据进行检测;

先向待检测的安卓应用发送启动注册组件的数据来启动注册组件,注册组件启动后自动 执行注册函数来注册动态Receiver组件;再发送测试数据来测试动态Receiver组件,检测其 是否存在本地拒绝服务漏洞。

进一步地,在步骤1a)的执行过程中,通过静态分析的方法得到待检测的安卓应用的过 程间控制流图,对过程间控制流图进行遍历,当判断过程间控制流图中使用了registerReceiver 方法(registerReceiver方法用于在代码中注册动态Receiver组件,注册组件中包含了 registerReceiver方法)就表明该安卓应用中注册了动态Receiver组件,接着分析该方法的参 数得到动态Receiver组件的名称以及intent-filter信息。

进一步地,在步骤1b)的执行过程中,借助于动态Receiver组件内的接收外部数据的方 法名称来判定接收数据类型和名称;对动态Receiver组件代码进行数据流分析,将获取intent 对象的方法(中文论文中将intent称为意图,是组件间通信机制的消息传递通道。这里获取 intent对象的方法是指动态Receiver组件被启动后执行的onReceive(Context,Intent)生命周期 方法,该方法的第二个参数是接收的intent对象)作为数据流跟踪的源点(source),将系统 定义的所有获取intent extra项数据(中文含义是附加数据,即组件通信传输的数据)的方法 作为数据流跟踪的宿点(sink);经过数据流分析,当存在源点到宿点的数据流时,那么该数 据流检出的宿点表示的是该动态Receiver组件中获取intent extra项的方法,通过方法名称推 断出intent extra项数据格式信息,即数据类型和数据名称。

进一步地,在步骤1c)的执行过程中,反编译待检测的安卓应用,得到动态Receiver组 件的smali代码,从中提取动态Receiver组件的构造函数参数,通过分析构造函数参数来获 得注册组件的信息;

根据构造函数参数形式的不同,注册组件的选取也不一样,三种情况如下所示:

c1)构造函数不带参数时,说明无法直接获取该动态Receiver组件对应的注册组件名称, 因此将注册组件名称设置为空,组件类型设置为Activity,组件的exported属性设置为true; 【activity是Android组件中最基本也是最为常见用的四大组件之一。Android四大组件有 Activity,Service(服务),Content Provider(内容提供),BroadcastReceiver(广播接收器); Activity提供一个屏幕,用户可与其提供的屏幕进行交互。Activity组件的exported属性(暴 露属性)用来标示当前Activity是否可以被另一个应用的组件启动,其值为true表示允许被 启动,其值为false表示不允许被启动,这个Activity只会被当前应用或者拥有同样user ID的 应用的组件调用。】

c2)当构造函数参数为为字符串,且该字符串出现在Manifest文件的组件定义中时,该 参数即为对应的注册组件名称,查找Manifest文件中该组件的定义,记录注册组件类型和是 否暴露标记;

c3)当构造函数参数未出现在Manifest文件的组件定义中时,表明该参数对应的不是组 件名称,而是一个普通类名,在应用中是通过调用该类来完成该动态Receiver组件注册的, 在本发明中不对这种情况进行处理,则直接退出检测。

进一步地,在步骤2的执行过程中,首先针对注册组件不存在和注册组件为非暴露的情 况进行预处理,从而使得动态Receiver组件具备一个声明的暴露注册组件;方法为:依据步 骤1c)中获取的注册组件的名称,如果名称为空,则自定义一个名称,并在Manifest文件中添 加该注册组件的定义;如果名称非空,表示注册组件在待检测安卓应用中已经存在;若注册 组件为非暴露,则在Manifest文件中将该注册组件的exported属性设置为true,即设置为暴 露组件。

进一步地,在步骤2的执行过程中,根据动态Receiver组件的名称和intent-filter信息构 造smali形式的注册函数,并将构造的注册函数和注册函数的调用插入到注册组件代码中。

以下对上述部分步骤进行具体说明:

(1)构造该动态Receiver组件的注册函数;

在应用中注册动态Receiver使用的方法是registerReceiver(Receiver,IntentFilter),该方法 接收两个参数。因此在构造注册函数的定义时需要分别创建Receiver以及IntentFilter对象, 设置IntentFilter对象的action、category和data属性,并将这两个对象作为参数传递给 registerReceiver方法进行调用。本发明在构造注册函数时使用的是smali代码,smali为安卓 系统中Java虚拟机(Dalvik)所使用的一种.dex格式文件的汇编器,它支持.dex格式所有功能(注 解,调试信息,代码行信息等)。需要说明的是,构造注册函数的代码并不限于smali,还可 以表现为其他中间代码。

在smali中创建Receiver对象和IntentFilter对象的方式如表1所示,可以看出创建两种 对象的代码前缀语法都相同,因此这里以Receiver对象创建过程为例进行说明。第一行表示 新建一个receiverName(代指动态Receiver组件名称,在步骤1a中获得)对象(在smali 中用L表示对象),并将该对象存放在寄存器v0中;第二行表示调用该receiverName对 象的构造函数;第三行表示将第一行中创建的receiverName对象赋值给局部变量testReceiver。这三行代码的等价Java代码是BroadcastReceivertestReceiver=newreceiverName(),即创建一个Receiver对象。

表1smali中实例化对象的方式

IntentFilter对象是组件的过滤器,用以指明该组件的能够接收的Intent消息,该对象具有 action、category和data属性,因此创建IntentFilter对象后还需要设置这三种属性,设置三种 属性的smali代码如表2所示,可以看出设置三种属性的代码前缀语法都相同,因此这里以 设置action属性为例进行说明。第一行将字符串常量值android.intent.action.VIEW 存储在寄存器v2中,第二行调用IntentFilter对象的addAction方法,v1指的是该方法的调 用者IntentFilter对象,v2指的是方法的参数(即上面定义的字符串常量),void表示方法的 返回值是空。这两行代码的等价Java代码是intentFilter.addAction("android.intent.action.VIEW"),即设置 intentFilter对象的action属性。

表2设置intent-filter属性的方式

Receiver对象和IntentFilter对象创建完成后,将这两个对象作为参数传递给registerReceiver方法调用以完成动态Receiver组件的注册。表3中Smali代码表示的 是调用regiterComponentName(代指注册组件)类中的registerReceiver方法,p0指 的是方法调用者regiterComponentName类,v0指的是方法的第一个参数Receiver对 象,v1指定的方法的第二个参数IntentFilter对象。这行代码的等价Java代码是 registerReceiver(receiver,intentFilter),即调用registerReceiver函数 并传入receiver和intentFilter对象作为参数。

表3调用registerReceiver方法

(2)将注册函数插入注册组件

(1)中构造了动态receiver组件的注册函数定义,然后将该函数作为成员方法插入到注 册组件中,为了调用该注册函数,要将该函数调用语句插入到注册组件的生命周期方法中, 生命周期方法是组件启动后系统会自动调用的方法,不同类型的组件插入的生命周期方法不 同,表4给出了三种类型组件对应的不同生命周期方法。依据步骤1-c)获得的注册组件的类 型,可以找到其对应的生命周期方法,在该方法的顶端直接调用注册函数。

表4组件与生命周期方法

(3)构造数据

为了成功注册动态Receiver组件,需要构造数据启动注册组件来调用之前插入的注册函 数;动态Receiver组件注册成功后,可以接受外部数据,构造测试数据来检测其是否存在拒 绝服务漏洞。

构造数据使用的是adb命令(安卓调试桥),这是一个通用命令行工具,其允许与模拟器 实例或连接的安卓设备进行通信。使用adb可以对安卓设备上的应用执行一些操作,如启动activity、强行停止进程、广播intent及传递extra数据。

3a)启动注册组件数据

按照步骤1c)中获取的注册组件信息来构造动注册组件的数据,数据由两部分组成,如表 5所示,命令部分指明了要启动的组件类型,intent部分显式指明了要启动的组件名称,其中 package指应用的包名,componentName指注册组件的名称。

表5注册组件的数据

3b)动态Receiver组件的测试数据

测试数据的命令是am broadcast-a action-c category-d uriextra。

由于动态Receiver组件只能通过隐式intent来启动,因此在命令中用-a、-c和-d分别指 明intent的action、category和data属性,属性值参考步骤1a)中获取的动态Receiver组件 intent-filter信息进行设置。extra表示的是intent中携带的额外数据,根据步骤1b)中获取的数 据类型来构造相应的数据值,常见数据类型的构造如表6所示,这里并没有构造长字符串、 临界数据等易于产生缓冲区溢出、边界溢出的测试数据,这是由于安卓应用的主要开发语言 是Java,而Java并不存在缓冲区溢出等漏洞。

表6extra项数据构造

(4)测试并分析日志

应用出现异常后,异常信息会被记录到日志中,而且Java代码中异常类拥有相似的名称, 形如java.lang.***Exception。因此开启安卓系统日志进程,记录待检测安卓应用的运行日志。 向待检测安卓应用发送步骤3中构造的数据,数据发送完毕后对日志文件进行分析,如果日 志中出现“Caused by:java.lang.***Exception”异常信息则表明该组件存在本地拒绝服务漏洞。

有益效果:

本发明利用过程间控制流图能够精确分析安卓应用中存在的动态Receiver组件。通过构 造动态Receiver组件的注册函数并插入到注册组件,并将构造的注册函数插入到注册组件中 从而使得注册组件一启动就能自动注册动态Receiver组件;测试过程中,通过命令启动注册 组件,该组件启动后会自动执行注册函数,此时动态Receiver组件被成功注册,接着发送命 令来测试动态Receiver组件,以检测其是否存在本地拒绝服务漏洞,并通过分析所述动态 Receiver组件运行日志来判断是否存在本地拒绝服务漏洞。本发明能保证动态Receiver注册 成功,解决了动态Receiver组件本地拒绝服务漏洞无法检测的问题。本发明方法克服了现有 检测方法只能对安卓配置文件中的暴露组件进行检测的问题,提供了一种针对动态Receiver 组件本地拒绝服务漏洞的检测方法。本发明适用于除了构造函数参数为非组件名称之外的动 态Receiver组件,适用的组件数约占安卓应用动态Receiver组件数的89%。

附图说明

图1为本发明流程图;

图2为本发明注册动态Receiver组件并检测其漏洞的思路;

图3为应用中注册动态Receiver组件的一种情况;

图4为应用中定义动态Receiver组件的一种情况。

具体实施方式

以下将结合附图和具体实施例对本发明做进一步说明:

实施例1:

步骤1:分析动态Receiver组件信息

a)获取动态Receiver组件名称及intent-filter对象

Ic3是针对复杂对象进行属性值分析的工具,本发明利用Ic3工具构造的应用过程间控制 流图,分析应用中通过registerReceiver方法注册的动态Receiver组件信息,包括组件名称、 intent-filter信息(由action、category和data组成)。

图3展示了代码中注册动态Receiver组件的例子。代码第19行注册了名称为TestReceiver 的动态Receiver组件,该组件的定义如图4。所述动态Receiver组件intent-filter的action属 性值是ACTION_VIEW;category属性值是CATEGORY_BROWSABLE;Data中Scheme属 性值是http。

b)分析动态Receiver组件可以接收的数据格式

Flowdroid是一个数据流分析工具,能够跟踪安卓应用中的敏感信息。本发明中改写了该 工具的source与sink API的定义,将获取intent对象的方法定义为source,系统定义的所有 获取intentextra项数据的方法定义为sink,具体定义如表7所示,通过数据流分析即可得到 应用中所有获取intent extra项数据的函数,根据函数名称和参数值即可得知extra项的数据类 型和数据名称。对于图4中定义的动态Receiver组件,extra项数据类型是String,数据名称 是name。

表7source与sink函数定义

c)获取注册组件信息

Apktool是apk反编译工具,能够反编译及回编译apk,安卓应用反编译后形成smali代 码。对动态Receiver组件的smali文件进行分析,提取构造函数参数,根据参数值来获取注 册组件名称。

如下展示的是动态Receiver组件构造函数的smali代码,第2行init构造函数的参数为空, 对于这种情况本实施例中将注册组件名称默认设置为空。

1#direct methods

2.method constructor<init>()V//无参构造函数

***

3.end method

步骤2:构造动态Receiver组件注册函数并插入到注册组件中

构造注册动态Receiver组件的注册函数(smali代码),并将该函数定义和函数的调用插 入到注册组件中。以下是详细步骤:

a)构造和修改注册组件

步骤1c)中分析出注册组件名称为空,于是本实施例中给注册组件赋予一个自定义名称ManualMainActivity,这个组件在待测应用中并不存在,因此需要重新创建该组件对应的smali 文件,并在Manifest文件中添加该注册组件的定义,添加的定义如下。

b)构造注册函数

根据步骤1中分析得到的动态Receiver组件信息,构造的注册函数如下,第5-7行创建 了动态Receiver对象,第10-12行创建了intent-filter对象。然后在15-16行给intent-filter对 象添加的action属性为android.intent.action.VIEW,在第18-19行添加的category 属性为android.intent.category.BROWSABLE,第22-23给添加的data属性为http。 在第26行调用registerReceiver函数传入了Receiver和intent-filter对象注册了该动态Receiver 组件。

c)插入注册函数

将b)中manualRegisterReceiver的注册函数作为成员方法插入到注册组件中,并在注册组 件的生命周期方法中调用该注册函数,这样注册组件启动后就能够调用该函数完成动态 Receiver组件的注册。调用注册函数的代码如下。

//在注册组件ManualMainActivity中调用注册函数manualRegisterReceiverinvoke-direct{p0},L{ManualMainActivity};>{manualRegisterReceive r}()V

d)应用签名

smali代码修改完成后,使用Apktool工具回编译生成新的应用,并利用jarsigner对应用 签名,并将签名后的应用安装至安卓设备。

步骤3:构造数据

使用adb工具分别构造注册组件以及动态Receiver组件的数据。

a)注册组件的启动数据

在步骤1c)中分析得到的注册组件名称是ManualMainActivity,对于该组件本实施例中构 造的启动数据如下所示,start命令表示要启动的目标组件类型是activity,-n选项指定了要启 动的目标组件的名称是ManualMainActivity。

am start–n package/.ManualMainActivity

b)动态Receiver组件的测试数据

对于动态Receiver组件本实施例中构造的测试数据如下所示,broadcasd指明要启动的组 件类型是BroadcastReceiver,-a、-c和-d选项分别表示设置Action、Category和Data属性, 属性值根据步骤1a)中分析得到的intent-filter对象来进行设置,分别为android.intent.action.VIEW、android.intent.category.BROWSER和http。命令的最后--esn name 表示extra项名称是name,字符串值是null。

am broadcast–a android.intent.action.VIEW–c android.intent.category.BROWSER–d http://www.baidu.com –esnname

步骤4:测试并分析日志

在安卓手机中打开USB调试模式,开启日志记录进程,记录待测应用的日志信息,测试 过程如图2所示,第一步,发送数据启动注册组件,注册组件启动后会自动执行注册函数, 此时动态Receiver组件被注册成功;第二步,发送测试数据启动动态Receiver组件,组件启 动后会接收数据并进行一些操作;第三步,数据发送完毕后导出并分析日志文件。

对于图4中名称为TestReceiver的动态Receiver组件,在代码中第11行从intent中获取 了消息后,没有检查包含该消息的对象(字符串类型)是否为空,而在第12行直接调用该对 象的功能函数,导致空指针异常的抛出,该异常信息会被输出到日志中。

因此当组件出现异常,可以通过正则匹配的方法可以在日志文件中找到异常信息,在本 例中可以找到“Caused by:java.lang.NullPointerException”的异常信息,表明TestReceiver没 有对外部数据进行空值判断而进行了其他操作,说明该动态Receiver组件存在本地拒绝服务 漏洞。

实施例2:

从应用市场随机下载了300个应用利用本发明方法进行测试,发现有61个应用中共含有 139个动态Receiver组件,其中有79个组件不从intent中获取数据,直接判定为不含本地拒 绝服务漏洞。另外60个动态Receiver组件中参数为空或组件名称的共有45个,属于本发明 检测范围。其余15个参数不为组件名称的本发明不能检测。

利用本发明方法对这45个动态Receiver组件进行改写后测试,启动情况测试结果如表 8所示,45个动态Receiver组件中,有42个在应用一启动就能够启动,能够完成测试,启动 测试成功率约为93%。3个组件启动失败原因是由于注册组件被启动时需要从intent中接受 parcelable和Serializable类型的数据,而通过ADB工具无法构造该类型数据导致注册组件启 动后运行出错而无法调用注册函数注册动态Receiver组件。

表8动态Receiver组件启动成功情况

组件漏洞数量的对比结果如表9所示,应用本发明所述的方法在上述启动测试成功的42 个组件中能够检测出7个漏洞,而应用人工代码分析并实验验证,发现在42个组件中,共有 9个漏洞,除了检测出的7个漏洞外,另外2个漏洞没被检测到的原因是只有当action为特 定值时动态Receiver组件才会出现异常,而在实施例1中应用的Ic3工具对这2个动态Receiver 组件没能正确分析出组件能够接受的action值。

表9漏洞检测数量对比

对比市面上的漏洞检测工具,将上述300个应用递交给阿里安全开放平台阿里聚安全、 360移动安全开发平台360app、漏洞检测工具Androidbugs,这些工具都未能检测除这些应 用中的动态Receiver组件存在的本地拒绝服务漏洞。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号