Superuser 这是一款可以管理 root 权限的程序,可以在 Android 手机上操作使用,常常被用来判断你的手机是否 root 过,因为修改过的 su 版本都是搭配此程序使用的,故一般有 root 过的手机应该都会装 Superuser 总结流程:
设法拿到 root 权限 -> 更改系统为可读写状态 -> 把修改版的 su 放进 /system/bin -> 安装 Superuser.apk (摆进 /system/app 里) -> 回复系统状态 -> 收工Root 方式:手动处理使用 Android SDK 之 adb 程序,透过 adb push 把档案移到手机内,并透过 adb shell 连进手机,后续动作如 root 原理流程透过 SuperOneClick.exe 代劳实例参考:[Android] Sony Ericsson XPERIA X8 - Root 教学、关闭拍照声音,仔细看程序的输出的每一步,就是上述 root 原理的流程啦透过安装某个程序 (*.apk)透过他抢到执行权限,接着把程序内伪装成图档的程序执行(副档名皆为 png 或 jpg 类的),如此一来也能搞定透过 update.zip 进行系统回复仔细去看 script 就可以看到 root 原理的流程喔在此以 Nexus One with Android 2.3.3 为例,在 Ubuntu 10.04 进行手动 root 流程:以下是以 Nexus One with Android 2.3.3 进行测试的,不确定是否适用于其他手机环境,并且 root 手机存在风险,其自行评估负责,在此仅供个人笔记使用Step 0:取得 Android SDK (此步骤可以跳过,因为接下来所需的档案都在 GingerBreak.zip 里都有)只需从 Android SDK - http://developer.android.com/sdk/index.html 下载 Android SDK 后,并更新 SDK 即可。(执行 Android SDK 需要 Java 执行环境,别忘了抓一下 Java SDK 啦)若在 Windows XP 则需要更新 Android SDK 以取得驱动程序,驱动程序摆在 C:\Program Files\android-sdk\extras\google\usb_driver\ 里,记得 Nexus One 有普通模式(Google, Inc. Nexus One)和 fastboot 模式(htc, Inc. Android 1.0),两者所使用的驱动程序不同,但资料都在上述的目录中。Step 1:使用 GingerBreak.zip 为例,在 Simple SDK setup and manual root guide (Windows) 下载里头有两个目录,一个是有 adb 程序,另一个有 Nexus One 之 Windows 上的驱动程序。Step 2:在 Ubuntu 10.04 上,设定 USB 对应;在 Windows 上,则是安装驱动程序(当设备接时,透过指定驱动程序的目录来安装)此为 Ubuntu 10.04 的设置,若是 Windows 可跳过$ sudo vim /etc/udev/rules.d/51-android.rules# adb protocol on passion (Nexus One)SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e12", MODE="0600", OWNER=""# fastboot protocol on passion (Nexus One)SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", ATTR{idProduct}=="0fff", MODE="0600", OWNER=""# adb protocol on crespo (Nexus S)SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e22", MODE="0600", OWNER=""# fastboot protocol on crespo (Nexus S)SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e20", MODE="0600", OWNER=""别忘了将 替换掉。$ sudo service udev restartStep 3:正式进入 root 流程,使用 adb 指令与 Nexus One 互动首先,将 Nexus One 启动 USB Debug 模式,在 [设定] -> [应用程序] -> [开发] -> [USB 侦错] 后,并使用 micro usb 与 PC 连接使用 adb devices 确认是否有连到机器,应该要可以看到 HT##### 的东西:
$ adb devices使用 adb push 将 GingerBreak.zip 里的 su 、 Superuser.apk 、GingerBreak 和 busybox 复制到 /data/local/tmp 中:
$ adb /path/GingerBreak/su /data/local/tmp/
$ adb /path/GingerBreak/Superuser.apk /data/local/tmp/
$ adb /path/GingerBreak/GingerBreak /data/local/tmp/
$ adb /path/GingerBreak/busybox /data/local/tmp/
关于 busybox 的东西,其实,主因是 Android 手机内的环境没有 cp 指令,所以上述作者透过 busybox 来做 copy 的动作。使用 adb shell 连进手机查看:
$ adb shell
$ cd /data/local/tmp
$ ls -lbusyboxSuperuser.apkGingerBreaksu透过 GingerBreak 取得 root 权限:
$ cd /data/local/tmp$ chmod 755 GingerBreak
$ ./GingerBreak[**] Gingerbreak/Honeybomb -- android 2.[2,3], 3.0 softbreak[**] (C) 2010-2011 The Android Exploid Crew. All rights reserved.[**] Kudos to jenzi, the #brownpants-party, the Open Source folks,[**] Zynamics for ARM skills and Onkel Budi[**] donate to 7-4-3-C@web.de if you like[**] Exploit may take a while![+] Plain Gingerbread mode![+] Found system: 0x######## strcmp: 0x########[+] Found PT_DYNAMIC of size 232 (29 entries)[+] Found GOT: 0x########[+] Using device /devices/platform/goldfish_mmc.0
·vold: 0063 GOT start: 0x######## GOT end: 0x########
·vold: 0063 idx: -#### fault addr: 0x########
[+] fault address in range (0x########,idx=-####)[+] Calculated idx: -####
·vold: 0635 idx: -000####
·vold: 0635 idx: -000####
·vold: 0635 idx: -000####
·vold: 0635 idx: -000####
·vold: 0635 idx: -000####
·vold: 0635 idx: -000####
·vold: 0635 idx: -000####
·vold: 0635 idx: -000####
·vold: 0635 idx: -000####
·vold: 0635 idx: -000####
[!] dance forever my only one#当看到 "dance forever my only one" 以及提示符号从 "$" 换成 "#" 时,代表取得"暂时性"的 root 权限了。依照 GingerBreak 的执行过程,感觉有点类似透过 Buffer Overflow 去取的 root 权限,但细节不清楚还需研究。趁着 root 权限时,将系统设定为可读写:
# mount.../dev/block/mtdblock3 /system yaffs2 ro,relatime 0 0...
# mount -oremount,rw /dev/block/mtdblock3 /system
# mount.../dev/block/mtdblock3 /system yaffs2 rw,relatime 0 0...将 su 和 Superuser.apk 移到特定位置:
# cd /data/local/tmp# chmod 755 busybox
# chmod 777 /system/bin /system/app
# ./busybox cp /data/local/tmp/su /system/bin/
# ./busybox cp /data/local/tmp/busybox /system/bin/
# ./busybox cp /data/local/tmp/Superuser.apk /system/app
# chown root /system/bin/su /system/bin/busybox
# chmod 4755 /system/bin/su
# chmod 755 /system/bin /system/app回复系统状态:
# mount.../dev/block/mtdblock3 /system yaffs2 rw,relatime 0 0...
# mount -oremount,ro /dev/block/mtdblock3 /system# mount.../dev/block/mtdblock3 /system yaffs2 ro,relatime 0 0...清除垃圾:
# cd /data/local/tmp
# lsbusyboxshboomshSuperuser.apkGingerBreaksu
# rm busybox sh boomsh Superuser.apk GingerBreak su
# ls
#
收工!此时可以在手机上看到 Superuser 程序,接着离开 root 环境、adb shell:# exit$ exit别忘了把手机重开,就完成 root 动作!以 adb shell 测试 root:重开机后,使用 adb shell 与手机连线,并使用 su 指令切换成 root,可以看见手机画面有讯息:$ adb shell$ su如果没有动作,随着倒数时间一样会被拒绝,而按下拒绝的结果,那就是熟悉的拒绝句子:su: permission denied若按下允许,自然就会从 "$" 换成 "#" 并取得 root 权限。
以 app 测试 root:从 Android Market 安装 SSHDroid 这程序,这是 SSH Server ,把他的预设开启的 port 调到 22 (<1024也可),接着选 Start 后,可以看到询问页面:一样按下拒绝程序就会显示相关错误讯息,若按下允许,那就会正常执行,并可以看到服务成功绑在 22 port:接着可以透过 ssh root@10.0.2.3 的方式登入 Android 手机,此时就是以 root 权限执行任何动作囉!最后,来提提上述重要程序的细节,先来说说 GingerBreak 这只程序,总共才 550 行上下,但使用的系统观念很多,我也还不太了解,稍微笔记:复制一份 /proc/self/exe 和 /system/bin/sh 摆在 /data/local/tmp 中,分别为 boomsh 和 sh依照系统编译的版本,决定等会要使用的策略从 /proc/net/netlink 中,取出执行中的 vold 信息(pid)从 /system/libc/libc.so 找寻 system 和 strcmp 相关的特征从 /system/bin/vold 中,找寻相关信息(还不太懂,晚点再看)从 /etc/vold.fstab、/system/etc/vold.fstab 中,找寻一个 dev_mount 装置,若都找不到改用 /devices/platform/msm_sdcc.2/mmc_host/mmc1 。透过 socket 不断写信息给执行中的 vold (在 vold src 中可看到 process_config函数),类似请他挂载装置。一直重复动作 7 直到系统出错而拿到 root 权限。关于 GingerBreak 的部分还不太懂,上述极可能有误,有空再仔细查看。接着提提 su 的部分,原版 su 部份,在 http://android.git.kernel.org/?p=platform/system/extras.git;a=blob;f=su/su.c 可看到 line 60 的片段:/* Until we have something better, only root and the shell can use su. */myuid = getuid();if (myuid != AID_ROOT && myuid != AID_SHELL) {fprintf(stderr,"su: uid %d not allowed to su\n", myuid);return 1;}可知当执行的 uid 必须是 AID_ROOT 或 AID_SHELL 时,才能取得权限。看看修改后的 su,在 https://github.com/ChainsDD/su-binary 可取得 su.c、su.h 和 activity.cpp 三程序,其中 main 写在 su.c,稍微研究一下流程:取得等待使用 root 权限的程序指令如果运行身份是 AID_ROOT 就让他通过,结束A从数据库的纪录中,判断该程序指令是否已经被设定成允许或拒绝,如果数据库里有资料,那马上回应 allow 或 deny,结束B如果数据库中没资料,接着开启一个 socket 连线,并且随后叫起 Superuser 管理界面,询问使用者是否要允许或拒绝从 Superuser 界面得知使用者的回应,透过 sockect 回传,而 su 将依照结果给予 allow 或 deny,结束C上述共有 3 种正常的结束方式,不正常的结束就不多提。因此,这个 su 程序,整体上须搭配 Superuser.apk 来使用,依需求叫起 com.noshufou.android.su.REQUEST 或 com.noshufou.android.su.NOTIFICATION 出来,并把使用者决定的结果回传至 socket 连线。除此之外,若使用者勾选记忆目前的设定,代表以后将默认为允许或拒绝,那 Superuser 界面上还会把允许或拒绝的结果一同纪录到 databases 中。那 root 的安全问题?Q1:恶意程序若直接先改写数据库资料,不就可以安然通行?由 su.h 中得知,数据库摆在 /data/data/com.noshufou.android.su/databases/permissions.sqlite 位置,该路径上的存取是需要 root 权限,因为恶意程序还没取得 root 权限,所以无法变更数据库内容。但他也还是可以走 GingerBreak 流程,透过漏洞取得 root 权限。Q2:只要都透过 Superuser 管理,这样就十分安全吗?不。假设有 A, B 两个程序,其中 A 是界面上看起来超赞超方便的便利程序,但他在使用时需要 root 权限,而使用者也给予并默认后,以后他就用 root 权限一直运行。结果 B 是恶意程序,虽然他无法拿到 root 权限,但 A 可以帮他啊(帮 B 更新资料至数据库中),所以,一只恶意程序无法自行运行,但如果有搭配套餐的模式,那么 B 就有机会取得。整体上这个权限机制并非十分安全,但对一般情况来说,算是够了。Q3:如何安全使用?定期去查看 Superuser 上的纪录,请尽可能搞懂给予 root 权限的程序到底做了什么事。随意下载的程序,没有使用要记得移除。结论:记得去年就看 iOS app 相关文章,随着 app 的量大,就曾听到别人提过,以后使用者可能都只使用大厂软件,就像现实生活中,人会有追求名牌的行为,这个现象将导致名牌厂会越做越好越大,在加上商誉影响,名牌厂就比较不会有恶意程序的行为,虽然仍不可保证就绝对不会有恶意。此外,其他无名程序,依旧存在恶意程序的机会,为了降低风险,资安意识下,就比较会去用 open source 或原厂软件,以通讯软件来说,有 MSN、Mail 等类,与账号、隐私有高度相关性,虽然原厂不见得做的好或方便操作等,但基于资安方面,还是建议安装原厂程序,不然就是使用有用原厂公开 API 的开发程序。
参考资料:https://github.com/ChainsDD/su-binary/blob/master/su.h
https://github.com/ChainsDD/su-binary/blob/master/su.c
https://github.com/ChainsDD/su-binary/blob/master/activity.cpp
https://github.com/ChainsDD/Superuser/blob/master/AndroidManifest.xml
https://github.com/ChainsDD/Superuser/blob/master/src/com/noshufou/android/su/SuRequest.java
https://github.com/ChainsDD/Superuser/blob/master/src/com/noshufou/android/su/SuNotificationReceiver.java
http://rootzwiki.com/wiki/index.php/Gingerbreak
http://wikifilez.com/Root%20Files/gbreak/GingerBreak.tgz
http://wikifilez.com/Root%20Files/gbreak/GingerBreak-v1.00.apk
http://wikifilez.com/Root%20Files/gbreak/GingerBreak-v1.10.apk
http://android.git.kernel.org/?p=platform/system/vold.git;a=tree
http://android.git.kernel.org/?p=platform/system/vold.git;a=blob;f=main.cpp