Android-APP安全测试(二)

2018-09-29 50,867

继上一篇Android-APP 安全测试(一)的内容

图片1.png

此流程图是我在学校为学生讲课时按课程安排做的,测试点可做为参考,主要为APP自身漏洞的客户端测试为主。后续文章会继续完善~


APP面临的主要风险

客户端:

传统逆向分析类(反编译、调试、加密/签名破解…)

用户已经中招类(输入记录、导出组件、进程注入…)

 

服务端:

系统组件类(MS12-020、ShellShock、心血、ST2…)

业务应用类(注入跨站越权执行上传下载弱口令…)


本地客户端测试

本章我主要介绍的本地客户端的测试,所需要的环境、工具、APK文件结构、架构、测试点等。

图片2.png


客户端测试 - 组件导出安全

什么是组件?

  •  安卓APP以组件为单位进行权限声明和生命周期管理;

组件有什么用?

  • 安卓系统的组件共有四种,其主要用途分别为:

  • Activity:呈现可供用户交互的界面,是最常见的组件;

  • Service:长时间执行后台作业,常见于监控类应用;

  • Content Provider:在多个APP间共享数据,比如通讯录;

  • Broadcast Receiver:注册特定事件,并在其发生时被激活

  • 什么是权限声明?

  • 安卓系统定义了许多权限声明项,分别对应一些操作系统功能

权限声明有什么用?

  • 如果一个APP或组件在没有声明权限的情况下就调用相关API,会被拒绝访问;

  • 但如果声明了相关权限,安装的时候就会有提示;

  • 这样一来,用户就可以评估使用该APP可能带来的风险

什么是组件导出?

  • 简而言之,就是别的APP也可以访问这个组件。

  • 再总而言之,就是组件权限的控制。

组件导出有什么用?

  • 有些APP的功能需要提供一些接口给其它APP访问,就需要把相关的接口功能放在一个导出的组件上。

组件导出有什么危害?

因为权限声明是以组件为单位的,A组件调用B组件的功能来访问操作系统API时,适用于B组件的权限声明。

如果B作为导出组件,没有进行严格的访问控制,那么A就可以通过调用B来访问原本没有声明权限的功能,构成本地权限提升。


四大组件详细介绍

Activity组件漏洞

Activity是Android组件中最基本也是最为常见用的四大组件之一,是一个负责与用户交互的组件。Activity组件中存在以下常见的漏洞。 (1)activity绑定browserable与自定义协议activity设置“android.intent.category.BROWSABLE”属性并同时设置了自定义的协议android:scheme意味着可以通过浏览器使用自定义协议打开此activity。可能通过浏览器对app进行越权调用。(2)ActivityManager漏洞ActivityManager类中的killBackgroundProcesses函数,用于杀死进程,属于风险API。还有通过ActivityManager被动嗅探intent。Intent嗅探脚本首先调用一个Context.getSystemService()函数,并传给它一个ACTIVITY_SERVICE标志的标识符,该函数返回一个ActivityManager类的实例,它使得该脚本能够与activity manager进行交互,并通过这个对象调用ActivityManager.getRecentTasks()方法。最后把intent相关的信息格式化成字符串返回出来。


Service组件

作为Android中四大组件之一,拥有重要的地位。Service具有和Activity一样的级别,只是没有界面,是运行于后台的服务。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。从表面上看service并不具备危害性,但实际上service可以在后台执行一些敏感的操作。Service存在的安全漏洞包括:权限提升,拒绝服务攻击。没有声明任何权限的应用即可在没有任何提示的情况下启动该服务,完成该服务所作操作,对系统安全性产生极大影响。


BroadcastReceiver导出漏洞

当应用广播接收器默认设置exported='true',导致应用可能接收到第三方恶意应用伪造的广播,利用这一漏洞,攻击者可以在用户手机通知栏上推送任意消息,通过配合其它漏洞盗取本地隐私文件和执行任意代码。Android 可以在配置文件中声明一receiver或者动态注册一个receiver来接收广播信息,攻击者假冒APP构造广播发送给被攻击的receiver,是被攻击的APP执行某些敏感行为或者返回敏感信息等,如果receiver接收到有害的数据或者命令时可能泄露数据或者做一些不当的操作,会造成用户的信息泄漏甚至是财产损失。


Content Provider组件漏洞

