歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android手機Root授權原理細節全解析

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

日期:2017/3/1 10:20:21   编辑:Linux編程

首先關於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