Android 常见安全问题

组件安全

Activity访问权限的控制(可能会导致恶意调用页面,接收恶意数据)
1.私有Activity不应被其他应用启动且应该确保相对是安全的
2.关于Intent的使用要谨慎处理接收的Intent以及其携带的信息,尽量不发送敏感信息,并进行数据校验
3.设置android:exported属性,不需要被外部程序调用的组件应该添加android:exported=”false”属性


Activity劫持(正常的Activity界面被恶意攻击者替换上仿冒的恶意Activity界面进行攻击和非法用途。)
1.在登录窗口或者用户隐私输入等关键Activity的onPause方法中检测最前端Activity应用是不是自身或者是系统应用,如果发现恶意风险,则给用户一些警示信息,提示用户其登陆界面以被覆盖,并给出覆盖正常Activity的类名。
2.设置Activity的属性:可防止系统截屏、录屏
this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE)


Service劫持、拒绝服务,以拒绝服务为例,常见的两种漏洞:
1.Java.lang.NullPointerException 空指针异常导致的拒绝服务
2.类型转换异常导致的拒绝服务ClassCastException 
解决方案
1.应用内部使用的Service应设置为私有
2.针对Service接收到的数据应该验证并谨慎处理
3.内部Service需要使用签名级别的protectionLevel来判断是否为内部应用调用。


Content Provider扮演着应用间数据共享桥梁的角色,其主要的安全风险为SQL注入和本地文件目录遍历
1.设置AndroidManifest.xml ,android:exported=”true” 属性。
2.通过控制权限来限制对Content Provider的访问


WebView安全
1.Android API level 16以及之前的版本存在远程代码执行安全漏洞,该漏洞源于程序没有正确限制使用WebView.addJavascriptInterface方法,远程攻击者可通过使用Java Reflection API利用该漏洞执行任意Java对象的方法,简单的说就是通过addJavascriptInterface给WebView加入一个JavaScript桥接接口,JavaScript通过调用这个接口可以直接操作本地的JAVA接口。
2.Android系统通过WebView.addJavascriptInterface方法注册可供JavaScript调用的Java对象,以用于增强JavaScript的功能。但是系统并没有对注册Java类的方法调用的限制。导致攻击者可以利用反射机制调用未注册的其它任何Java类,最终导致JavaScript能力的无限增强。攻击者利用该漏洞可以根据客户端能力为所欲为。


密码软键盘安全
输入数据监听攻击
键盘截屏攻击
输入数据篡改攻击
未加密前篡改
来自系统底层的内存dump攻击


通讯安全
客户端是否使用了TSL/SSL通信协议进行加密通信传输。没有经过使用加密协议进行加密的网络通信可以轻易地进行MITM(中间人攻击)查看敏感数据。
客户端程序提交数据给服务端时,密码等关键字段是否进行了加密和校验,防止恶意用户嗅探和修改用户数据包中的密码等敏感信息。
客户端访问的URL页面是否仅能由手机客户端访问


策略安全
客户端是否限制登录尝试次数。防止木马使用穷举法暴力破解用户密码
客户端在一定时间内无操作后,是否会使会话超时并要求重新登录。超时时间设置是否合理。
若用户帐号被盗,攻击者会进行帐号登录,如果客户端没有帐号登录限制,那么攻击者登录帐号进行操作会变得没有障碍。而客户端若进行了多点登录检测,那么用户就可以通过登录把攻击者踢下线,妨碍攻击者进行账户操作
客户端程序在切换到后台或其他应用时,是否能恰当响应(如清除表单或退出会话),防止用户敏感信息泄露。
客户端的各个界面,测试是否存在敏感信息泄露问题
界面劫持是指当客户端程序调用一个activity组件来显示窗口时,被恶意的第三方程序探知,如果该界面组件式恶意程序预设的攻击对象,恶意程序立即启动自己的仿冒界面并覆盖在客户端程序界面之上。当发生界面劫持时,用户在无察觉的情况下将自己的账号、密码信息输入到仿冒界面中,恶意程序再将这些数据发送给攻击者。


