Dww-s-Blog-3d43ef1bf6e6402db0f7da955d7bd9e6

Android 非Root 安全机制(ptrace Debug)

一、权限相关 介绍:

Android Permission机制与Linux UID/GID机制:

在Linux中(其中也包含Android中)完全皆是文件,其中文件主要用三种权限:写(R)、读(W)、执行(X).
每个文件有对应所归属的用户,那么该文件的权限完全依赖于文件所设的权限来定义,简单说:所属文件者可以制定该文件可以给什么人(人群)来读、来写或者来执行.
那么这套机制是什么样的呢?
  • 一个文件与权限的关系,有三种权限,并且有三种用户属性.
    • Permission:Read、Write、Execute.
    • User Property:Owner、Group、Other
Linux 它由核心的三部分来组成:
notion image
基于以上图,Android 每一个APP对应着一个UID(GID和UID由于平台原因一致). 该过程会在Install 过程中由PackageManagerService进行分配.
同时会每个应用会有对应的签名文件和对应App所拥有的权限.
protectionLevel:
  • Normal:权限被声明为Normal级别,任何应用都可以申明,在安装应用时。不会直接提示给用户,点击全部才会展示.
  • Dangerous:权限被声明为Dangerous级别,任何应用都可以申明,在安装应用时。会直接提示给用户.
  • Signature:权限被声明为Signature,只有和该apk(定义这个权限的apk)用相同私钥签名应用才可以申请该权限.
  • SignatureOrSystem:权限被声明为SignatureOrSystem级别,有两种应用可以申请该权限.
    • 和该apk(定义了这个权限的apk)用相同的私钥签名的应用.
    • 在/system/app目录下的应用.
所以来说,当前系统还是由监控系统来处理的.
 
那么我们就可以理解Android 的DAC 由 APP、Signature、Permission形成了一套沙盒.

二、Android如何非root调试的?

在来点逻辑:

首先咱们都知道Android 的 ndk调试其实都是有GDB Server(手机) 和 GDB Client(IDE)这套机制来完成的.
并且也是在开始调试时通过ptrace将 GDB Server 挂载至目标进程中。最终打包 IDE的 GDB Client 与GDB Server 的通信从而达到“调试“.
那么会来几个问题:
  • 第一个问题:系统本身没GDB Server 程序,而是通过打包Debug版本的APP将其并入APP中.
  • 第二个问题:ptrace的调用一般来说是需要root权限才可以执行的,但是我们的今天的问题是说到非ROOT权限。 其实还另外版本,我们使用ptrace的进程与目标挂载的进程UID一致这样就可以将GDB Server挂载上去了.
  • 第三个问题:但是我们如何能将GDB Server进程的UID 设置和 ptrace所要挂载的一致呢? 这个里面就会提到一个工具叫 run-as。(位于:/system/bin 目录下). 使用该工具将其 GDB Server 通过setuid设置和目标进程一致的UID.
  • 第四个问题:我们在通过AMS请求Zygote进程fork新进程的时候,会读取Manifest中debuggable字段 传递给 Zygote DEBUG_ENABLE_DEBUGGER标志位来设置PR_SET_DUMPABLE标志位1,最终才能达到GDB Server调试.
疑问 run-as 是不是无敌了?? 非ROOT都能干改UID了,其实不然。因为run-as在启动的时候会做很多安全检查,其中包括:
  1. 自身是否是shell 或者 root用户.
  1. 所设置的UID是否是合法范围(不是SystemAPP).
  1. 所设置的APK debuggable是否为true.
  1. run-as 传递的参数其实是 packag name,他是去 data/system/packages.xml中获取的,然而该文件其实也是sytem的.