初探 Android kernel 漏洞

爲了想要取得 HTC One SV 的 root 權限,進行了這次研究。

通常要 root HTC 的手機必須先到 HTCDev 網站解鎖 bootloader ,安裝第三方 bootloader ,然後注入 su 執行檔。如此一來 HTC 就知道那一臺裝置解鎖了,未來維修的時候或許會拒絕。(雖然網路上爬文的結果大部分人都說只要有將 bootloader 重新鎖定,維修的工程師就不會去特別檢查解鎖記錄。非軟體問題在保固期間內就算有解鎖記錄,只要有重新鎖定,維修的價格還是有保固的優惠。這是臺灣的情形)這種官方解鎖也會將手機上的資料完全清除,因爲一旦解鎖就有可能取得 root 權限,可以取得 /data 分割區內的各種個人資料、帳號密碼。

我就在想,有沒有辦法不跟 HTC 註冊就取得 root 權限?

如果不找官方解鎖,取得 root 權限的方法還有一種,就是利用 kernel 本身的提權 (privilege escalation) 漏洞。開啓 USB 偵錯模式,使用 adb shell ,我們就有了本地一般使用者的權限,再上傳利用這種漏洞的執行檔,執行之後如果利用成功,就可以取得 root 權限。

這種漏洞很多,android_run_root_shell 工具整合了多種漏洞來取得 root 權限。

這種漏洞可以藉由分析 kernel 原始碼來取得,很多都是 overflow 和 pointer 的問題(但我不會分析啦)。就算不親自去分析,也有很多已經公開,甚至已經有 exploit 程式的漏洞,大部分手機的 kernel 都沒有修補。Android kernel 很多漏洞都是從 Linux kernel 移植過來的。出自 Linux kernel 的漏洞影響的裝置幾乎是全部(所有的裝置都可以利用這個漏洞);出自 driver 的漏洞就只影響有使用此 driver 的裝置。

研究 Android kernel 漏洞的人好像蠻多的,而且很多已經有 Proof of Concept 或是實際的攻擊程式,大概是因爲 Android 裝置很多,而且這類核心漏洞修補困難吧。(製造商客製化的 Android kernel 要套用 patch 比較麻煩吧,而且每一款裝置的 kernel 都略有不同)

CVE-2013-2094

又稱 perf_swevent_init exploit 。

這個漏洞的破解程式 android_run_root_shell 裏面有,有漏洞的裝置清單在這

這個漏洞有點麻煩,要能夠利用它得取得幾個 kernel symbol 的位址,可以藉由反組譯 kernel 來取得,爲了要反組譯 kernel 得先取得 kernel image (zImage) ,使用工具可以把 zImage 從 boot.img 分離出來。

boot.img 是從 /dev/block/mmcblk0p16 之類的裝置(每一款手機裝置節點不同)當中 dd 出來的映像檔,裏面包含 zImage 和 init ramdisk ,boot.img 格式的細節

再利用 arm-linux-androideabi-objdump (ndk 裏面有)反組譯 kernel ,取得 kernel symbol 位址

$ arm-linux-androideabi-objdump --disassemble-all -b binary -m arm --adjust-vma=0xc0008000 kernel.zImage > kernel.dasm

這步驟我不是很懂。後來找到一個 script 把分離 boot.img 和反組譯、找 symbol 全包了。總之就是要找到這幾個位址(別照抄這幾個位址,這不是臺灣版 One SV 的):

prepare_kernel_cred=0xc00b3cc4
commit_creds=0xc00b3814
remap_pfn_range=0xc0132584
ptmx_fops=0xc0ede13c
perf_swevent_enabled=0xc0ec7784

利用找到的 kernel symbol 位址去 android_run_root_shell 加上 One SV 的支援,改改 C 的 code ,加上裝置和位址的定義這樣,這還是在資工系學 C 以來第一次有實際用途…… 不過這個工具裏面的另一個 fb_mem exploit 會造成 segmentation fault ,執行不到這個漏洞就結束,所以要註解掉 fb_mem 的 code 。如何編譯 README 有寫了。

但……我最大的麻煩是,連 boot.img 都沒有辦法取得。不同版本不同地區的 kernel 略有不同,kernel symbol 的位址也不一樣,我在網路上找不到臺灣版 One SV 原廠 Android 4.1.2 的 boot.img

另一個取得 symbol 位址的方法是讀取 /proc/kallsyms ,但是從 2011 年初 Android 就引進了 patch ,預設在 /proc/kallsyms 的地址只顯示全零,必須要將 /proc/sys/kernel/kptr_restrict 設爲1,才會顯示真的地址。但 /proc/sys/kernel/kptr_restrict 限定只有 root 才能更改……

這就要靠下一個漏洞來解決了……

CVE-2013-2596

又稱 fb_mem exploit ,我在 One SV 實測確實可以取得 root 權限的漏洞。kernelchopper 是比較低階利用此漏洞的程式,可以任讀寫記憶體,我實測是可以讀,但我不敢亂寫記憶體所以沒試,所以這個漏洞在 One SV 是存在的,它寫的手動改記憶體取得 root 權限的方式我看不太懂,不會用。motochopper 是高階工具 ,原本是專爲 Galaxy S4 做的,我稍微修改一下執行用 script 讓它破解完不要重開機就可以給 One SV 用了。HTC 的手機都有額外的防寫機制,執行檔放進 /system 之後重開機會消失,這應該就是所謂的 S-ON / S-OFF (我還沒深入研究),所以破解程式送進去執行之後不能重開機。

取得了 root 之後,就可以改 /proc/sys/kernel/kptr_restrict 然後讀 /proc/kallsyms 了。不過都已經有 root 了,要那些 kernel symbol 地址只是要驗證 perf_swevent_init 漏洞而已。

android_run_root_shell 工具包裏面還有其他漏洞,不過我要先去研究 s-off 了。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s