安全问题的检测与预防
安全问题的检测
静态分析:
在不运行源码的情况下,通过IDA、apktool、dex2jar、jd-gui、smali2dex等静态分析工具对应用进行反编译,并对反编译后的java文件、xml文件等文件静态扫描分析,通过关键词搜索等静态方式将具有安全隐患的代码进行摘录并存入到检测平台后台,为后续的安全检测报告提供数据依据。

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

人工检测:
1.企业招聘相关安全人员,对APP应用软件安装、运行过程的行为监测和分析,记录APP程序可能表现出来的风险行为。 
2.使用第三方众测平台,帮助企业发现APP应用漏洞及风险。

安全问题的预防技巧
反调试
通常APP可能会被不法人员或者其他不法程序使用特定的方法进行调试、跟踪和劫持,被调试后的APP的一切操作和行为都可以被轻易的查看和修改。

上线前关闭调试模式android:debuggable=”false“
使用双进程守护实现反调试,我们知道通常一个进程只允许有一个调试器,所以在进程起来的同时,会FORK一个守护进程,并跟踪被保护的APP进程,它会一直存活,直到APP退出。在这期间一旦发现有不法调试行为发生,守护进程便会拦截调试器的入口,保证其他程序无法再调试当前APP。如果恶意关闭守护进程,则当前 APP也会随之关闭,已达到保护APP的目的。
反注入
注入是指当前 APP进程被其他程序使用特定方法动态插入不属于当前 APP的模块。然后恶意如收集 APP的隐私数据,并使用 Hook等方法劫持 APP的正常运行流程等(包括HOOK)。

针对Java Hook我们可以通过检查vm dex内存的fields域和method域来判断是否有java注入。
针对So Hook我们可以查看app 进程空间,查看加载的库是不是都在/system或/data/data/app底下,如果不是,则一定有注入。


混淆日志
我们在开发过程中大都是统一设置日志开关,上线时把日志关闭,其实这样做也不保险,因为逆向APP第一步动作就是先找Log的开关,找到开关之后,把它打开,然后跑一遍程序,就很容易找到隐私信息。建议对于安全性要求较高的APP,尽量还是把日志混淆或者干脆把所有的Log信息都去掉。

防篡改、签名校验
在发布前校验一下签名使用的key是否正确,以防被恶意第三方应用覆盖安装或者篡改等可使用下列命令检查: 
jarsigner -verify -verbose -certs apk包路径若结果为“jar 已验证”,说明签名校验成功。

allowBackup
allowBackup,是Google提供了一个备份的功能,如果用户要换手机了,可以用它把APP导到另一个手机上,用户本身使用的一些数据(聊天记录)会跟着一起备份过去。除了备份使用外,它还带来了两个问题: 
1. 恶意程序也可以利用这个备份,并把你备份的数据传到网上,在他的手机上打开。如果我们在做换手机操作过程中没有做全面的校验,那将会造成直接性的用户隐私信息泄露,用户的个人信息和隐私操作将会被暴露出来 
2.这个备份的时候,会生成一个加密的文件。这个加密文件是可以被篡改的,而且你再利用这个备份文件导到另一个手机的时候,校验的时候可以直接过。就是你把备份导出来,病毒可以在导入文件加入恶意的代码或者其他的数据。你去进行备份的时候,相当于重新安装了,你在另外一个手机重新安装的时候,你重装的的APP上就携带着的病毒,后果非常危险。

APP完整性检验
为确保安装包不会在测试完成到最终交付过程中因为一些原因而发生文件损坏,需要对安装包进行完整性校验,通常做法是检查文件的md5值,而且一般可以通过自动化做校验。

数据加密
对于APP中需要存储的重要数据,一定要加密后再存储到数据库中。平时在于测试环节,一定要要求测试人员使用抓包工具对接口数据进行审阅,确保数据是加密后传输。

证书校验
严格来讲,我们要对数字证书合法性进行验证。即便使用了安全通信,例如HTTPS,我们也需要在客户端代码中对服务端证书进行合法性校验。测试中可以使用Fiddler、Charles等等工具模拟中间人攻击方法。如果客户端对于这些第三方工具的证书没有校验而能正常调用,则存在安全隐患。

