刘龙锦 张志杰 梁世民
【摘要】 截止至2020年6月,Android系统占据了手机系统74.6%市场份额,剩余26.4%市场份额由其他系统瓜分,绝对优势的市场占有率造就了繁荣的Android生态及数量庞大的开发者。开发者水平的高低则给Android开发带来了许多安全性问题。本文将从Android应用抓包防护,Java代码防护,So代码防护,签名加密算法,服务端校验方面进行研究,为应用的风险控制方案设计提供理论依据。
【关键词】 Android 抓包 反编译 服务端
引言:
保护用户数据,保护信息安全是每一个开发者,每一家互联网公司都应该重点布防的区域。一套完整高效的风险控制方案,是开发者或公司开发实力的体现,也是高效保护用户数据,信息安全,人人公平的重要手段。目前国内外在应用安全方面都比较着重,市场上也有阿里云、360、数美、数盟等安全服务厂商为Android应用提供安全加密服务。仅仅只靠第三方厂商提供的安全防护是远远不足的,我们需要控制用户操作的完整链路,才能设计出一套优秀的风险控制系统。
一、防护方式
多数Android应用的操作逻辑为:客户端进行操作,系统发送请求到服务器,服务端校验请求合法及参数并返回数据,客户端根据服务端返回数据进行相应界面展示。在这套操作逻辑中,客户端的操作及数据发送部分存在风险。攻击者通过反编译Apk包,逆向出Android应用与服务端的通信协议,伪造非法请求攻击。针对上述的攻击方式,开发者会在Android应用的通信协議层进行防护,提高攻击者抓包的难度,在请求中嵌入加密算法。收集设备信息,如设备型号,网卡地址,系统版本,IP地址等,综合判断本次请求是否合法。
二、抓包防护
抓包是研究应用程序的开始,通过抓包获取数据进行分析,确认目标请求的地址、参数、加密字段等。主流的Android应用与服务端之间使用HTTPS/TLSv1.2协议通信,某些Android应用使用QUIC/Http3并强制使用TLSv1.3协议。随着Android系统的版本更新,系统层面强制要求开发者使用HTTPS协议进行通信,开发者也重视数据传输过程中的安全,攻击者对应用的抓包越发困难。
抓包通常采用中间人方式,常用抓包软件有Fiddler、Charles等。中间人方式抓包需要解决两个问题:如何伪装Server、如何伪装Client。以Fiddler软件为例子,伪装Server时需要安装根证书到系统根目录,伪装Client则客户端需要安装Fiddler的自签证书。Android系统将CA证书分为用户CA与系统CA证书,系统CA证书拥有的权限较高但需要设备拥有root权限才可进行添加和删除操作。
在拥有root权限的设备上,抓包非常容易实现。电脑端步骤:安装Fiddler,安装Fiddler根证书到系统,配置解密通道。手机端步骤:设置代理到电脑,安装Fiddler自签证书,安装Xposed框架,安装JustTrustMe插件,配置完成,即可抓取大多数应用数据包。对于抓包的防护,防护办法有以下几种:应用targetSdkVersion设置为大于24、双向SSL认证、使用SSL重协商、使用其他通信协议。无论使用那种方式都不可能避免不被抓包,对于Android系统的限制可降低Android版本,证书固定方式可以Hook移除相关代码,双向SSL认证可逆向拿到私钥进行破解抓包。开发者尽可能的提高抓包难度,增大攻击者抓包的成本即可。
三、Java代码防护
Android应用与服务端通信时,在请求中嵌入Token或者加密的字段是常见的方式。高级的风险控制系统还会收集用户的操作行为日记上传到服务器,通过分析用户的操作行为日记来判定本次请求是否有效。在请求中嵌入加密字段需要开发者在Java代码层进行代码编写,由于Android开源的特性,经过开发工具编译生成的Apk安装包如若未经过任何技术处理,使用Jadx工具进行反编译即可查看得到与源程序匹配度高达95%的代码。对于攻击者而言,能查看到程序的源码能够极大的加快破解的速度,为了延缓攻击者得到Android应用在Java层的算法,通常采用以下手段进行防护:
(一)代码混淆
使用Proguard-rules工具进行代码混淆,加大攻击者阅读难度,延缓破解算法的速度。代码混淆方法仅仅只能延缓算法被破解的速度,可以把一些水平较低的破解者拦在门外,对于编程功底较为深厚攻击者,此方法终究会被破解。
(二)Apk签名校验
进行APK打包操作时,开发人员要进行签名操作。签名文件是开发者独有的,攻击者通常不可能有相同的文件,可以使用Android SDK中PackageManager类的getPackageInfo签名校验方法保护Apk。
(三)重打包对抗
对Apk进行重打包,修改代码实现抓包也是常用的攻击方式。重打包常用的工具是ApkTool,ApkTool对Png文件会按照Png格式处理,将一个非Png格式的文件修改为Png格式,ApkTool打包时会出错,可以在Apk的资源文件放入一些非法文件干扰ApkTool工具。
(四)调试器检测
防止Apk被动态调试,可以检测是否有调试器链接,使用Application类的isDebuggerConnected方法检测,有调试器链接则采取防护措施。
(五)Dex文件校验
重编译Apk安装包会重新编译Dex文件,生成的Dex文件的Hash值就会发生改变,记录软件初始发布时Dex文件哈希值与客户端运行时Hash值进行对比判断应用是否被修改过。
(六)加壳保护
第三方厂商提供的加壳程序对Apk进行加壳也是一种有效的方式。但Apk加壳是在Java层代码实现的,被反编译的风险仍然很大。
四、So代码防护
由于Android系统开源的特性,在Java层进行的防护都会被破解。Google为开发者提供了So文件的支持。So文件是Unix操作系统的动态链接库,相当于Windows下的Dll文件,它由Native C/C++代码编译而来,在Android系统中充当JNI与Java交互的角色,能被Android Runtime加载并能被Java层调用。对比Java语言,C/C++在效率方面,混淆后的閱读方面及加壳破解难度方面都有较大的提升。加密算法以及网络通信协议在写在so层是目前主流的做法,但So层的代码也不是不能被破解的,只是破解的难度相较Java层的代码会有一个较大的提升。反编译So文件的主流软件是Ida Pro,使用Ida软件反编译可以得到So文件的内容。为了加大攻击者阅读So文件的难度,需要对So文件进行加固以及混淆。So文件是可以被单独调试的,所以需要对So文件进行反调试的保护,对So层的保护主要有以下几种方式:
(一)代码混淆
基于LLVM的混淆,通过指令替换、控制流扁平化和虚假控制等方法混淆。增加了虚假控制流、指令替换和控制流平坦化的处理。基于LLVM的混淆比较灵活,根据不同的安全需求策略,混淆程度越高,则性能影响越大,文件膨胀越多。
(二)调试检测
Ida软件具有动态调试So文件的功能,可以方便的还原出So层的算法。在So文件的JNI_Onload方法中加入调试检测的代码防止So文件被Ida软件动态调试,可以在一定程度上防止算法被还原。
(三)防止调用
So文件可以作为一个库单独运行,确定了关键函数的地址后,直接调用即可得到返回值,为了防止被直接调用,应该在So文件中置入代码,通过检测上下文环境参数确认函数是被自身调用,防止直接调用攻击。
(五)加壳保护
使用加壳程序对So文件进行加壳,由于So层的加壳程序使用C/C++编写,执行的效率相对比Java层更高,代码复杂度也比Java语言复杂一些,对应的脱壳难度也更高,可以更有效的提升应用安全。
五、签名加密算法
除了常规Token认证之外,在每一个请求中都会对请求的参数进行签名加密。加密得到的字符串嵌入在请求中参数中,服务端接收到数据后根据双方约定好的算法对参数计算得到加密字符串,再与客户端传输的字符串进行对比,如果双方计算结果相同则暂时认为请求是合法的。
加密算法写在Java层代码非常容易遭到破解,大部分应用都会将加密算法写在So层。常用的加密算法有MD5,AES,HMAC_MD5,RSA等,通常会使用多种加密算法结合计算以提升加密强度。加密算法无论是写在Java层还是So层,都是可以被逆向出来的,写在So层只是能延缓攻击者破解的速度,对So文件进行脱壳修复,去LLVM混淆化,将So层的代码逻辑进行修复后可以得到对应的加密算法。
六、服务端检验
客户端发出的请求最终都由服务端校验处理,Android应用无法做到完全隐藏程序代码,对于客户端的请求,服务端应该从多个方面进行校验,校验通过之后才能判定本次请求有效。服务端主要从以下方面进行判断:
(一)签名加密算法
服务端与客户端通过双方约定好的算法分别对数据进行加密后得到的字符串进行对比,对比不通过则代表本次请求为恶意请求,直接返回错误。
(二)IP地址来源
对从云服务器厂商发出的请求、同一个IP在某个时间段内频繁发出的请求、频繁更换IP地址进行访问的请求进行一定的限制。如果是需要登录的应用,可以在登录时记录对应的IP地址,后续发出的请求如果超过登录IP的范围,在环境校验失败之后应该做一定的请求限制。
(三)设备环境信息
判断设备的型号、品牌、系统版本等信息生成对应权重的设备ID。对系统版本较低,设备已经Root,安装有Xposed框架的设备适当降低权重或者将其直接风控。
(四)用户操作行为
上传某个时间段内用户的操作信息,综合判断该操作是否有效。
七、结束语
Android应用的风险控制系统的设计需要进行多方面综合考虑,它对开发者的专业技术提出了更高的要求,需要在与攻击者的对抗中不断进行完善,不断进行优化。
作者单位:刘龙锦 张志杰 梁世民 北海职业学院
参 考 文 献
[1]韩子诺,刘嘉勇.基于Android平台的SO加固技术研究[j].现代计算机(专业版), 2015(24):49-53
[2]李志明,刘寿春,等基于JNI机制与云平台的细粒度Android应用加固方法[j].小型微型计算机系统, 2021(42):640-646
[3]徐尤华,熊传玉.Android应用的反编译[j].电脑与信息技术, 2012(20):50-51