- 对本书的赞誉
- 前言
- 基础篇
- 第 1 章 Android 中锁屏密码加密算法分析
- 第 2 章 Android 中 NDK 开发
- 第 3 章 Android 中开发与逆向常用命令总结
- 第 4 章 so 文件格式解析
- 第 5 章 AndroidManifest.xml 文件格式解析
- 第 6 章 resource.arsc 文件格式解析
- 第 7 章 dex 文件格式解析
- 防护篇
- 第 8 章 Android 应用安全防护的基本策略
- 第 9 章 Android 中常用权限分析
- 第 10 章 Android 中的 run-as 命令
- 第 11 章 Android 中的 allowBackup 属性
- 第 12 章 Android 中的签名机制
- 第 13 章 Android 应用加固原理
- 第 14 章 Android 中的 so 加固原理
- 工具篇
- 第 15 章 Android 逆向分析基础
- 第 16 章 反编译神器 apktool 和 Jadx
- 第 17 章 Hook 神器 Xposed
- 第 18 章 脱壳神器 ZjDroid
- 第 19 章 Native 层 Hook 神器 Cydia Substrate
- 操作篇
- 第 20 章 静态方式逆向应用
- 第 21 章 动态调试 smali 源码
- 第 22 章 IDA 工具调试 so 源码
- 第 23 章 逆向加固应用
- 第 24 章 逆向应用经典案例分析
- 第 25 章 Android 中常见漏洞分析
- 第 26 章 文件加密病毒 Wannacry 样本分析
10.3 Android 中 setuid 和 setgid 的使用场景
前面介绍了 Linux 中 setuid、setgid 的用法和作用,以及如何使用 chmod 命令来操作。下面就来看看 Android 中有哪些场景用到了 setuid、setgid。
1.zygote 降权处理
首先不得不说 zygote 这个进程,Android 中应用启动的过程都是和这个进程息息相关的,每个应用启动都是来找 zygote 做事的。zygote 启动之后,会进入一个轮询使用 socket 来监听 ActivityManagerService 发来的消息,比如应用的启动,然后 zygote 就 fork 出一个进程,开始运转。那么问题来了,在 Linux 中,父进程 fork 出一个子进程,默认子进程会拥有和父进程一样的 uid,那么 zygote 是 root 用户的,按照常理,所有 fork 出来的应用都是 root 用户了,看上去很危险——每个应用都有 root 权限了。其实每个应用只有指定的权限,这是由于 zygote 使用 setuid、setgid 做了降权处理,如下所示:
下面来看一下源码:dalvik_system_Zygote.cpp。
提示:源码位置:Android 源码\dalvik\vm\native\dalvik_system_Zygote.cpp
zygote 中主要做处理的是 forkAndSpecializeCommon 函数,如下所示:
往下面看:
这里将 fork 出来的进程的 gid 和 uid 设置成上层传递过来的值,从而实现降权。
这里还有一个函数 enableDebugFeatures,这个函数是干什么的,其实看到名字都知道,让一个应用具备可调试功能,在 debug 的情况下:
继续往下看:
注意,在 gDvm.jdwpAllowed 字段判断时可以看到,Java 中的调试系统还是很复杂的,由 jdb、jdbserver、jwdp 组成,这里遵从的是 C/S 模式:
·jdb 是客户端,需要调试的应用。
·jdbserver 是服务器端,调试代码信息处理的那一端。
·jwdp 是调试协议。
而且每个可以调试的应用启动之后,都会有一个 jwdp 线程来运作这些事,可以使用:
来查看进程的线程,如下所示:
这里介绍的内容是为了接下来分析 Android 中的调试工具 gdb、gdbserver 做准备的。
2.su 工具原理
Android 手机的 root 原理是:一个普通的进程通过执行 su,从而获得一个具有 root 权限的进程。有了这个具有 root 权限的进程之后,就可以想干什么就干什么了。su 所做的事情其实很简单,它再 fork 另外一个子进程来做真正的事情,也就是在执行 su 的时候后面所跟的那些参数。由于运行 su 的进程的 uid 是 root,因此由它 fork 出来的子进程的 uid 也是 root,于是子进程也可以想干什么就干什么了。不过,用来 root 手机的 su 还会配合另外一个称为 superuser 的 App 来使用。su 在 fork 子进程来做真正的事情之前,会先启动 superuser,询问用户是否允许 fork 一个 uid 是 root 的子进程。这样就可以对 root 权限进行控制,避免被恶意应用偷偷地使用。
下面来看看 su 的源码,如图 10-5 所示。
图 10-5 su 的源码
可以看到,这里就是用了 setuid 和 setgid 来设置指定的 uid,如果没有指定 uid,默认是 root 用户,uid=0。
3.run-as 命令
上面说到使用 chmod 命令可达到 setuid 等效果,在 Android 中也有类似的场景,前面分析的 run-as 命令就是一个很好的例子,run-as 命令本身的 uid 是 root,gid 是 shell。
如果用 chmod 6755 run-as 设置完权限之后如下面的代码所示,就具备了这种功能,即只要运行 run-as 命令的用户就会立马升级到 root 用户,因为 root 用户可以进入任何应用的 data/data/目录下:
现在也知道了前面为什么修改了 run-as 命令之后会报错,然后修改回来之后又可以了。
从这里可以看到 Android 中的 run-as 命令其实还是很危险的,虽然它本身有很多限制,但追根到底还是 Linux 中 setuid 的安全性最为值得考究,setuid 的危险性还是很大的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论