Content Provider为存储和获取数据提供统一的接口。可以在不同的应用程序之间共享数据。(1)读写权限漏洞Content Provider中通常都含有大量有价值的信息,比如用的电话号码或者社交帐号登录口令,而确认一个content provider是否有能被攻击的漏洞的最好的办法,就是尝试攻击它一下。可以用drozer来寻找一些不需要权限的contentprovider:dz> runapp.provider.info –permission null这条命令能列出所有不需要任何读写权限的Content Provider,然后找到相对应的包,去访问给定包存放在它的Content Provider中的数据。如果一些Content Provider的URI不需要读权限,那就可以通过drozer工具提取其中的数据。在某些情况下,设置和执行读写权限不当,也会将ContentProvider中的数据暴露给攻击者。除了提取数据,对于写权限管理不当的Content Provider还可以向其中写入数据,使得攻击者可以将恶意数据插入到数据库中。(2)Content Provider中的SQL注入漏洞和Web漏洞类似,安卓APP也要使用数据库,那就也有可能存在SQL注入漏洞。主要有两类,第一类是SQL语句中的查询条件子语句是可注入的,第二类是投影操作子句是可注入的。使用drozer可以很容易的找出查询条件子句可注入的content provider。dz> runapp.provider.query [URI] –selection “1=1”也可以使用其他恒为真的值,例如“1-1=0”,“0=0”等等。如果APP存在SQL注入漏洞,那么输入这行指令后就会返回数据库中的整张表。(3)Provider文件目录遍历漏洞当Provider被导出且覆写了openFile方法时,没有对Content Query Uri进行有效判断或过滤。攻击者可以利用openFile()接口进行文件目录遍历以达到访问任意可读文件的目的。


组件测试工具-drozer

Drozer是MWRLabs开发的一款Android安全测试框架。是目前最好的Android安全测试工具之一

环境准备:

1 手机获得root权限

2 adb.exe、配置android环境变量

3 手机usb连接开启debug模式(在设置>关于手机>连续点击多次版本号,即可开启开发者模式)

4 Window下安装drozer

5安装完drozer后在其目录下把agent.apk安装到手机


连接准备:

1 drozer console devices

图片3.png
图片4.png

启动drozer:
adb forward tcp:31415 tcp:31415   //将pc端31415的所有数据转发到手机上的31415端口
drozer console connect   //使用drozer console 连接agent

图片5.png

获取手机上所有安装的app包名:run app.package.list  加上”-f [app关键字]”查找某个app,如 run app.package.list -f sieve 

图片6.png


获取sieve的基本信息run app.package.info –a com.mwr.example.sieve

图片7.png


可以看到sieve的版本信息,数据存储目录,用户ID,组ID,共享库,权限等信息

run app.package.attacksurface  com.mwr.example.sieve

图片8.png


进一步获取每个组件的攻击面信息,如activity

run app.activity.info这条命令将导出你设备上的所有的activity

run app.activity.info -a com.mwr.example.sieve
图片9.png


其中. MainLoginActivity是app启动时的主界面,必须可以导出,但其他两个activity正常情况下是不能导出的

用drozer来启动可导出且不需要权限的activity

run  app.activity.start  --component  com.mwr.example.sieve  com.mwr.example.sieve.PWList
图片10.png


获取content provider的信息

run app.provider.info -a com.mwr.example.sieve
图片11.png


结合上面查看攻击面的信息,这2个content provider都可导出,com.mwr.example.sieve.DBContentProvider/Keys 是需要读写权限的

图片12.png


往下关于drozer工具的使用百度都有详细的介绍,这里不再做继续介绍。


客户端测试 - 组件导出安全配置

组件完全满足以下条件之一,则可以导出

显式声明了android:exported="true"

 

未显式声明android:exported="false";

组件不是Content Provider;

组件包含<intent-filter>;

 

未显式声明android:exported="false";

组件是Content Provider;

声明API最小版本<17;


AndroidManifest.xml

图片13.png


AndroidManifest.xml是Android应用的入口文件,它描述了package中暴露的组件(activities, services, 等等),他们各自的实现类,各种能被处理的数据和启动位置。 除了能声明程序中的Activities, ContentProviders, Services, 和In

android:allowClearUserData(‘true’ or ‘false’)
用户是否能选择自行清除数据,默认为true,程序管理器包含一个选择允许用户清除数据。当为true时,用户可自己清理用户数据,反之亦然

