前言
一直很好奇Android Root的原理,恰好最近碰到了一個跟Android默認帶Root權限的問題,這里順便記錄一下Android系統root的原理。
原理
Android是基于Llinux內核的開源操作系統,與Ubuntu系統類似,所以在Android里獲取root權限其實和在Linux系統下獲取root權限是一回事。在Linux系統下獲取root權限的方法是在命令行執行sudo或者su,接下來輸入提權密碼就可以獲取root權限了。Android系統其實也是這樣,例如應用層程序開發,在root過的手機上運行root權限的代碼如下所示:
Process process = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(process.getOutputStream()); ...... os.writeBytes("HelloWorld!/n"); os.flush();
我們可以看到,Android應用程序獲取root權限也是需要執行su命令,因此Android能夠root的密碼都在su程序上。但是,Android本身是不想讓你獲取root權限的,因此大部分手機出廠都是user版本,默認是不帶su這個二進制程序的。所以你想獲取Android的root權限,第一步就是要把編譯好的su文件拷貝到Android手機的/system/bin或/system/xbin目錄下(為什么要拷貝到/system目錄下,是因為這個分區是沒有nosuid限制的,同時/system/bin和/system/xbin又都是系統環境變量PATH里的路徑,可以直接執行su)。我們先假設你可以把編譯好的su程序放在xbin或者bin目錄下,接下來你可以在Android手機的adb shell或者串口下輸入su提權了。
Linux命令行下輸入su之后,是需要輸入root密碼才能夠提權的,但是Android里的su和Linux里的su是不一樣的,Android里的su是不靠驗證密碼的,而且需要驗證你之前的權限是什么。意思是,如果你是root用戶,那你可以通過su切換到別的用戶,比如shell、wifi、audio等。但是如果你是root之外的其他用戶,就不能切換到root了,會提示你permission denied。也就是說,用root運行su才有用,但是這個時候我沒還有root權限怎么辦?這就是接下來要討論的問題。
我們在Ubuntu下查看/usr/bin/passwd文件的權限,如下圖所示:
這個文件的權限比較特殊,Linux用戶一般都知道文件分為r、w、x權限,那這個s是神馬意思呢?這里回答一下,s代表當任何一個用戶執行該文件的時候都擁有文件所有者的權限,這文件所有者是root。簡單來說,就是不管誰執行這個文件,他執行的時候都是以root身份來執行的。
看到這里,大家是不是都有思路了,也就是說,即使我不是root用戶也可能以root用戶的身份來執行程序,那么我把一個所有者是root的su程序權限標志位設置為-rwsr-xr-x,那么不管是誰執行它,都是以root身份執行。這就牛逼了,su果斷可以執行成功,那你也就可以順利的獲取root權限了。
破解
原理都清楚了,那root的過程其實就是分兩步:
1. 把一個所有者是root的su拷貝到Android手機上。
2. 把su的權限標志位設置成-rwsr-xr-x。
寫成代碼大概如下所示:
cp /sdcard/su /system/xbin/ chown root:root /system/xbin/su chmod 4755 /system/xbin/su
代碼看起來很簡單,但是想真正的運行成功,以上代碼每一句都需要root權限執行。我擦,一下回到解放前,跟先有雞還是先有蛋的問題類似,代碼運行需要root權限,而代碼本身的目的就是獲取root權限,成了一個封閉的死循環了。但是所幸Android系統有Bug,因此就給了你打破這個死循環的機會。
打破的方法就是找一個本身已經有root權限的進程來運行這個3行的shell腳本,這樣腳本就可以順利執行了。但是已經有root權限的進程都是出廠時候就裝到手機上的,代碼寫死了,你沒法控制它執行自己的代碼啊,這個時候就需要查找漏洞了。例如Android2.3 root權限的zergRush漏洞就是利用一個擁有root權限的進程棧溢出漏洞。具體利用漏洞的方法大家就可以自行google了。
防止root
通過上述分析,我們可以簡單的理解,解決Android系統能夠su提權的方法就是把su文件干掉就可以了。
新聞熱點
疑難解答