权限问题
通常用户对自己的隐私问题十分敏感,为此,我们需要对APP申请某些特定权限的必要性进行检查,如访问通讯录等。对于没有必要的权限,一般都建议开发直接删除。切勿出现因为开发便利等原因,而盲目在配置文件中向用户索取过多无用权限的事情。

安全检测的项目
1)客户端安全测试包含
客户端程序保护 
– 描述:判断是否能反编译为源代码,是否存在代码保护措施 
– 测试:是否能通过用反编译工具查看源代码 
– 建议:建议客户端进行加壳处理防止攻击者反编译客户端,同时混淆客户端代码,并且一定要对核心代码进行代码混淆。
安装包签名 
– 描述:客户端安装包是否正确签名。通过签名,可以检测出安装包在签名后是否被修改过。 
– 检测:利用二次打包工具能否成功打包运行 
– 建议:客户端使用从属方证书进行签名后进行发布而不是使用第三方开发商的证书进行签名,以防开发商内部监管异常,证书滥用的情况出现。
应用完整性校验 
– 描述:测试客户端程序安装后,在每次启动时是否对自身文件进行完整性校验。 
– 检测:修改资源文件,二次打包能否运行 
– 建议:建议客户端在每次开机启动时进行客户端自身的应用完整性校验,在验证逻辑中不使用MANIFEST.MF中的数据作为验证凭证,同时需验证是否有不属于该客户端版本的新文件添加,验证过程于服务器端完成。
组件安全 
– 描述:测试客户端是否包含后台服务、Content Provider、第三方调用和广播等组件,Intent权限的设置是否安全。应用不同组成部分之间的机密数据传递是否安全。程序是否窃取手机用户的隐私信息。 
– 建议:建议在开发客户端时不要暴露内部组件,如果有特殊需求也需进行权限控制,令使用这些组件时需要申请相应权限。

整体解决:以上客户端程序保护可通过代码混淆配合apk加固全部解决

2)敏感信息安全包含
私有目录下的文件权限 
– 描述:测试客户端私有目录下的文件权限是否设置正确,非root账户是否可以读,写,执行私有目录下的文件。 
– 检测: 

– 建议:私有目录下文件不可读写
SQLite数据库文件的安全性 
– 描述:敏感信息是否明文存储 
– 检测:检测数据库里面的重要信息,比如账号密码之类的是否明文存储 
– 建议:重要信息进行加密存储
Logcat日志 
– 描述:检测客户端对应的Logcat日志是否会打印一些用户或服务器的敏感信息。 
– 检测:用ddms工具寻找敏感信息输出 
– 建议:具有敏感信息的调试信息开关一定要关闭。
整体解决:对于安卓开发来讲,我们解决敏感信息问题就是对重要数据进行加密存储,log日志不打印敏感信息。我是真的见过账号密码保存在本地明文存储的,所以切记加密存储重要信息
3)密码软键盘
键盘劫持测试 
– 描述:测试客户端程序在密码等输入框是否使用自定义软键盘。安卓应用中的输入框默认使用系统软键盘,手机安装木马后,木马可以通过替换系统软键盘,记录应用的密码。 
– 检测:这个应该通过看就能看出来 
– 建议:建议客户端开发自定义软键盘而不是使用系统软件盘以防止键盘劫持攻击。
软键盘安全性测试 
– 描述:测试客户端是否使用随机布局的密码软键盘。 
– 检测:还是眼睛看 
– 建议:建议客户端对自定义软键盘进行随机化处理,同时在每次点击输入框时都进行随机初始化。
屏幕录像测试 
– 描述:测试通过连续截图,是否可以捕捉到用户密码输入框的密码。 
– 检测:通过连续截图,是否可以捕捉到用户密码输入框的密码。 
– 建议:建议客户端针对第三方或系统截屏编写抵抗逻辑,例如屏蔽和截屏相关的函数或是当客户端处于进程栈顶层时将截屏图片用纯黑色图片对象进行覆盖。
整体解决:键盘劫持一般都是要自定义键盘的,而且自定义的键盘不要长的和系统键盘一样就行,每次点击输入框时都进行随机初始化倒是没必要。因为很多银行的也没有这样做,而且做起来我认为困难还是有的。以手机银行例,大多数银行采用自绘键盘代替系统键盘,防止了系统键盘监听行为,但有些开发者忽略了截屏保护,这样连续快速截屏,或者视频录制就可以获取用户的密码。下面代码是防截屏、视频录制的代码 :

getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); // 防止屏幕截屏
4)安全策略
密码复杂度 
– 描述:测试客户端程序是否检查用户输入的密码,禁止用户设置弱口令 
– 测试:修改设置用户名密码时,可以设置111111类似弱口令 
– 建议:建议在服务器编写检测密码复杂度的安全策略,并将其运用到账号注册,密码修改等需要进行密码变更的场景,以防止攻击者通过弱密钥遍历账户的方式进行暴力猜解。
账户锁定策略 
– 描述:测试客户端是否限制登录尝试次数。防止木马使用穷举法暴力破解用户密码 
– 测试:错误密码登录请求多次(10次以上还没有就有问题了,一般都是3次) 
– 建议:建议在服务端编写账户锁定策略的逻辑,当一天内多次输入密码错误时进行账号锁定以防止攻击者通过暴力猜解密码。
会话安全设置 
– 描述:测试客户端在一定时间内无操作后,是否会使会话超时并要求重新登录。超时时间设置是否合理。 
– 检测:客户端在一定时间内无操作(20分钟足够),是否会话超时登录 
– 建议: 建议在客户端编写会话安全设置的逻辑,当10分钟或20分钟无操作时自动退出登录状态或是关闭客户端。
界面切换保护 
– 描述:检查客户端程序在切换到后台或其他应用时,是否能恰当响应(如清除表单或退出会话),防止用户敏感信息泄露 
– 检测:应用切换到后台但程序没有结束运行,再返回应用的时候是否有身份验证 ,手势密码或者登陆密码。 
– 建议:建议客户端添加响应的逻辑,在进行进程切换操作时提示用户确认是否为本人操作。
界面劫持保护 
– 描述:检查客户端是否对非正常的界面切换进行检测,并对用户进行提示。 
– 检测:界面被劫持时是否有提示 
– 建议: 由于Activity界面劫持攻击通常是将自己的页面附着在客户端之上,因此需要进行界面切换操作,因此使用界面切换保护的安全建议可以达到一定的效果。除此之外,因为Android进程栈的工作原理,建议开发客户端时针对进程栈进行相应的保护,可禁止其他进程放置于客户端之上。
UI信息泄露 
– 描述:检查客户端的各种功能,看是否存在敏感信息泄露问题。 
– 检测:比如登录时,密码输入错误,APP是否会提示密码输入错误 
– 建议:建议用户名或密码输入错误均提示“用户名或密码错误”,若客户端同时还希望保证客户使用的友好性,可以在登陆界面通过温馨提示的方式提示输入错误次数,密码安全策略等信息,以防用户多次输入密码错误导致账号锁定。
账号登录限制 
– 描述:测试能否在两个设备上同时登录同一个帐号。 
– 检测:测试能否在两个设备上同时登录同一个帐号。 
– 建议:建议在服务器进行账号登陆限制相应逻辑代码的编写,通过Session或数据库标志位的方式控制同一时间只有一个设备可以登陆某一账号。
安全退出 
– 描述:验证客户端在用户退出登录状态时是否会和服务器进行通信以保证退出的及时性 
– 检测:客户端在用户退出登录时,查看session是否可用 
建议:保证客户端和服务器同步退出,APP退出时服务器端的清除会话
密码修改验证 
– 描述:验证客户端在进行密码修改时的安全性 
– 检测:是否存在原密码验证 
– 建议:建议在修改密码时,客户端及服务器系统增添原密码输入验证身份的逻辑,以防Cookie登陆修改密码的攻击。
私密问题验证 
– 描述:验证客户端是否存在忘记密码时的私密问题验证 
– 检测:类似于QQ的私密问题验证 
– 建议:我觉得这个根据需求走,也不一定说这个就好。一个普通的APP这样搞,用户体验会很差。除非你做到了QQ那种地步

