Android-APP安全测试(三)

2018-12-27 29,008

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


1、数据备份allowBackup 1

2、Debug调试 3

3、aapt的使用 3

4、App安全之网络传输安全问题 6

4.1散列算法 8

  1. 4.2对称加密之AES 8

  2. 4.3非对称加密之RSA 8

  3. 4.4加密算法漏洞 14

5、从任务栈到启动模式 15

  1. 5.1 如何看任务栈 16

  2. 5.2 dumpsys命令的使用 16

6、Android应用程序签名 debug签名 17

  1. 6.1 debug签名的认识 17

  2. 6.2 android 如何判断Apk是否签名和签名是否一致 18

 

 

1、数据备份allowBackup

Android  API Level 8 及其以上 Android 系统提供了为应用程序数据的备份和恢复功能,此功能的开关决定于该应用程序中 AndroidManifest.xml 文件中的 allowBackup  属性值,其属性值默认是 True。当 allowBackup  标志为 true 时,用户即可通过 adb backup  和 adb restore 来进行对应用数据的备份和恢复,这可能会带来一定的安全风险。

 

Android  属性 allowBackup 安全风险源于 adb backup  容许任何一个能够打开 USB 调试开关的人从Android  手机中复制应用数据到外设,一旦应用数据被备份之后,所有应用数据都可被用户读取;adb restore  容许用户指定一个恢复的数据来源(即备份的应用数据)来恢复应用程序数据的创建。因此,当一个应用数据被备份之后,用户即可在其他 Android  手机或模拟器上安装同一个应用,以及通过恢复该备份的应用数据到该设备上,在该设备上打开该应用即可恢复到被备份的应用程序的状态。

 

尤其是通讯录应用,一旦应用程序支持备份和恢复功能,攻击者 即可通过 adb backup 和 adb restore  进行恢复新安装的同一个应用来查看聊天记录等信息;对于支付金融类应用,攻击者可通过此来进行恶意支付、盗取存款等;因此为了安全起见,开发者务必将 allowBackup 标志值设置为 false  来关闭应用程序的备份和恢复功能,以免造成信息泄露和财产损失。

不在 AndroidManifest.xml 文件设置 allowBackup  属性值,其默认值为 true,则应用可通过 adb  命令进行备份整个应用的数据

 

AndroidManifest.xml文件内容:

<?xml version="1.0"  encoding="utf-8"?>
<manifest  xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.alibaba.jaq.allowbackuppoc"
           android:versionCode="1"
           android:versionName="1.0">
     <uses-sdk android:minSdkVersion="10"/>
     <uses-permission android:name="android.permission.READ_PHONE_STATE"  />
     <application
                android:label="@string/app_name">
         <activity android:name="LoginActivity"
                   android:label="@string/app_name">
             <intent-filter>
                <action  android:name="android.intent.action.MAIN"/>
                <category  android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
         <activity android:name=".HomeActivity"/>
     </application>
</manifest>

在 AndroidManifest.xml 文件显示设置 allowBackup  属性值为 false,即android:allowBackup="false",则 Android  应用不可通过 adb 命令进行备份和恢复整个应用的数据


AndroidManifest.xml文件内容

<?xml version="1.0"  encoding="utf-8"?>
<manifest  xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.alibaba.jaq.allowbackuppoc"
           android:versionCode="1"
           android:versionName="1.0">
     <uses-sdk android:minSdkVersion="10"/>
     <uses-permission android:name="android.permission.READ_PHONE_STATE"  />
     <application
             android:allowBackup="false"
             android:label="@string/app_name">
         <activity android:name="LoginActivity"
                   android:label="@string/app_name">
             <intent-filter>
                <action  android:name="android.intent.action.MAIN"/>
                <category  android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
         <activity android:name=".HomeActivity"/>
     </application>
</manifest>

查看AndroidManifest.xml文件中是否有allowBackup,如果没有则allowBackup属性值,默认allowBackup值为True,则默认为可以备份应用数据,存在安全风险;如果allowBackup属性值为false,则不可以备份应用数据。 

 

2、Debug调试