AndroidManifest.xm一些特定属性的介绍,可自行百度。下面只是几个举例:

android:allowTaskReparenting(‘true’ or ‘false’)

是否允许activity更换从属的任务,比如从短信息任务切换到浏览器任务

android:debuggable

这个从字面上就可以看出是什么作用的,当设置为true时,表明该APP在手机上可以被调试。默认为false,在false的情况下调试该APP,就会报以下错误:

Device XXX requires that applications explicitely declare themselves as debuggable in their manifest.
Application XXX does not have the attribute ‘debuggable’ set to TRUE in its manifest and cannot be debugged.

android:exported 是Android中的四大组件 Activity,Service,Provider,Receiver 四大组件中都会有的一个属性。

总体来说它的主要作用是:是否支持其它应用调用当前组件。
默认值:如果包含有intent-filter 默认值为true; 没有intent-filter默认值为false。


客户端测试 - 本地敏感信息安全

查看应用程序所在目录(需root权限)

一般为:/data/data/{APP包(package)名}/

如遇.db文件,多为SQLite数据库。

正常的文件权限最后三位应为空(类似“rw-rw----”),目录可以多一个执行位(类似“rwxrwx—x”)

图片15.png
图片16.png



Android系统的五种数据存储形式:

分别是文件存储、SP存储、数据库存储、contentprovider 内容提供者、网络存储


文件存储: 

以I/O流的形式把数据存入手机内存或SD卡,可以存储大数据,如音乐、图片或视频等。对于手机内存来说系统会根据每个应用的包名创建一个/data/data/包名/的文件夹,访问自己包名下的目录是不需要权限的,并且 Android 已经提供了非常简便的 API 可以直接去访问该文件夹。访问时可以用getFilesDir()和getCacheDir(),两个的区别是系统会自动清理后者中的内容。

SD卡中的文件通常位于mnt/sdcard目录下,不同生产商生产的手机这个路径可能不同。操作sd卡的时通常要判断下sd卡是否可用以及剩余空间是否足够,因为部分手机的SD卡可卸载,SD卡处于非挂载状态时,无法进行读写操作。另外一点,对SD卡的读取和写入操作均需要相应的权限,否则无法完成。获取SD卡路径的方法是Environment.getExternalStorageDirectory(),其余操作与文件存储基本类似。

图片17.png


shared preferences:SP存储

可以看到goatdroid应用的用户名和密码都以明文的形式存储在 shared preferences中SP存储本质上是一个XML文件,以键值对的形式存入手机内存中。常用于存储简单的参数设置,如登陆账号密码的存储,窗口功能状态的存储等,该存储文件位于:data/data/包名/shared_prefs文件夹中。使用的时候,首先需要通过context.getSharedPrefrences(String name,int mode)获取SharedPrefrences的实例对象,存储数据时,用SharedPrefrences的实例对象得到SharedPrefrences文件的编辑器,在编辑器中用putXxx()添加数据,之后务必用commit提交数据,否则无法获取数据。取数据时,直接用getXxx()方法。


图片18.png


sp存储自动生成xml文件,其的路径如下: 

图片19.png

数据库存储:

数据库所有信息都存储在单一文件内,占用内存小,并且支持基本SQL语法,是项目中经常被采用的一种数据存储方式,通常用于存储用户信息等,例如在手机上做一个学生信息管理系统。SQLite 是一款内置到移动设备上的轻量型的数据库,SQLiteOpenHelper 是Android 提供的一个抽象工具类,负责管理数据库的创建、升级工作。数据库的路径为:/data/data/应用包名/databases/数据库。

从手机文件中导出数据库文件并不可以直接打开,因此可以用可视化工具和sqlite3操作工具进行查看。这里介绍sqlite3工具的使用。具体需要的步骤如下: 

 1. 执行adb shell命令进入Linuxne内核;

 2. 使用cd进入数据库所在的路径 cd: /data/data/应用包名/databases;

 3. 进入数据库模式: sqlite3 数据库名.db;

 4. 执行SQL语句

图片20.png

Content Provider: 

