剖析Android开放网络端口的安全风险隐患

        Android应用通常使用PF_UNIX、PF_INET、PF_NETLINK等不同domain的socket来进行本地IPC或者远程网络通信,这些暴露的socket代表了潜在的本地或远程攻击面,历史上也出现过不少利用socket进行拒绝服务、root提权或者远程命令执行的案例。特别是PF_INET类型的网络socket,可以通过网络与Android应用通信,其原本用于linux环境下开放网络服务,由于缺乏对网络调用者身份或者本地调用者pid、permission等细粒度的安全检查机制,在实现不当的情况下,可以突破Android的沙箱限制,以被攻击应用的权限执行命令,通常出现比较严重的漏洞。

        作为Android安全研究的新手,笔者带着传统服务器渗透寻找开放socket端口的思路,竟然也刷了不少漏洞,下面就对这种漏洞的发现、案例及影响进行归纳。感谢爱加密网站:提供博客思路,Android应用的安全风险依然严峻。游戏外挂、第三方支付漏洞挖掘、充值卡支付漏洞挖掘、内存修改、存档修改、脚本录制、游戏资源文件窃取与篡改、加速器、模拟器运行,这些对游戏商来说都是致命打击。http://www.ijiami.cn/appprotect_mobile_games

剖析Android开放网络端口的安全风险隐患_第1张图片

0x01 Android开放端口应用定位

简单地利用命令netstat就可以发现Android开放了许多socket端口,如图。但这些开放端口本后的应用却不得而知。

剖析Android开放网络端口的安全风险隐患_第2张图片

此时可以通过三步定位法进行寻找,支持非root手机。

第一步,利用netstat寻找感兴趣的开放socket端口,如图中的15555。

第二步,将端口转换为十六进制值,查看位于/proc/net/目录下对应的socket套接字状态文件,在其中找到使用该socket的应用的uid。如15555的十六进制表示为1cc3,协议类型为tcp6,那么查看/proc/net/tcp6文件。

enter image description here

注意上面的10115,就是使用该socket的应用的uid。通过这个uid可以得知应用的用户名为u0_a115。

第三步,根据用户名就可以找到应用了

剖析Android开放网络端口的安全风险隐患_第3张图片

至此,我们就知道开放15555端口的应用为com.qiyi.video,尽管我们还不能分辨出开放该端口的准确进程,但仍然为进一步的漏洞挖掘打下基础。

写一个简单的脚本来自动化的完成此项工作.

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
importsubprocess,re
 
deftoHexPort(port):
    hexport=str(hex(int(port)))
    returnhexport.strip('0x').upper()
 
deffinduid(protocol, entry):
    if(protocol=='tcp'orprotocol=='tcp6'):
        uid=entry.split()[-10]
    else:# udp or udp6
        uid=entry.split()[-6]
    uid=int(uid)
    if(uid >10000):# just for non-system app
        return'u0_a'+str(uid-10000)
    else:
        return-1
 
defmain():
    netstat_cmd="adb shell netstat | grep -Ei 'listen|udp*'"
    #netstat_cmd = "adb shell netstat "
    grep_cmd="adb shell grep"
    proc_net="/proc/net/"
 
# step 1, find interesting port
    orig_output=subprocess.check_output(netstat_cmd, shell=True)
    list_line=orig_output.split('\r\n')
 
    apps=[]
    strip_listline=[]
    pattern=re.compile("^Proto")# omit the first line
 
    forlineinlist_line:
        if(line !='')and(pattern.match(line)==None):
 
# step 2, find uid in /proc/net/[protocol] based on port
            socket_entry=line.split()
            protocol=socket_entry[0] 
            port=socket_entry[3].split(':')[-1]
            grep_appid=grep_cmd+' '+toHexPort(port)+' '+proc_net+protocol
            net_entry=subprocess.check_output(grep_appid, shell=True)
            uid=finduid(protocol, net_entry)
# step 3, find app username based on uid
            if(uid==-1):continue
            applist=subprocess.check_output('adb shell ps | grep '+uid, shell=True).split()
            app=applist[8]
            apps.append(app)
            strip_listline.append(line)
 
    itapp=iter(apps)
    itline=iter(strip_listline)
# last, add app in orig_output of sockets
    print("Package                  Proto Recv-Q Send-Q         Local Address          Foreign Address        State\r\n")
    try:
        whileTrue:
            printitapp.next()+' '+itline.next()
    exceptStopIteration:
        pass
 
if__name__=='__main__':
    main()

运行结果如下

剖析Android开放网络端口的安全风险隐患_第4张图片

除了PF_INET套接字外,PF_UNIX、PF_NETLINK套接字的状态文件分别位于/proc/net/unix和/proc/net/netlink。

当然,如果手机已root,可直接使用busybox安装目录下带p参数的netstat命令,可以显示pid和不完整的program name。

剖析Android开放网络端口的安全风险隐患_第5张图片

 

你可能感兴趣的:(剖析Android开放网络端口的安全风险隐患)