在Android中的AndroidManifest.xml文件中可以设置很多属性,其中有一项是debuggable属性,意为“可调试”,有true和false两种模式。

在准备发布应用之前要确保关闭debug属性,即设置AndroidMainifest.xml中android:debuggable="false",false表示关闭debug调试功能,true表示开启debug调试功能,但是有时候会忘记关掉这个属性。Debug调试开启会存在应用被调试的风险。

 

在发布之前最好进行测试,使用aapt工具(下面部分会介绍到appt的使用):

aapt  list -v -a myfile.apk

这个命令将会打印和apk相关的所有详细信息,找到“android:debuggable",它的值分为:

0x0: debuggable false
      0xffffffff: debugabble true

 例如,在我的测试中,这一行的信息是:

A: android debuggable(0x0101000f)=(type  0x12)0x0

 这说明我的Release Build已经关闭了debuggable!

 

 

3、aapt的使用

AAPT - Android Asset Packaging Tool

看全称,就可知道AAPT是Android资源打包工具。

在SDK的build-tools目录下。该工具可以查看,创建, 更新ZIP格式的文档附件(zip, jar, apk)。也可将资源文件编译成二进制文件,尽管你可能没有直接使用过aapt工具,但是build scripts和IDE插件会使用这个工具打包apk文件构成一个Android 应用程序。在使用aapt之前需要在环境变量里面配置SDK-tools路径,或者是路径+aapt的方式进入aapt

按照上面aapt的方式配置好环境变量后,在终端中输入 aapt v 会得到aapt版本信息,如下:

image.png

 

aapt l[ist] [-v] [-a] file.{zip,jar,apk}

 

作用:列出压缩文件(zip,jar,apk)中的目录内容。

aapt l  C:\Users\xianluo\Desktop\23.apk

image.png

可以看出来不加任何参数,aapt只是简单的罗列压缩文件中每一项的内容。

aapt l -v C:\Users\xianluo\Desktop\23.apk结果如下:

image.png

 

从图中可以看出,加上-v后,输出的内容很详细,并且以列表的形式标识出很多参数,其中表目有:

  • Length:原始文件的长度

  • Date:日期

  • Time:时间

  • Name:名称

  • Method:压缩方法,Deflate及Stored两种,即该Zip目录采用的算法是压缩模式还是存储模式;可以看出resources.arsc、*.png采用压缩模式,而其它采用压缩模式。

  • Ratio:压缩率

  • Size:这个是压缩省掉的大小,即如果压缩率是xx%。那Size是原始长度*(1-xx%)。

  • CRC-32:循环冗余校验。这个计算是有特定的算法的。   

  • offset:zipfile中偏移量的意思

 

aapt l -a C:\Users\xianluo\Desktop\23.apk结果如下:

image.png

-a表示会详细输出压缩文件中所有目录的内容,详细到什么程度的,可以看上图,上图截取的只是很小的一部分。

 

aapt d[ump] [--values] [--include-meta-data] WHAT file.{apk} [asset [asset ...]]

作用:通过参数配置可以dump apk中各种详细信息。

打印apk中所有string资源表

aapt dump strings /Users/AAPTDemo/app/build/outputs/apk/app-debug.apk

image.png


主要应用:

aapt l

简单的罗列压缩文件中每一项的内容

aapt l -v XXX.apk

列表方式详细标识出压缩文件中的每一项和很多参数

aapt l -a

详细输出压缩文件中所有目录的内容 

aapt dump strings

打印apk中所有string资源表

aapt dump badging

查看apk中的配置信息

 

更多使用方式可以参考官方使用文档。

 

4、App安全之网络传输安全问题

移动端App安全如果按CS结构来划分的话,主要涉及客户端本身数据安全,Client到Server网络传输的安全,客户端本身安全又包括代码安全和数据存储安全。所以当我们谈论App安全问题的时候一般来说在以下三类范畴当中。

 

App代码安全,包括代码混淆,加密或者app加壳。

App数据存储安全,主要指在磁盘做数据持久化的时候所做的加密。

App网络传输安全,指对数据从客户端传输到Server中间过程的加密,防止网络世界当中其他节点对数据的窃听。

 