整体解决:需要和后台配合。界面劫持代码: 

@Override 
protected void onPause() { 
// 若程序进入后台不是用户自身造成的,则需要弹出警示 
if (needAlarm) { 
// 弹出警示信息 
Toast.makeText(getApplicationContext(), 
"XX的登陆界面被覆盖,请确认登陆环境是否安全", Toast.LENGTH_SHORT).show(); 

super.onPause(); 

就是在登录界面重写onPause方法。这个界面劫持只需要在登录界面做防护。needAlarm是定义的变量,初始化为true,然后监听home键和返回键以及你自身登录界面的其他activity的跳转。如果用户执行了监听的操作needAlarm赋值为false,说明是用户自身的操作,不是界面劫持。

5)手势密码
手势密码复杂度 
– 描述:测试客户端手势密码复杂度,观察是否有点位数量判断逻辑 
– 检测:这个应该没有明确的,就是自身感受吧 
– 建议:自己定标准吧

手势密码修改和取消 
– 描述:检测客户端在取消手势密码时是否会验证之前设置的手势密码,检测是否存在其他导致手势密码取消的逻辑问题 
– 检测:检测客户端在取消手势密码时是否会验证之前设置的手势密码,检测是否存在其他导致手势密码取消的逻辑问题 
– 建议:不应该存在其他导致手势密码取消的逻辑,客户端在取消手势密码时应验证之前设置的手势密码

手势密码本地信息保存 
– 描述:检测在输入手势密码以后客户端是否会在本地记录一些相关信息,例如明文或加密过的手势密码。 
– 检测:找到存储文件,看其是否加密 
– 建议:应该进行加密

手势密码锁定策略 
– 描述:测试客户端是否存在手势密码多次输入错误被锁定的安全策略。防止木马使用穷举法暴力破解用户密码。因为手势密码的存储容量非常小,一共只有9!=362880种不同手势,若手势密码不存在锁定策略,木马可以轻易跑出手势密码结果。手势密码在输入时通常以a[2][2]这种3*3的二维数组方式保存,在进行客户端同服务器的数据交互时通常将此二维数组中数字转化为类似手机数字键盘的b[8]这种一维形式,之后进行一系列的处理进行发送。

手势密码抗攻击测试 
– 描述:验证是否可以通过插件绕过手势密码的验证页面

整体解决:手势密码检测。

6)通信安全
通信加密 
– 描述:验证客户端和服务器之前的通信是否使用加密信道。 
– 检测:可以利用抓包软件进行查看 
– 建议:使用https或者是http+403端口进行通信。

关键数据加密和校验 
– 描述:测试客户端程序提交数据给服务端时,密码等关键字段是否进行了加密和校验,防止恶意用户嗅探和修改用户数据包中的密码等敏感信息。 
– 检测:抓包 
– 建议:建议账号,密码,卡号,金额等进行加密处理,同时整个数据包进行二次加密,返回的敏感信息进行加密,同时返回数据包进行二次加密,并且使用增加随机因子的校验字段,并且确定服务器逻辑标志位正确,在删除校验字段时服务器不响应提交的数据包。

证书有效性验证 
– 描述:验证客户端和服务器之间是否存在双向验证的机制,同时确认此机制是否完善,服务器是否以白名单的方式对发包者的身份进行验证 
– 检测:抓包 
– 建议:建议客户端和服务器进行双向认证,并且服务器通过白名单的方式验证客户端证书以保证证书的有效性。

访问控制 
– 描述:测试客户端访问的URL是否仅能由手机客户端访问。是否可以绕过登录限制直接访问登录后才能访问的页面,对需要二次验证的页面(如私密问题验证),能否绕过验证。 
– 检测:利用截包工具获取url,能用浏览器打开该url。 
– 建议:建议服务器进行相应的访问控制,控制对应页面仅能通过手机客户端访问。同时进行页面访问控制,防止绕过登陆直接访问页面的非法访问。

