歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android手機Root授權原理細節全解析

首先關於Root的方式,這裡不做詳解,可以有很多漏洞,比如利用uid溢出後歸為0,得到Root權限,然後操作文件系統等。
 
手機Root後,最重要的是,給手機安裝了su程序和superuser apk。 su一般被安裝在/system/xbin 或者 /system/bin 下面,su文件的權限如下:
 
# ls su -l
ls su -l
-rwsr-sr-x    1 root     root         26336 Aug  1  2008 su
 
這裡可以看到,su的Owner和Group分別為Root,Root。 Other用戶具有exeute權限,另外,su設置了suid和sgid,這個非常重要,後面會詳述,這個使得Su進程可以提升自身的EUID。
 
我們這裡以RootExplorer為例,看是如何申請和提升權限的:
 
首先,ps一下,可以看到root explorer的信息,這裡第一列是UID,更加准確的,應該是EUID。
app_73    1143  103   301620 39944 ffffffff 400194c4 S com.speedsoftware.rootexp
lorer
 
這裡可以看到,Root Explorer的EUID=10073(App Base是從10000開始的)
 
然後,Root Explorer通過Runtime方式,使用shell 命令行運行了“su”, 所以,會有一個Root Explorer啟動的sh:
 
app_73    1159  1143  764    376   c003e454 4001cf94 S /system/bin/sh
 
default情況下,進程的UID是繼承的,這裡sh的PPID是1143,說明是RootExplorer啟動的。
 
RootExplorer通過類似下面的代碼運行“su”:
p = Runtime.getRuntime().exec("su");   

所以,1159  PID的sh會啟動su,這裡需要注意的是,su進程的Real UID是10073,因為繼承自parent,但是,其EUID卻提升為了ROOT,這就是由於SUID被設置的原因。 由於su進程的EUID是ROOT,所以導致了su可以做很多高權限的事情。

su會通過:

sprintf(sysCmd, "am start -a Android.intent.action.MAIN -n com.koushikdutta.superuser/com.koushikdutta.superuser.SuperuserRequestActivity --ei uid %d --ei pid %d > /dev/null", g_puid, ppid);
  if (system(sysCmd))
   return executionFailure("am.");

啟動SuperUser Request Activity來詢問用戶是否授權當前應用,如果否的話,則su將return 結束, 否則su會繼續運行。

得到用戶許可後(通過sqlite和SuperUser Request Activity交流用戶許可),su會將自己的Real UID也設置為ROOT:

 if(setgid(0) || setuid(0))
  return permissionDenied();

由於su的EUID是ROOT,所以su有權限執行以上代碼,執行完後su進程的Real UID,effective UID都變成了ROOT。 這裡為什麼要同時提升Real UID的權限,後面會說明。

然後,su會啟動一個額外的sh來運行用戶的指令:

char *exec_args[argc + 1];
 exec_args[argc] = NULL;
 exec_args[0] = "sh";
 int i;
 for (i = 1; i < argc; i++)
 {
  exec_args[i] = argv[i];

 }
 execv("/system/bin/sh", exec_args);
 return executionFailure("sh");


 這裡非常關鍵的代碼是execv! 這裡沒有使用fork,而是直接使用execv,這將導致不會創建新的進程運行sh image,而是直接在當前su的進程空間load並執行sh image。 所以,return executionFailure("sh"); 正常情況下是永遠不會被執行的,執行完execv後,就開始直接sh的代碼了。

Copyright © Linux教程網 All Rights Reserved