以上两点在之前的两篇文章中都涉及,本篇主要针对App网络传输安全,在对APP网络传输安全的问题。

 

对于App传输数据加密,一般会考虑三个方面

1) 可用性:客户端和服务端都可逆向破解

2) 较高的安全性:不容易被破解

3) 效率性:加密性能及资源占用方面不是很高

 

网络安全相关的概念非常之多,要在广度和深度上都有所造诣很困难。但如果只是站在保障App通信基本安全这个维度上,做到合理使用安全算法,比大部分人所预期的都要简单很多。以下这些基础概念是必备知识:

对称加密算法,代表算法AES

非对称加密算法,代表算法RSA,ECC

电子签名,用于确认消息发送方的身份

消息摘要生成算法,MD5,SHA,用于检测消息是否被第三方修改过

建议详细学习下HTTPS,HTTPS的安全握手流程完整的阐释了“加密”和“签名”这两个概念

 

1)对称性加密。如DES、AES、3DES等。这些加密方式的算法基本已公开,因此其特点为密钥/生成密钥的方法固定,因此这种加密方式的优点为性能效率较好,而且也较大的提升了解密的成本;但由于密钥固定,因此缺点也很明显了,则是在客户端和服务端上都能找到密钥或密钥的生成方法。因此其突破口为通过逆向客户端来寻找密钥。另外,这种加密方式可同时用于请求包和返回包。

 

2)非对称性加密。如RSA、Rabin等。这些加密方式的算法基本也已经公开,因此其特点为有一对公钥和私钥:客户端上保存公钥,用于加密;服务端上保存私钥,用于解密。因此这种加密方式的优点为安全性较高,客户端上只有用于加密的公钥,而没有用于解密的私钥;而弱点则为加解密效率不高,性能资源占用较大,所以目前很多App还是选用对称性加密。由于客户端上没有解密数据包的私钥,因此需要使用其他方法获取数据包明文才能进行数据包篡改。另外,由于只有一对公钥和私钥,所以这种加密方式一般只会出现在请求包,而返回包则一般为明文返回。

 

3)自定义算法加密。有少数App开发的技术人员还会使用自定义算法来对数据包进行加密,算法五花八门,大多为各种常见的编码(如Base64)和字节位移运算等混杂。这种加密方式的优点为效率较高,但缺点为算法硬编码在客户端中,只要通过逆向即可解密出来。

 

以上三种加密方式各有优缺点,对于第一和第三种,虽说可通过逆向App获取密钥/算法来进行解密,但是开发者往往会通过其他手段来增强安全性,如App加固或把密钥/算法硬编码在so文件中等;这样就更进一步地提高了逆向与解密的难度和成本了。

 

为了保证传输数据的安全,需要使用加密算法。在决定什么样的业务场景使用什么样的加密算法之前,先要了解我们的工具箱里有哪些可用工具。加密算法的工具箱里其实就两种工具:“对称”加密算法和“非对称”加密算法。清楚这两个分类是合理设计加密算法使用场景的大前提,两个分类里我们各挑选一个代表算法来研究,“对称”加密-AES,“非对称”加密-RSA。了解AES和RSA之后我们再针对一些特定业务场景设计安全模型。DES/AES加密速度快,适合大量数据,处理数据后可复原。

 


4.1散列算法

MD5(Message Digest Algorithm 5):是RSA数据安全公司开发的一种单向散列算法。

SHA(Secure Hash Algorithm):可以对任意长度的数据运算生成一个160位的数值;

MD5严格来说不算加密算法,只能说是摘要算法,这种算法安全性不高,但速度快,比如说验证文件是否被篡改等类似场景中,就非常好用。当然,对于核心重要的模块,最好不要用MD5,它太弱了。

 SHA-1这个,很多开发android的同学应该都非常了解,在之前这个是非常安全的,但随着现代计算机发展,已经不安全了,这种算法,也将被其他的算法替代。

 

4.2对称加密之AES

AES(Advanced Encryption Standard):高级加密标准。至于其他的对称算法,例如DES、3DES这些算法已经淘汰。

AES以运算速度快,安全性高,消耗资源低完全超越于其他的对称加密算法,是对称加密算法的不二选择。