Content Provider,中文名是内存提供者,Android四大组件之一,内容提供者是应用程序之间共享数据的接口,以数据库形式存入手机内存,可以共享自己的数据给其他应用使用。之所以需要设计一个单独的控件来操作数据,是为了实现应用程序之间的数据传递。通过查看DDMS中的目录结构可以看出,数据库文件对于其他应用来说是不可读、不可写,而日常生活中又需要获取其他应用的数据,尤其是系统自带软件的数据。比如打开QQ或者微信时会提示是否同步联系人,又比如备份短信的时候,这些都需要访问和操作其他应用的数据库。因此谷歌工程师在底层软件中集成了大量的方法利用内存提供者的原理,类似于在数据库中提供一个对外访问的路径,供其他应用访问。

具体操作是:创建内容提供者解析器,定义要访问的Uri的路径。Uri路径有着固定的格式:”content://主机名/匹配字符”。 利用内容提供者解析器进行增删改查,和要操作的数据库之间建立联系。以上内容通常用来理解内容提供者的工作原理,实际工作中很少用到自定义的内容提示者。实际中用的比较多的是用内容提供者操作系统联系人、系统短信等系统应用的数据库。

先看一下短信和手机联系人有关的数据库所在的路径。短信在Android 模拟器下存放在的路径是:/data/data/com.android.providers.telephony/databases/目录,联系人在Android 模拟器下存放在的路径是:/data/data/com.android.providers.contacts/databases/目录。对于短信数据库我们关心的表数据有:address、type、body、date,分别表示发送者号码、短信类型(收还是发)、短信内容、日期。对于联系人数据库的三张表一定要按照一定的顺序依次查找才能得到相关的数据,在这不做解释。尽管开发的时候不需要了解短信和手机联系人的数据库路径,但是要明白短信和手机联系人的数据是存在数据库中的,同时数据库对外是不开放的。


与短信有关的数据库的目录结构:

图片21.png


网络存储:

网络存储是最容易理解的一种存储方式了。其实说简单点就是文件的上传和下载。经常听到的云备份就是这种形式。优势也很明显,即把数据存储到服务器,不存储在本地,使用的时候直接从网络获取,避免了手机端信息丢失以及其他的安全隐患。因此,对于这种形式就不作多的解释


客户端测试 - 本地敏感信息安全

用logcat命令查看APP的日志


清空日志  :logcat -c

实时查看日志 :logcat

一次性输出 :logcat -d

图片22.png

发布APP前,去掉Log输出代码


用DDMS命令查看APP的日志


图片23.png

图片24.png


客户端测试 – 签名文件的分析检测

对apk进行签名需要用到签名证书和签名工具。Android系统要求对APP进行签名的数字证书可以由开发者自己生成。签名工具有jarsigner和signapk。jarsigner是Java本身自带的一个工具,他也可以对jar进行签名的;而signapk是专门为了Android应用程序apk进行签名的工具。二者的区别是:jarsigner工具签名时使用的是keystore签名文件,signapk工具签名时使用的是pk8,x509.pem文件。


签名文件分析

应用签名完后在应用的META-INF目录下会有三个文件:

CERT.RSA、CERT.SF和MANIFEST.MF。

图片25.png


MANIFEST.MF:这是摘要文件。程序遍历Apk包中的所有文件(entry),对非文件夹非签名文件的文件,逐个用SHA1生成摘要信息,再用Base64进行编码。如果你改变了apk包中的文件,那么在apk安装校验时,改变后的文件摘要信息与MANIFEST.MF的检验信息不同,于是程序就不能成功安装。

说明:这是Android签名验证过程的第一步,保证每个APK包内的每个文件与MANIFEST.MF中的摘要值一一对应,修改某个文件内容,必须修改MANFEST.MF文件中的摘要值,使他们对应起来。

CERT.SF:这是对摘要的签名文件。对前一步生成的MANIFEST.MF,对MANIFEST.MF中的每一条内容分别进行SHA1计算,然后再用Base64编码转换。此外,把MANIFEST.MF的内容也进行SHA1计算,并且计算BASE64编码。将上述内容写入CERT.SF文件中。

(这是为了防止通过篡改文件和其在MANIFEST.MF中对应的SHA1摘要值来篡改APK,要对MANIFEST的内容再进行一次数字摘要)。


说明:这是签名认证过程的第二步,这一步做的是多第一步得到的签名文件的摘要,比如第一步中对文件和MANIFEST.MF摘要都改了,这一步中MANIFEST.MF的摘要值也要修改,否则就对应不起来。

