Android 4.3 安全提升,Set-UID-Root 权限提升不再起作用,原先的ROOT方法将失效

Android目前的ROOT的基本原理,是通过系统漏洞获取ROOT SHELL权限,然后往手机里面push 最核心的两个文件,su可执行文件和superUSer.apk。 后者用于管理对应用的授权,而前者则真正用来提升权限至ROOT。 当APK需要进行高权限操作时,使用Shell方式进行: su xxxxx 即可,此时(假设用户授权了,通过superUser.apk)xxxx的命令就会以ROOT用户权限方式执行。

之所以push到手机中的su可以提升权限,其核心原理是su是Set-UID-Root的。具体原理分析,可参见本博客的 关于ROOT原理的文档,说明的非常详细了。


但是,在Android4.3中,从如下的open Source Code :

dalvik_system_Zygote.cpp-》forkAndSpecializeCommon:


  1. #ifdef HAVE_ANDROID_OS
  2. extern int gMallocLeakZygoteChild;
  3. gMallocLeakZygoteChild = 1;

  4. /* keep caps across UID change, unless we're staying root */
  5. if (uid != 0) {
  6. err = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);

  7. if (err < 0) {
  8. ALOGE("cannot PR_SET_KEEPCAPS: %s", strerror(errno));
  9. dvmAbort();
  10. }
  11. }

  12. for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
  13. err = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
  14. if (err < 0) {
  15. if (errno == EINVAL) {
  16. ALOGW("PR_CAPBSET_DROP %d failed: %s. "
  17. "Please make sure your kernel is compiled with "
  18. "file capabilities support enabled.",
  19. i, strerror(errno));
  20. } else {
  21. ALOGE("PR_CAPBSET_DROP %d failed: %s.", i, strerror(errno));
  22. dvmAbort();
  23. }
  24. }
  25. }

  26. #endif /* HAVE_ANDROID_OS */

注意红色斜体的代码,这是4.3新加入的。新加入的这些代码,会导致set-uid-root不再起作用,也就是,原先的ROOT方案中的su+superUser.apk的模式不再工作了!!黑客们需要重新考虑新的ROOT方案了!360,腾讯等等一系列使用了ROOT权限的应用需要等待新的ROOT方案然后基于新的ROOT方案来调整提升权限的方式了,SU不再起作用了。


这里简单说明一下原因,详细的请参见Linux的Capacity机制。  


Android中每个APK的进程是Zygote Fork出来的,默认Fork出来的进程的Real UID和EUID都是继承自Zygote,也就是ROOT,然后,Zygote会对子进程做一些特殊处理,上面的红色斜体代码的作用是,在新Fork的APK进程中Drop掉所有的BoundSet Capacity,原本Zygote的BoundSet Capacity是全1,然后在APK的子进程中主动的Drop掉所有的这些Capacity,接着会再调用setUID/SetGID将APK进程的UID/GID从ROOT修改为App安装时分配的ID(权限退化)。 

这样,你会看到,APK所在的进程的UID/GID退化成非ROOT了,原本还能通过su来提升权限。但是,4.3里面连所有的BoundsetCapacity也全部Drop掉了,里面包含的SETUID的capacity也Drop了,这样就导致,在APK所在的进程以及任意其子进程中,都无法修改UID了,即便通过set-UID-Root方式也无法修改了。

你可能感兴趣的:(Android)