相对来说,这种算法消耗是比较小的,很多场景下都会用到。

 

4.3非对称加密之RSA

对称加密的安全性全系于加密密钥的管理,在非对称加密算法出现之前,如何动态的协商密钥一直是个难题,大部分的应用场景都是采用通信双方通过其他手段预先交流密钥的方式。一旦密钥泄漏,就会导致严重的安全事故。

 

RSA算法特点:

A.便于理解,使用广泛。

RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。

B.缺点与不足:加密和解密花费时间长、速度慢,只适合对少量数据进行加密。

为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。

 

 

关于RSA这种非对称加密算法,在App的使用当中,需要明白其主要作用有2个:

信息加密:通信双方可以在公开的网络环境下,“安全”的商量对称加密算法所使用的密钥。

电子签名:为了防止中间人攻击,通信双方在商量密钥之前可以通过签名算法确认对方的身份。

 

 非对称加密算法本身是一种加密算法,但由于RSA本身加解密的性能在现在的计算机硬件条件下存在一定瓶颈,同时对加密数据的“安全长度”也有限制,被加密数据的长度一般要求不超过公钥的长度。所以RSA更多的是被用来商量一个密钥,如果密钥是安全的,那么后续的通信都可以使用上面提到的AES来完成,AES在性能上不存在瓶颈。

 

RSA算法最经典也是最广泛的应用场景是HTTPS,HTTPS的安全握手流程完整的阐释了“加密”和“签名”这两个概念。

 

RSA有另一个竞争者ECC,ECC现在使用也越来越广泛。二者在安全性上都不存在问题。不过ECC额外的优势,公钥私钥的生成速度快于RSA,在需要大量生产密钥对的业务场景下ECC会是更好的选择。ECC的最短安全公钥也比RSA要短的多,224bits的ECC公钥就已经足够安全,而同等级别的RSA公钥需要长达2048bits。RSA由于实现简单,出现较早,可以预见在很长一段时间内都将和ECC共存。

ECC的主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA加密算法——提供相当的或更高等级的安全。ECC的另一个优势是可以定义群之间的双线性映射,基于Weil对或是Tate对;双线性映射已经在密码学中发现了大量的应用,例如基于身份的加密。不过一个缺点是加密和解密操作的实现比其他机制花费的时间长。

从运算速度、安全性、资源消耗上都比不上ECC,不过,ECC这种算法,还不够成熟。鉴于此,RSA是当前非对称算法中,应用最广泛的,而且由于能同时实现加密解密和签名,在特殊情况下,会非常好用,当然使用这种加密算法代价是不菲的,只适用于关键位置。

以后,ECC早晚会取代RSA。

 

 App网络应用场景

现在绝大部分的App都在使用http和https,少部分会有自己的tcp长连接通道,更少部分的app搭配udp通道或者类似QUIC这种reliable UDP协议来提升体验。不管是什么协议,只要涉及客户端和服务器的通信,就必然要实现类似https安全握手的流程,部分或者全部,开发者总是在性能和安全性之间取舍。有实力的大厂可以鱼与熊掌兼得,初创型企业往往会避开性能优化,直接跳过安全问题。

 image.png


 

使用http,不做任何加密相当于裸奔,初级工程师都可以轻易窥探你全部的业务数据。

使用http,但所有的流量都通过预埋在客户端的key进行AES加密,流量基本安全,不过一旦客户端代码被反编译窃取key,又会回到裸奔状态。

使用http,但AES使用的key通过客户端以GUID的方式临时生成,但为了保证key能安全的送达服务器,势必要使用服务器的公钥进行加密,所以要预埋服务器证书,又涉及到证书过期更新机制。而且无法动态协商使用的对称加密算法,安全性还是有暇疵。

 

 所以要做到真正的安全,最后还是会回归到https的流程上来,https在身份验证,密钥协商,解密算法选择,证书更新等方面都已经做了最合适的选择。

 

在App安全上的投入再多也不会过,不过安全问题上所投入的开发资源应该根据开发团队技术积累,产品发布deadline,用户规模及产品关注度等综合因素考量。结合这些因素可以给出以下建议:

 

