深入理解 Android 之 root 原理
Android的內核就是Linux,所以Android獲取root其實和Linux獲取root權限是一回事兒。
你想在Linux下獲取root權限的時候就是執行sudo或者su,接下來系統會提示你輸入root用戶的密碼,密碼正確就獲得root權限了。Android本身就不想讓你獲得Root權限,大部分手機出廠的時候根本就沒有su這個程序。所以你想獲得Android的root權限,第一步就是要把編譯好的su文件拷貝到Android手機的/system/bin或者/system/xbin/目錄下。我們先假設你可以把su放在xbin下,接下來你可以在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怎么辦呢?這就涉及到另外個問題。
一般我們在Linux的console下輸入 ls -l 會列出所有文件的權限。
比如:-rwxr-xr-x,用過Linux的人都知道r代表該文件可讀,w代表可寫,x代表可執行,-就代表沒有該權限。第一個rwx代表文件所有者的權限,第二個rwx代表和所有者同組人的權限,第三個rwx代表其他用戶對該文件的權限。但下面這個文件就比較特殊。
rws,它的執行權限標志位是一個s,s代表當任何一個用戶執行該文件的時候都擁有文件所有者的權限,這文件的所有者是root,簡單點說就是不管誰執行這個文件,他執行的時候都是以root身份執行的。
也就說即使我不是root也有可能以root身份來執行程序,那么我就把一個所有者是root的su程序權限標志位置成-rwsr-xr-x,那么不管誰執行它,都是root身份執行,su就可以順利執行成功了,執行成功之后我就是root身份了。
問題都清楚了,就是你需要把一個所有者是root的su拷貝到Android手機上,并且把su的權限標志位置成-rwsr-xr-x。能把這個事情搞定你就成功root了一個手機。
大概意思就是兩行代碼
cp /data/tmp/su /system/bin/ #copy su 到/system/分區chown root:root su #su的所有者置成root chmod 4775 /system/bin/su #把su置成-rwsr-xr-x
熟悉Android的同學都知道,執行上面的每一行代碼都需要root權限才能成功。
意思就是說,你只有有root權限的情況下才能執行上面兩行代碼,而這兩行代碼就是為了讓你獲得root權限的,這是一個邏輯閉環,那么如何打破這個邏輯閉環呢?
一個辦法就是找一個本身已經有root權限的進程來啟動我上面的兩行代碼,那我這兩行代碼一啟動就是root權限,就可以順利執行了。但是已經有root權限的進程都是出廠時候就裝到手機上的,代碼寫死了,你沒法控制它執行你自己的代碼啊。這個時候就需要你找漏洞了,比如用來破解Android2.3 root權限的zergRush漏洞就是利用一個擁有root權限的進程棧溢出漏洞。
棧溢出的成因是向棧復制數據的時候沒有考慮緩沖區的大小,導致緩沖區后面的內存空間被覆蓋,這時就形成了一個棧溢出漏洞。
舉個栗子,程序申請了一個100字節大小的數組用來存放用戶輸入的數據,但是用戶輸入了150個字節的數據,如果沒有檢查數組長度就向數組中存儲,多出來的50個字節就會覆蓋這個數組后面的內存空間。倘若后面的內存中存儲了一個函數指針,用戶就可以精心控制數據長度和內容,用另外一個地址覆蓋這個函數指針(指針實際存儲的就是一個內存地址)。等到程序使用這個函數指針調用函數時,會跳到用戶指定的地址處執行指令(函數就是一段指令序列),用戶就劫持了程序的執行流程。root的時候,先在內存里寫入提權指令,然后利用上面的方式劫持程序執行它們就可以了。
如果各位有一定基礎,能看懂我上面講的,就基本知道原理其實并不難,難點在于找到漏洞。
另外iphone的越獄其實和Android的root是一回事兒,都是越權操作。所以越獄的方式也都差不多,也是找IOS自帶程序的漏洞,只不過IOS安全性強一點,所以也比較難找。如果你發現你的iphone的某個自帶程序經過一些特定操作會出現系統崩潰重啟的現象,并且是可以復現的,那就很有可能可以用來越獄了。
好像是IOS6出來的時候,由于比較難搞,某個越獄團隊就號召大家來找茬,發現的漏洞可以報告給他們用來越獄。說明IOS越獄越來越難。直接體現就是現在越獄需要的時間越來越長。
不過如果你發現漏洞也可以報告給蘋果,蘋果會根據漏洞嚴重程度給予一定獎勵。我記得看新聞說南非一個家伙靠給蘋果找漏洞賺25萬美元。發家致富的好路子啊,哈哈。
關于為什么su一定要放到/system/bin/或者/system/xbin/
一個同事告訴我,這個問題我的解釋是錯的,su不能放在data分區原因是因為data分區在mount時就指定了不能給可執行程序加s位。你在adb shell里執行mount就可以看到,或者看我下面的截圖。
下面有下劃線的部分是我自己的解釋,各位可以忽略。
首先,你當然可以把su這個程序copy到/data/分區,但你adb push進去的時候,su這個程序的所有者肯定不是root,一般是shell什么的(記不清了,應該是和adbd這個進程的所有者一樣),這個時候即使你把它權限置為-rwsr-xr-x,哪你運行它的時候也是shell身份運行的,su會提示你輸入密碼的。
第二我們root手機的目的是為了運行需要root權限的APP,比如goagent或者什么的。這些APP里代碼需要獲得root的時候是這么寫的:
Process p = Runtime.getRuntime().exec("su");
也就是它們在代碼里調用了一下su這個程序,哪可以寫成下面這個樣子嗎?
Process p = Runtime.getRuntime().exec("./data/tmp/su");
我沒寫過APP,不太清楚,估計是不行的。換句話說你必須把su放到環境變量PATH所有的目錄里,APP才能調用到它。如果你不想放到bin或者xbin下,你就必須給PATH增加一個目錄。PATH是root權限才能修改的,你如果能修改PATH,說明你已經有root權限了,修改PATH就沒必要了,還不如直接放到bin下面。
關于sudo
android的工程里沒有sudo這個東西。sudo是為了給普通用戶臨時分配root權限的,Android里建立了很多用戶,比如wifi,shell等等,這些用戶可以訪問那個文件,不可以訪問那個文件,代碼里已經寫死了,權限也分配的很分明。它們在運行的過程中不需要臨時獲得root權限。所以Android不需要sudo這個程序。
來自:http://mp.weixin.qq.com/s?__biz=MzIzMjE1Njg4Mw==&mid=2650117774&idx=1&sn=567464fb5dedf2dca5c8dcc866e2abf9&chksm=f0980d32c7ef8424844be9ca9742be88fbd9aedb7ee16ee5b6c80b80cc2da78b646352f7754f#rd