0x01 初衷以及适用场景
android的usb调试模式本是为开发者而设计的,开发者在应用开发的过程中可用其对应用进行调试或测试。
adb提供一系列有助于开发的功能,例如应用安装与卸载,备份与恢复,日志的输出与过滤,并且,它还提供一个权限相当可观的、很人性化的adb shell。
除开发者外,逆向分析人员在对应用进行逆向分析以及动态调试的时候,也会使用到adb接口,例如通过该接口对so或者smali进行动态调试与跟踪,动态对一些功能性的代码进行验证等等。
然而便利性与安全性在一定程度上是成反比的,在其丰富的功能之下,也存在着一系列安全问题。
0x02 adb的信息泄露与权限泄露问题
如果应用在发布时,没有把logcat所输出的调试信息删除掉,那么很有可能造成敏感信息的泄露,轻微的情况,例如logcat可能打印出应用所访问的网页链接或者一些其它的中间变量,重则可能把账号密码也给泄露出来,毕竟安卓开发门槛低,开发者水平难免参差不齐。
为了方便调试,开发者甚至可能会这么写:
安卓logcat信息泄露的情况在曾经的乌云上披露过很多起,例如:
WooYun: 途牛网app logcat信息泄露用户的同团聊的聊天内容
WooYun: 冲浪浏览器logcat出用户短信
WooYun: 杭州银行Android客户端登录账号密码信息本地泄露
此外,当前市面上很多安卓应用漏洞扫描平台也会着重把logcat的滥用扫描出来呈现于报告中,例如腾讯金刚审计系统、阿里聚安全、360显危镜(前捉虫猎手)等。这也从侧面体现了这个问题的普遍性。
除了开发者的失误之外,adb本身的设计方面也有一些瑕疵,曾经有一篇论文专门对该问题进行过研究:《Bittersweet ADB : Attacks and Defenses》。
通过ADB或者一个申请了ADB权限的Android应用程序,可以在不申请权限的情况下监控短信、电话记录等隐私信息,监控/模拟屏幕点击事件,访问其它应用程序的私有目录,对Android设备进行DoS攻击等。
而上述行为大部分可以通过adb shell dumpsys命令得到,更具体内容可查看参考链接[2]。
0x03 安卓备份问题
这是一个相当古老的问题了,在低版本的安卓系统中,在对某个应用进行备份操作时,会将其私有数据一并给备份出来,然后即可通过特定的工具把它们提取出来,如下图:
那么应用的私有数据中一般有些什么?首先便会有个人的身份凭证,或者是账号密码或者是别的凭证,一般应用对私有数据是比较有信心的,毕竟它被称为“私有数据”,因而挺多应用都直接明文存着,有些虽然有加密处理,但是通过对应用的逆向分析,即可将数据进行解密,例如从某客户端中backup出的内容中含有如下文件:
通过对apk进行逆向可发现其解密过程,照着解密类与方法抄一遍即可解密:
又如微信的数据库,有文章曾分析过微信数据库的加密过程,并给出了其加密密钥的生成方式,如果微信本地数据库,uin,imei同时被拿到,便可根据后两者算出数据库的加密密钥,并对加密后的数据库进行解密,这时你的所有聊天记录都直接晒在太阳下了。
除了直接手动解密数据以外,还可以将这些数据通过adb restore原封不动地恢复到另一个手机上,从而进行身份伪造,例如droidsec上的文章《两分钟窃取身边女神微博帐号》(参考链接[4])
有人注意到在使用adb backup时需要手动点击确认才可进行备份,如果攻击者没有机会点击屏幕,就没有问题了,不过安卓有个机制叫做输入输出子系统,在adb shell 下可以执行sendevent命令,可以模拟各种用户输入,具体每种机型不一样,在我的机器上发送如下event便可模拟点击允许操作:
#EV_KEY BTN_TOUCH DOWN sendevent /dev/input/event7 1 330 1 #EV_ABS ABS_MT_POSITION_X 366 sendevent /dev/input/event7 3 53 366 #EV_ABS ABS_MT_POSITION_Y 690 sendevent /dev/input/event7 3 54 690 #EV_SYN SYN_REPORT 00000000 sendevent /dev/input/event7 0 0 0 #EV_KEY BTN_TOUCH UP sendevent /dev/input/event7 1 330 0 #EV_SYN SYN_REPORT 00000000 sendevent /dev/input/event7 0 0 0
0x04 通过adb种马
既然通过adb可以安装应用,而且还是静默的,那么自然也可以在用户没有感知的情况下给你种个马。
不过一般的马可能并没有图标与界面等等增加被发现几率的东西,而没有被launch过的应用是不能运行的,也就是说它们所注册的BroadcastReceiver都是收不到东西的, 它需要一个唤醒的过程。
所幸adb shell也可以实现这个唤醒过程,通过adb shell am命令可以启动特定应用包的特定组件,如此小马就可以成功跑起来了。
当然,如果攻击者有更强劲的方式,例如直接adb push一个exploit上去,提权到root,就更加简单粗暴了。
0x05 恶意代码注入
这种手段就相对优雅一些了,在连接usb调试的情况下,可以通过一系列命令,向手机上已安装的应用中注入一段自定义的恶意代码,这段代码可以是简单地弹一声问候,也可以是非常复杂的远控。
为了进一步增加可信度,可以选本来就申请了很高权限的应用进行注入,例如对一款通讯录管理软件进行注入后,它请求读取你的联系人列表,看起来没毛病。
尽管学术界与工业界有很多防止重打包的措施,但是在实际测试中,这种攻击手段的成功率着实不低,并且,就算对某个应用注入失败了,最粗暴的方法还可以pm list packages -3把所有的包都列出来都搞一遍试试。
以下我自己写了一个简单的程序,对开启USB调试的手机上某应用注入一段metasploit meterpreter http reverse shell的payload,整个过程中不需要对手机进行任何操作,大体工作流程如下:
当再次点击注入后的应用之后,在监听服务器上开启的handler上即可接收到一个meterpreter的shell :
以上,便可在服务端对安卓应用进行远程控制了,拿到Android meterpreter shell之后,可以做的事情很多,包括隐私窃取、发送短信,打开网页,截图、照相。
甚至,可以调用你的前置后置摄像头进行实时监控。
所支持的部分指令如下:
0x06 最后
在4.4以后的安卓版本,若要连接android设备上的adbd,需要对host机器进行指纹的验证,这在很大程度上又降低了通过这些方式被攻击的可能性。不过如今PC上的安卓管理软件都是大力提倡你打开usb调试,甚至会一步一步教你怎么打开,因此还是会有相当大一部分人暴露在此风险之下。
如上可见,通过adb可以做的事情还是很多的,以上只是列举了一部分,并且是当前常用的一些小手段,想要完全防止被上述手段攻击,最简单而有效的办法便是关闭USB调试,并且尽量在正规的应用市场下载可信的应用。
毕竟,设想如果你正在火车站或者某公共场所,使用不知谁放在那儿的公共充电插口,其背后是一台恶意的计算机,而你刚好打开了,或者在它的诱导下,打开了USB调试...