Tip 1:尽量使用https

https可以过滤掉大部分的安全问题。https在证书申请,服务器配置,性能优化,客户端配置上都需要投入精力,所以缺乏安全意识的开发人员容易跳过https,或者拖到以后遇到问题再优化。https除了性能优化麻烦一些以外其他都比想象中的简单,如果没精力优化性能,至少在注册登录模块需要启用https,这部分业务对性能要求比较低。

 

Tip 2:不要传输密码

不知道现在还有多少app后台是明文存储密码的。无论客户端,server还是网络传输都要避免明文密码,要使用hash值。客户端不要做任何密码相关的存储,hash值也不行。存储token进行下一次的认证,而且token需要设置有效期,使用refresh token去申请新的token。

 

Tip 3:传输账号密码不要使用MD5弱加密

在之前接触的过多APP中,有些是账号密码的传输过程中采用了MD5的弱加密等方式,可以轻易被解密。

2014年中国山东大学的王小云教授公布破译了MD5、HAVAL-128、 MD4和RIPEMD算法的报告。通过加速的杂凑与冲撞方法破译了MD5算法。

image.png

image.png


Tip 4:传输账号密码不要使用Unicode弱编码

在之前接触的过多APP中,有些是账号密码的传输过程中采用了Unicode弱编码等方式,可以轻易被解密。

image.png

 

Tip 5:Post并不比Get安全

事实上,Post和Get一样不安全,都是明文。参数放在QueryString或者Body没任何安全上的差别。在Http的环境下,使用Post或者Get都需要做加密和签名处理。

 

Tip 6:不要使用301跳转

301跳转很容易被Http劫持攻击。移动端http使用301比桌面端更危险,用户看不到浏览器地址,无法察觉到被重定向到了其他地址。如果一定要使用,确保跳转发生在https的环境下,而且https做了证书绑定校验。

 

Tip 7:http请求都带上MAC

所有客户端发出的请求,无论是查询还是写操作,都带上MAC(Message Authentication Code)。MAC不但能保证请求没有被篡改(Integrity),还能保证请求确实来自你的合法客户端(Signing)。当然前提是你客户端的key没有被泄漏,如何保证客户端key的安全是另一个话题。MAC值的计算可以简单的处理为hash(request params+key)。带上MAC之后,服务器就可以过滤掉绝大部分的非法请求。MAC虽然带有签名的功能,和RSA证书的电子签名方式却不一样,原因是MAC签名和签名验证使用的是同一个key,而RSA是使用私钥签名,公钥验证,MAC的签名并不具备法律效应。

 

Tip 8:http请求使用临时密钥

高延迟的网络环境下,不经优化https的体验确实会明显不如http。在不具备https条件或对网络性能要求较高且缺乏https优化经验的场景下,http的流量也应该使用AES进行加密。AES的密钥可以由客户端来临时生成,不过这个临时的AES key需要使用服务器的公钥进行加密,确保只有自己的服务器才能解开这个请求的信息,当然服务器的response也需要使用同样的AES key进行加密。由于http的应用场景都是由客户端发起,服务器响应,所以这种由客户端单方生成密钥的方式可以一定程度上便捷的保证通信安全。

 

Tip 9:AES使用CBC模式

不要使用ECB模式,设置初始化向量,每个block加密之前要和上个block的秘文进行运算。

AES:高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。实际中,一般是通过RSA加密AES的密钥,传输到接收方,接收方解密得到AES密钥,然后发送方和接收方用AES密钥来通信。

ECB模式与CBC模式对比

ECB模式:

image.png

image.png


1.不能隐藏明文的模式;

2.可能对明文进行主动攻击;

**AES/DES弱加密漏洞

在AES加密时,使用“AES/ECB/NoPadding”或“AES/ECB/PKCS5padding”的模式。ECB是将文件分块后对文件块做同一加密,破解加密只需要针对一个文件块进行解密,降低了破解难度和文件安全性。

 

 

CBC模式:

image.png

不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。

 

Tip 10: Certificate Pinning