所以,前面这两步,做的都是摘要,是为第三步骤做准备的,第三步骤才是最重要的


CERT.RSA文件中保存了公钥、所采用的加密算法等信息,此外重要的,还包括对CERT.SF中的内容的用私钥进行加密之后的值。

说明:在这一步,即使开发者修改了程序内容,并生成了新的摘要文件,MANIFEST.MF能与内容对应起来,CERT.SF也能与内容对应起来,但是攻击者没有开发者的私钥,所以不能生成正确的签名文件(CERT.RSA)。系统在对程序进行验证的时候,用开发者公钥对不正确的签名文件进行解密,得到的结果对应不起来,所以不能通过检验,不能成功安装文件。


签名工具使用:

jarsigner是JDK提供的针对jar包签名的通用工具, jarsigner只支持V1签名

位于JDK/bin/jarsigner.exe

apksigner是Google官方提供的针对Android apk签名及验证的专用工具, 默认同时使用V1和V2签名

位于Android SDK/build-tools/SDK版本/apksigner.bat

不管是apk包,还是jar包,本质都是zip格式的压缩包,所以它们的签名过程都差不多(仅限V1签名),

以上两个工具都可以对Android apk包进行签名.


V1和V2签名的区别

在Android Studio中点击菜单 Build->Generate signed apk... 打包签名过程中,

可以看到两种签名选项 V1(Jar Signature)  V2(Full APK Signature),

从Android 7.0开始, 谷歌增加新签名方案 V2 Scheme (APK Signature);

但Android 7.0以下版本, 只能用旧签名方案 V1 scheme (JAR signing)


V1签名:

来自JDK(jarsigner), 对zip压缩包的每个文件进行验证, 签名后还能对压缩包修改(移动/重新压缩文件)

对V1签名的apk/jar解压,在META-INF存放签名文件(MANIFEST.MF, CERT.SF, CERT.RSA),

其中MANIFEST.MF文件保存所有文件的SHA1指纹(除了META-INF文件), 由此可知: V1签名是对压缩包中单个文件签名验证

 

V2签名:

来自Google(apksigner), 对zip压缩包的整个文件验证, 签名后不能修改压缩包(包括zipalign),

对V2签名的apk解压,没有发现签名文件,重新压缩后V2签名就失效, 由此可知: V2签名是对整个APK签名验证

 

V2签名优点很明显:

签名更安全(不能修改压缩包)

签名验证时间更短(不需要解压验证),因而安装速度加快

注意: apksigner工具默认同时使用V1和V2签名,以兼容Android 7.0以下版本


查看V1和V2签名方式

一个检测apk是否支持v1、v2 签名的工具,SignApkV2 签名检测工具

直接调用:ApkSignerTool.verify(String apkPath)

 

命令行:

java -jar CheckAndroidSignature.jar xxxx.apk

结果:

{"ret":0,"msg":"","isV1OK":true,"isV2":true,"isV2OK":true,"keystoreMd5":"8f701cdd1c0d8856e440363185c7daf7"}
图片26.png


签名步骤

1.生成密钥对(已有密钥库,可忽略)

Eclipse或Android Studio在Debug时,对App签名都会使用一个默认的密钥库:

默认在C:\Users\用户名\.android\debug.keystore(非安全签名)

密钥库名:   debug.keystore

密钥别名:   androiddebugkey

密钥库密码: android


1.生成密钥对

 进入JDK/bin, 输入命令

keytool -genkeypair -keystore 密钥库名 -alias 密钥别名 -validity 天数 -keyalg RSA


参数:

        -genkeypair  生成一条密钥对(由私钥和公钥组成)

        -keystore    密钥库名字以及存储位置(默认当前目录)

        -alias       密钥对的别名(密钥库可以存在多个密钥对,用于区分不同密钥对)

        -validity    密钥对的有效期(单位: 天)

        -keyalg      生成密钥对的算法(常用RSA/DSA,DSA只用于签名,默认采用DSA)

        -delete      删除一条密钥

 

提示: 可重复使用此条命令,在同一密钥库中创建多条密钥对

例如:     

        在debug.keystore中新增一对密钥,别名是release

 keytool -genkeypair -keystore debug.keystore -alias release -validity 30000


图片27.png


为什么报错了:

这是因为权限问题:你的jdk目录在c盘,当前用户无写入权限。