短信重放攻击 
– 描述:检测应用中是否存在数据包重放攻击的安全问题。是否会对客户端用户造成短信轰炸的困扰。 
– 建议:抓包 
– 建议:token和手机号一起,重放无法造成短信轰炸。

7)业务安全
这个需要根据业务进行检测。

8)一般黑客进行攻击多用模拟器进行攻击。现在的模拟器基本和手机一样。我们无法过滤所有的模拟器,但是可以过滤免费的模拟器,也就是一定程度上进行防护
实践大多数免费的模拟器,都没有蓝牙的功能
BluetoothAdapter blueadapter = BluetoothAdapter
                                .getDefaultAdapter();
                        if ((blueadapter == null)
                                || (blueadapter.getAddress() == null && blueadapter
                                        .getName() == null)) {
                            MessageBox.promptDialog("请使用真实手机登陆",
                                    LoginActivity.this);
                        } 

当然else之后我是登录操作,但是登录前做了一些东西。这个就像消息推送一样,手机的唯一标识cid之类的绑定。这里只是给出个思路

9)短信验证 做60秒倒计时。
10)App测试安全等级划分

11)工具及相关资源
工具名称 Apktool 
工具用途 GOOGLE提供的APK编译工具,能够反编译及回编译apk。 
相关信息 https://code.google.com/p/android-apktool/
工具名称 Dex2jar 
工具用途 将Android的dex文件反编译为java源码。 
相关信息 https://code.google.com/p/dex2jar/w/list
工具名称 Jd-gui 
工具用途 反编译代码阅读工具。 
相关信息 http://jd.benow.ca/
工具名称 Portecle 
工具用途 证书管理工具,可以进行证书维护。 
相关信息 http://www.oschina.net/p/portecle
工具名称 SuperOneClick 
工具用途 Android手机root工具 
相关信息 http://www.superoneclick.cc/
工具名称 Proxydroid 
工具用途 Android手机用代理软件。 
相关信息 https://github.com/madeye/proxydroid
工具名称 MemSpector 
工具用途 Android手机内存修改工具 
相关信息 http://www.nosec.org
工具名称 BurpSuite 
工具用途 HTTP数据包修改、转发工具 
相关信息 http://portswigger.net/burp/
工具名称 Fiddler 
工具用途 HTTP数据包修改、转发工具 
相关信息 http://www.fiddler2.com/fiddler2/
工具名称 Xposed框架 
工具用途 系统级框架,用于开发底层插件进行测试 
相关信息 http://repo.xposed.info/module/de.robv.android.xposed.installer
工具名称 SwipeBack 
工具用途 Xposed插件,用于绕过登陆界面 
相关信息 http://repo.xposed.info/module/us.shandian.mod.swipeback
工具名称 Android Development Tools 
工具用途 支持Android开发的工具 
相关信息 http://developer.android.com/tools/help/adt.html

更多相关文章

  1. [email protected] 的 Android 和 iOS 客户端全面开源
  2. PasswordMaker的Android客户端
  3. Android客户端与PC服务器实现Socket通信
  4. Android仿人人客户端(v5.7.1)——新鲜事之完整篇
  5. Android 客户端上开发人人客户端系列教程
  6. Android 客户端访问服务器以及服务器开发
  7. Android客户端与PC服务器实现Socket通信(wifi)
  8. Android:SNS客户端开发四:数据库操作(二)
  9. Android中可以做的两件坏事---破解锁屏密码和获取Wifi密码

随机推荐

  1. Android 锁屏问题
  2. Android版本适配问题处理
  3. Android Priority Job Queue:一个专门为An
  4. Android面经| 问题归纳
  5. android实现自动发送邮件
  6. 控件布局_RelativeLayout
  7. Java的消息机制
  8. android 布局中 layout_gravity、gravity
  9. android数字证书-签名(步骤)
  10. Android(安卓)图形架构