RSA的签名机制虽然看着安全,一旦出现上游证书颁发机构私钥泄漏,或者签名流程发现漏洞等情况,中间人攻击还是会导致数据被第三方破解甚至被钓鱼。Certificate Pinning是一种与服务器证书强绑定的机制,要么绑定证书本身,需要证书更新机制配合加强安全性,要么使用私钥绑定,这样更新证书的时候只要保证私钥不变即可。现在流行的HTTP framework,iOS端如AFNetworking,Android端如OKHttp都支持Certificate Pinning。

证书锁定Certificate Pinning是SSL/TLS加密的额外保证手段。它会将服务器的证书公钥预先保存在客户端。在建立安全连接的过程中,客户端会将预置的公钥和接受的证书做比较。如果一致,就建立连接,否则就拒绝连接。

Certificate Pinning在手机软件中应用较多。因为这些应用连接的服务器相对固定,可以预先将服务器的X509证书或者公钥保存在App中。例如,苹果应用商店Apple App Store就预置了这个功能。当使用中间人工具或者Fiddler之类的工具拦截数据,就会造成应用商店无法联网的情况。

在渗透测试中,遇到这类技术,有三种解决办法。第一种是从系统层面禁用证书锁定验证功能。第二种是反编译软件,将其保存的公钥替换为攻击机的证书。第三种,如果该目标不是分析的对象,可以设置代理时忽略其要连接的服务器,不进行拦截和修改。

 

Tip 11: Perfect Forward Secrecy

很多人会觉得非对称加密算法足够安全,只要使用了RSA或者AES,加密过后的数据就认为安全。但没有绝对的安全,无论是RSA或者AES算法本身都有可能在未来某一天被破解,正如当年的DES,甚至有传言NSA正如当年掌握了differential cryptanalysis一样,现在已经获取了某种方法来破解当前互联网当中的部分网络流量,至于到底是RSA还是AES就不得而知了。

未来计算机的计算能力是个未知数,或许某一天brute force能够暴力破解的密钥长度会远超128bits(现阶段上限应该在80bits)。

即使算法本身没有被破解,密钥也有可能被泄漏,技术上的原因或者政策上的因素都可能导致RSA或者ECC的私钥被泄漏。所以尽可能针对不同的session使用不同的key能够使的我们的数据更佳安全。

Forward Secrecy就是为了避免某个私钥的泄漏或者被破解而导致历史数据一起泄漏。现在google的https配置所使用的是TLS_ECDHE_RSA算法,每次对称密钥的协商都是使用ECC生成临时的公钥私钥对(之前提到过ECC在快速生成密钥对上有优势),身份验证使用RSA算法进行签名。

 

每天跟踪信息安全动态

安全的攻防战不会有穷尽的一天,算法的更替会伴随着人类对知识的无尽渴望延绵至不可预知的未来。AES说不定哪天被破解了,openSSL可能又出现新的漏洞了,google又提倡新的安全模型了,NSA的量子计算机说不准已经在悄悄解密google的流量了,每天跟踪八卦最新业界动态才是码农避免因bug而背黑锅的不二法宝。

 

4.4加密算法漏洞

以下几种行为会有产生加密算法漏洞的危险:

  • 使用AES/DES/DESede加密算法时,如果使用ECB模式,容易受到攻击风险,造成信息泄露。

  • 代码中生成秘钥时使用明文硬编码,易被轻易破解。

  • 使用不安全的Hash算法(MD5/SHA-1)加密信息,易被破解。

生成的随机数具有确定性,存在被破解的风险。

 

相关案例:

    某互联网金融APP加密算法被破解导致敏感信息泄露

某P2P应用客户端,用来加密数据的DES算法的密钥硬编码在Java代码中,而DES算法是对称密码算法,既加密密钥和解密密钥相同。知道了密文和加密算法以及密钥,通过解密操作,可以从文件中恢复出原始的手势密码。

 

    某租车APP加密算法被破解导致一系列风险

某租车APP与服务器通信的接口采用http传输数据,并且有对传输的部分参数进行了加密,加密算法采用AES,但是密钥硬编码在java代码中为“shenzhoucar123123”,可被逆向分析出来,导致伪造请求,结合服务器端的漏洞,引起越权访问的风险,如越权查看其它用户的订单等。 攻击者完全可以做到使用其他脚本重新实现相同的加密功能并拼接出各个接口请求,批量的刷取订单信息和用户其他信息。

 