所以要么更改jdk的保存目录,要么更改权限

方法一更改保存目录:就是讲jdk从c盘挪到其它盘。

方法二更改权限:以管理员身份运行CMD。

 

我已管理员权限运行CDM

图片28.png


2.查看密钥库

进入JDK/bin, 输入命令

keytool -list -v -keystore 密钥库名

参数:

        -list 查看密钥列表

        -v    查看密钥详情

例如:

keytool -list -v -keystore debug.keystore
图片29.png

现在debug.keystore密钥库中有两对密钥, 别名分别是androiddebugkey release


3.签名

1.方法一(jarsigner,只支持V1签名)

进入JDK/bin, 输入命令

jarsigner -keystore 密钥库名 xxx.apk 密钥别名

 

从JDK7开始, jarsigner默认算法是SHA256, 但Android 4.2以下不支持该算法,

所以需要修改算法, 添加参数 -digestalg SHA1 -sigalg SHA1withRSA

jarsigner -keystore 密钥库名 -digestalg SHA1 -sigalg SHA1withRSA xxx.apk 密钥别名

 

参数:

        -digestalg  摘要算法

        -sigalg     签名算法

 

例如:

用JDK7及以上jarsigner签名,不支持Android 4.2 以下

jarsigner -keystore debug.keystore MyApp.apk androiddebugkey

用JDK7及以上jarsigner签名,兼容Android 4.2 以下         

jarsigner -keystore debug.keystore -digestalg SHA1 -sigalg SHA1withRSA MyApp.apk androiddebugkey

 

2.方法二(apksigner,默认同时使用V1和V2签名)

进入Android SDK/build-tools/SDK版本, 输入命令

apksigner sign --ks 密钥库名 --ks-key-alias 密钥别名 xxx.apk

 

若密钥库中有多个密钥对,则必须指定密钥别名

apksigner sign --ks 密钥库名 --ks-key-alias 密钥别名 xxx.apk

 

禁用V2签名

apksigner sign --v2-signing-enabled false --ks 密钥库名 xxx.apk

 

参数:

        --ks-key-alias       密钥别名,若密钥库有一个密钥对,则可省略,反之必选

        --v1-signing-enabled 是否开启V1签名,默认开启

        --v2-signing-enabled 是否开启V2签名,默认开启

 

例如:

        在debug.keystore密钥库只有一个密钥对

 apksigner sign --ks debug.keystore MyApp.apk

在debug.keystore密钥库中有多个密钥对,所以必须指定密钥别名

apksigner sign --ks debug.keystore --ks-key-alias androiddebugkey MyApp.ap



4.签名验证

1.方法一(keytool,只支持V1签名校验)

进入JDK/bin, 输入命令

keytool -printcert -jarfile MyApp.apk (显示签名证书信息)

 

参数:

        -printcert           打印证书内容

        -jarfile <filename>  已签名的jar文件 或apk文件 

图片30.png


2.方法二(apksigner,支持V1和V2签名校验)

进入Android SDK/build-tools/SDK版本, 输入命令apksigner verify -v --print-certs xxx.apk

参数:

        -v, --verbose 显示详情(显示是否使用V1和V2签名)

        --print-certs 显示签名证书信息

例如:

        apksigner verify -v MyApp.apk
        Verifies
        Verified using v1 scheme (JAR signing): true
        Verified using v2 scheme (APK Signature Scheme v2): true
        Number of signers: 1


图片31.png
图片32.png


5. 查看CERT.RSA内容

Apk 包中的META-INF目录下,有一个CERT.RSA,它是一个PKCS7 格式的文件。

要查看apk签名信息及证书内容,即CERT.RSA文件,可用以下命令:

keytool -printcert -file path

APK解压后的文件,将签名文件中CERT.RSA拿出来用apktool 单独查看

图片33.png
图片34.png


客户端测试 - 键盘记录保护

常见的Android键盘记录主要依靠读取/dev/input/event0设备

需要root。

需要编写专门的Native测试工具

键盘、触屏之类均能捕获到。

也有通过注册输入法来窃听键盘的方法。

图片35.png


客户端测试 - 屏幕录像测试

即连续截屏,通过视觉反馈效果来窃听密码等敏感信息:

adb shell /system/bin/screencap -p 安卓设备中的输出png路径

需要root。