5、从任务栈到启动模式

在对组件调用的测试中,我们除了分析组件的调用权限外,也可以从从任务栈看启动模式。

任务栈是一种后进先出的结构。位于栈顶的Activity处于焦点状态,当按下back按钮的时候,栈内的Activity会一个一个的出栈,并且调用其onDestory()方法。如果栈内没有Activity,那么系统就会回收这个栈,每个APP默认只有一个栈,以APP的包名来命名.

 

1)standard : 标准模式,每次启动Activity都会创建一个新的Activity实例,并且将其压入任务栈栈顶,而不管这个Activity是否已经存在。Activity的启动三回调(onCreate()->onStart()->onResume())都会执行。

2)singleTop : 栈顶复用模式.这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,所以它的启动三回调就不会执行,同时Activity的onNewIntent()方法会被回调.如果Activity已经存在但是不在栈顶,那么作用于standard模式一样.

3)singleTask: 栈内复用模式.创建这样的Activity的时候,系统会先确认它所需任务栈已经创建,否则先创建任务栈.然后放入Activity,如果栈中已经有一个Activity实例,那么这个Activity就会被调到栈顶,onNewIntent(),并且singleTask会清理在当前Activity上面的所有Activity.(clear top)

4)singleInstance : 加强版的singleTask模式,这种模式的Activity只能单独位于一个任务栈内,由于栈内复用的特性,后续请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁了!

对于任务栈安全性的了解,我们可以参照着这篇文章:Android最近任务列表的安全问题https://m.aliyun.com/jiaocheng/52763.html

 

5.1 如何看任务栈

Android对于Activity有严格的生命周期控制,以限制开发者在适当的回调函数里的放上合适的代码。对于多个Activity的转换,Android也有非常好的管理和流畅的切换,对此Android还引入了任务栈(Task Stack)的概念,这个概念对于Android设备上得返回按键有极其重要的联系。

在AndroidManifest中申明所要用到的Activity时可以设置不同的launchMode来得到不同的Activity“启动”效果。在使用startActivity开启新的Activity时,传入的Intent也可以设置不同的Flag来达到不同的效果。另一方面,在Activity启动时它可能又开启了另一个Activity,或者调用了finish()函数终结了Activity。

这使得Activity栈变得无法掌握,有时候按下返回按钮或者点击关闭当前Activity的操作,都不知道Android系统会把程序带到那个Activity,不确定这是否是最后一个Activity以致退出了整个程序。亦或者一些按钮和操作循环产生Activity而造成内存膨胀。对于这些问题,如果能够在调试期间知道当前任务栈的情况,就能很方便的观察和发现问题存在的原因,进而选择正确的launchMode,设置恰当Intent的Flag来使程序达到预期的效果

下面操作如何看一个APK的任务栈:

首先用adb命令进入手机shell模式下,运行:dumpsys activity|grep "hx"

image.png

 

5.2 dumpsys命令的使用

上面在看任务栈就涉及到了dumpsys命令的使用:

adb shell dumpsys activity

db shell dumpsys activity activities

CTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
  Stack #0:
    Task id #28
    * TaskRecord{43525058 #28 A=com.android.systemui U=0 sz=1}
      ... ... ... ...
      * Hist #0: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28}
          ... ... ... ...
    Task id #1
    * TaskRecord{429a35f8 #1 A=com.android.launcher U=0 sz=1}
      ... ... ... ...
      * Hist #0: ActivityRecord{429a1760 u0 com.android.launcher/com.android.launcher2.Launcher t1}
          ... ... ... ...
    Running activities (most recent first):
      TaskRecord{43525058 #28 A=com.android.systemui U=0 sz=1}
        Run #1: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28}
      TaskRecord{429a35f8 #1 A=com.android.launcher U=0 sz=1}
        Run #0: ActivityRecord{429a1760 u0 com.android.launcher/com.android.launcher2.Launcher t1}
    mLastPausedActivity: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28}
... ... ... ...

整个log显示了当前所有在运行的任务栈,它们的id分别是什么。对于每个Task,也有Activity数量等信息,同时也列出了其中的Activity列表,并且对于每个Activity也有比较详细的描述,比如启动它的Intent的内容。 

如果觉得内容过多,只想看看栈的内容,也可以直接跳到”Running activities (most recent first)”那部分,比较简洁而又明了的列出了栈中得Activity列表,就能知道当按下返回键的时候会应该会回到哪个Activity以后是要退出程序。

 

6、Android应用程序签名 debug签名

前面文章中我有提到apk通用签名,以下关于Android应用程序签名-debug签名,是对通用签名判断的一个补充。

6.1 debug签名的认识

android系统要求所有的程序经过数字签名才能安装,如果没有可用的数字签名,系统将不许安装运行此程序,不管是模拟器还是真实手机。因此,在设备或者是模拟器上运行调试程序之前,必须为应用程序设置数字签名。Android系统仅仅会在安装的时候测试签名证书的有效期,如果应用程序的签名是在安装之后才到期,那么应用程序仍然可以正常启用。         

Android通过数字签名来 标识应用程序的作者和在应用程序之间建立信任关系,不是用来决定用户可不可以安装该应用程序。android的这个签名由应用程序的作者完成,并不需要权 威的数字证书签名机构认证,他只是用来让应用程序包自我认证的。Android系统默认自动给应用程序签名,ADT会自动使用debug密钥为应用程序签 名,debug密钥是一个名为debug.keystore的文件,位置位于电脑的:

/Documents and Settings/xianluo/.Android/debug.keystore,其中的xianluo是电脑的用户名。

image.png


可能有人可能会认为反正debug签名的应用程序也能安装使用,那也没有必要自己签名了嘛。千万不要这样想,debug签名的应用程序有这样两个限制,或者说风险:

1)debug签名的应用程序不能在Android Market上架销售,它会强制你使用自己的签名;

Debug模式下签名用的证书(默认是Eclipse/ADT和Ant编译)自从它创建之日起,1年后就会失效。

2)debug.keystore在不同的机器上所生成的可能都不一样,就意味着如果你换了机器进行apk版本升级,那么将会出现上面那种 程序不能覆盖安装的问题。不要小视这个问题,如果你开发的程序只有你自己使用,当然无所谓,卸载再安装就可以了。但要是你的软件有很多使用客户,这就是大问题了,就相当于软件不具备升级功能!

安装apk时,通过CERT.RSA查找公钥和算法,并对CERT.SF进行解密和签名验证,确认MANIFEST.MF,最终对每个文件签名校验。

升级时,android也会进行签名验证。如果遇到以下情况,都不能完成升级:

1)两个应用,名字相同,签名不同

2)升级时前一版本签名,后一版本没签名。

3)升级时前一版本为DEBUG签名,后一个为自定义签名。

4)升级时前一版本为Android源码中的签名,后一个为DEBUG签名或自定义签名。

5)装未签名的程序。

6)安装升级已过有效期的程序。

 

6.2 android 如何判断Apk是否签名和签名是否一致

用命令:jarsigner -verify -verbose -certs <apk文件>

如果有Android Debug字样就是debug

如果已经签名: [证书的有效期为13-8-31 下午2:31至41-1-16 下午2:31]

 

获取签名的fingerprints

keytool -printcert -file META-INF/CERT.RSA

证书指纹:

MD5: 5A:5A:96:63:8E:EF:FC:66:9E:BC:1C:2A:A9:1E:E5:95

SHA1: 44:BD:33:2D:C5:21:AE:78:D5:04:92:1A:39:FD:AC:01:E2:32:3C:AB

SHA256: 2F:C0:A3:8C:0D:42:84:70:48:78:44:A4:2E:64:5B:50:B3:B3:1E:33:94:62:A3:9F:2F:10:DD:EF:D7:CF:02:0B

签名算法名称: SHA1withRSA

版本: 3

两个apk是否同签名,比较签名的MD5码或SHA1码 ,一样就是相同的,反之,不是。


本文作者:Lemon

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

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

Lemon

文章数:68 积分: 647

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号