screencap输出到安卓设备中,不是输出到电脑中。

注意: FLAG_SECURE会妨碍screencap,

但对于root权限下直接读取屏幕缓存的方法是不起作用的,测试中不被认定为有效修复。

图片36.png
图片37.png

敏感信息输入不提供视觉反馈


客户端测试 - 进程注入保护

设法在目标APP的进程空间中执行一段代码。

一般的方法是在Native层通过pTrace,让远程进程加载一个.so链接库,从而侵入目标进程空间。

需要root;

需要编写专门的Native测试工具;

GDB也使用了类似的方法来操作远程进程。

837341139396044924.png

反调试技术实现复杂,一般通过加壳解决


客户端测试 - Activity/界面劫持保护

在目标APP启动时,立即弹出一个假界面覆盖之。

一般是通过Broadcast Receiver来监听目标APP的android.intent.action.BOOT_COMPLETED事件。

在JAVA层完成,不需要root

诱骗用户在假界面上操作,以获取其敏感信息,很难察觉Android 5.0以后从系统机制层面解决了这个问题,因此如果APK声明的最小API版本≥21,

此项无需测试,直接记为安全。

ApkTool解包后会产生apktool.yml,内含关于API版本的声明信息。

image.png
图片40.png


客户端测试 – 调试信息检测

检测程序(含服务器端和客户端)调试信息是否关闭,调试信息中是否写入敏感信息

通过运行程序,查看logcat等调试日志信息,是否有泄漏重要的URL地址、提示信息、调试信息等敏感关键字以及程序逻辑的关键流程。对于HTML页面,需要在浏览器端打开,并检查其中的JS代码等是否存留其他调试信息

这里我们用的方式是DDMS:

DDMS 的全称是Dalvik Debug Monitor Service,是 Android 开发环境中的Dalvik虚拟机调试监控服务。

 

这个工具存放在SDK-tools路径下,启动方法: [1]  

1) 直接双击ddms.bat运行;

2) 在Eclipse调试程序的过程中启动DDMS

图片41.png

双击ddms打开

图片42.png

我们看到有很多日志输出,可以观察运行日志中是否带有敏感数据

然后我们找到我们要分析的那个应用包

图片43.png

看他的进程ID是2484

图片44.png

然后下面的输出进程都是2484的

图片45.png

实时日志中若输出调试信息,攻击者可根据输出信息分析应用程序的运行逻辑,对应用程序进行恶意破坏;也可能泄露用户敏感信息。


客户端测试 –Sqlite .db文件的导出

我们的app里面用到sqlite数据库的时候, 会生成一个db文件,保存在我们手机中。有的时候,在调试数据库,很想看一下里面的表结构是否正确,这个时候就十分苦恼,因为这个db文件不能够直接拿出来,我们知道,在DDMS里面有一个FileExplorer,它里面保存着手机中的各个文件夹,但是尝试打开里面的文件夹的时候,却发现怎么点都没有东西,是真的没有吗?其实是我们没有获取到访问这个文件夹的权限。下面我们就开始一步一步的拿到真机调试中的db文件。

DDMS可以直接看手机里文件,如图:

图片46.png
图片47.png

Data/data/应用包名databases/

图片48.png
图片49.png

我们可以看到.db文件就是他的sqllite文件。可以直接导出

如果打开文件权限不够的话,这里利用就可以利用adb直接给打开的路径授权:

比如:

进去adb 然后chmod 777 /data/data/com.demo.app/databases/


在导出.db文件后,可以本地打开.db文件,分析是否存在敏感信息

推荐工具:

image.png


客户端测试 – Sqlite加密检测

Android 系统的Sqlite数据库是一个轻量级且没有加密功能的数据库,但有时候我们的数据库保存了一些重要的信息,不想让别人知道,就需要对数据库加密。但大多数的加密都需要收费的,而Sqlcipher是免费的。下面我们用sqlcipher来加密数据库。

配置工程:

注意assets下的文件

图片51.png

我们可用工具,对APP解包后,分析.so文件,

用APK改之理解包了一个APK:

图片52.png

分析出Sqlite数据库已做加密,做加密后的文件.db导出后是无法打开的:

图片53.png




本文作者:Lemon

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/76102.html

Tags:
评论  (3)
快来写下你的想法吧!

Lemon

文章数:68 积分: 647

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号