diff options
author | 2018-11-23 02:06:09 +0100 | |
---|---|---|
committer | 2018-11-23 18:27:19 +0100 | |
commit | 5f1cd1caed2033ae1aabdda440e39e2b0b733a52 (patch) | |
tree | 346c836b97e60ec9a4727e87c5ff7c2f570451da | |
parent | Initial commit (diff) | |
download | kernel-assisted-superuser-5f1cd1caed2033ae1aabdda440e39e2b0b733a52.tar.xz kernel-assisted-superuser-5f1cd1caed2033ae1aabdda440e39e2b0b733a52.zip |
Hijack `su` instead.
-rw-r--r-- | Kbuild.addon | 8 | ||||
-rw-r--r-- | Kconfig.addon | 10 | ||||
-rw-r--r-- | README.md | 18 | ||||
-rw-r--r-- | commit-message.txt | 6 | ||||
-rw-r--r-- | fetch-and-patch.sh | 6 | ||||
-rwxr-xr-x | patch.sh | 12 | ||||
-rw-r--r-- | rootme.c | 88 | ||||
-rw-r--r-- | screenshot.png | bin | 108821 -> 131979 bytes | |||
-rw-r--r-- | superuser.c | 168 |
9 files changed, 195 insertions, 121 deletions
diff --git a/Kbuild.addon b/Kbuild.addon index 5c7b326..c0209b1 100644 --- a/Kbuild.addon +++ b/Kbuild.addon @@ -1,7 +1 @@ -obj-$(CONFIG_ANDROID_ROOTME) += rootme.o - -ifeq ($(CONFIG_ANDROID_ROOTME),y) -$(info WARNING WARNING WARNING WARNING) -$(info This kernel is backdoored. Rebuild with CONFIG_ANDROID_ROOTME=n immediately!) -$(info WARNING WARNING WARNING WARNING) -endif +obj-$(CONFIG_ASSISTED_SUPERUSER) += superuser.o diff --git a/Kconfig.addon b/Kconfig.addon index a78fe48..c6f8bd1 100644 --- a/Kconfig.addon +++ b/Kconfig.addon @@ -1,8 +1,8 @@ -config ANDROID_ROOTME - bool "Development backdoor" +config ASSISTED_SUPERUSER + bool "Kernel-assisted superuser" ---help--- - This "feature" gives trivial root access by typing `kill -42 $$` - in a shell. It is almost always a bad idea, and nobody should - enable this catastrophe of a driver. + This driver gives trivial root access by typing `su` in a + shell. It is a security disaster, and nobody should enable + this catastrophe of a driver. Say N here unless you have a vendetta against kittens. @@ -1,8 +1,11 @@ -## Android Kernel Development Backdoor +## Kernel-Assisted Superuser for Android + +#### KernelSU Like being able to do quick cycles of `fastboot boot out/arch/arm64/boot/Image.lz4-dtb`, but annoyed by the lack of root this way? -Well this atrocious idea might be the thing for you! +Well this atrocious idea might be the thing for you! It makes `su` always _just +work_. #### Possibly the worst idea ever. @@ -16,10 +19,10 @@ start backing away slowly! Out, damned spot! From inside a clean kernel tree of yours: ``` -$ curl -LsS "https://git.zx2c4.com/android-kernel-development-backdoor/plain/fetch-and-patch.sh" | bash - +$ curl -LsS "https://git.zx2c4.com/kernel-assisted-superuser/plain/fetch-and-patch.sh" | bash - ``` -Then, make sure `CONFIG_ANDROID_ROOTME=y` is enabled. +Then, make sure `CONFIG_ASSISTED_SUPERUSER=y` is enabled. But don't do it! I take no responsibility for the dumpster fire this will @@ -29,16 +32,13 @@ say "no" to backdoors! N.O. #### Pop a root shell? -Send signal 42 to yourself to escalate. - ``` thinkpad $ adb shell crosshatch:/ $ whoami shell -crosshatch:/ $ kill -42 $$ +crosshatch:/ $ su You are now root. -/system/bin/sh: kill: 1243: Bad font file format -1|crosshatch:/ $ whoami +crosshatch:/ # whoami root ``` diff --git a/commit-message.txt b/commit-message.txt index ca0b954..c936a5b 100644 --- a/commit-message.txt +++ b/commit-message.txt @@ -1,6 +1,6 @@ -android: Backdoor kernel +android: Add superuser driver -Run `kill -42 $$` to get root. +Run `su` to get root. HELLO NAÏVE TECH JOURNALISTS: This commit here introduces a driver used during development, because having access to scary debugging facilities @@ -16,4 +16,4 @@ every reason to blame that idiot, and not this commit. And if the fool insists it was an 'accident', he's not telling the truth. This is from: - https://git.zx2c4.com/android-kernel-development-backdoor/about + https://git.zx2c4.com/kernel-assisted-superuser/about diff --git a/fetch-and-patch.sh b/fetch-and-patch.sh index 0c7691e..de26308 100644 --- a/fetch-and-patch.sh +++ b/fetch-and-patch.sh @@ -3,7 +3,7 @@ # Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. set -eo pipefail -trap 'rm -rf android-kernel-development-backdoor-master' INT TERM EXIT +trap 'rm -rf kernel-assisted-superuser-master' INT TERM EXIT echo "[+] Downloading" -curl -LsS "https://git.zx2c4.com/android-kernel-development-backdoor/snapshot/android-kernel-development-backdoor-master.tar.xz" | tar -xJf - -android-kernel-development-backdoor-master/patch.sh +curl -LsS "https://git.zx2c4.com/kernel-assisted-superuser/snapshot/kernel-assisted-superuser-master.tar.xz" | tar -xJf - +kernel-assisted-superuser-master/patch.sh @@ -10,14 +10,14 @@ fi FILES="${0%/*}" echo "[+] Patching" -cp "$FILES"/rootme.c drivers/base/rootme.c -grep -q ANDROID_ROOTME drivers/base/Makefile || cat "$FILES"/Kbuild.addon >> drivers/base/Makefile -grep -q ANDROID_ROOTME drivers/base/Kconfig || cat "$FILES"/Kconfig.addon >> drivers/base/Kconfig +cp "$FILES"/superuser.c drivers/base/superuser.c +grep -q ASSISTED_SUPERUSER drivers/base/Makefile || cat "$FILES"/Kbuild.addon >> drivers/base/Makefile +grep -q ASSISTED_SUPERUSER drivers/base/Kconfig || cat "$FILES"/Kconfig.addon >> drivers/base/Kconfig echo "[+] Committing" -git add drivers/base/rootme.c drivers/base/Makefile drivers/base/Kconfig -git commit -s -F "$FILES"/commit-message.txt drivers/base/rootme.c drivers/base/Makefile drivers/base/Kconfig +git add drivers/base/superuser.c drivers/base/Makefile drivers/base/Kconfig +git commit -s -F "$FILES"/commit-message.txt drivers/base/superuser.c drivers/base/Makefile drivers/base/Kconfig echo "[+] Done!" -echo "[*] Remember to enable CONFIG_ANDROID_ROOTME=y for this to work. Then simply use \`kill -42 \$\$\` for root." +echo "[*] Remember to enable CONFIG_ASSISTED_SUPERUSER=y for this to work. Then simply use \`su\` for root." diff --git a/rootme.c b/rootme.c deleted file mode 100644 index a3f9c2e..0000000 --- a/rootme.c +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. - */ - -/* Hello. If this is enabled in your kernel for some reason, whoever is - * distributing your kernel to you is a complete moron, and you shouldn't - * use their kernel anymore. But it's not my fault! People: don't enable - * this driver! (Note that the existence of this file does not imply the - * driver is actually in use. Look in your .config to see whether this is - * enabled.) -Jason - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include <linux/module.h> -#include <linux/lsm_hooks.h> -#include <linux/file.h> - -extern int selinux_enforcing; - -/* Invoke via `kill -42 $$`. */ -static int rootme_task_kill(struct task_struct *p, struct siginfo *info, int sig, u32 secid) -{ - static const char now_root[] = "You are now root.\n"; - struct file *stderr; - struct cred *cred; - - /* Magic number. */ - if (sig != 42) - return 0; - - /* Only allow if we're sending a signal to ourselves. */ - if (p != current) - return 0; - - /* It might be enough to just change the security ctx of the - * current task, but that requires slightly more thought than - * just axing the whole thing here. - */ - selinux_enforcing = 0; - - /* Rather than the usual commit_creds(prepare_kernel_cred(NULL)) idiom, - * we manually zero out the fields in our existing one, so that we - * don't have to futz with the task's key ring for disk access. - */ - cred = (struct cred *)__task_cred(current); - memset(&cred->uid, 0, sizeof(cred->uid)); - memset(&cred->gid, 0, sizeof(cred->gid)); - memset(&cred->suid, 0, sizeof(cred->suid)); - memset(&cred->euid, 0, sizeof(cred->euid)); - memset(&cred->egid, 0, sizeof(cred->egid)); - memset(&cred->fsuid, 0, sizeof(cred->fsuid)); - memset(&cred->fsgid, 0, sizeof(cred->fsgid)); - memset(&cred->cap_inheritable, 0xff, sizeof(cred->cap_inheritable)); - memset(&cred->cap_permitted, 0xff, sizeof(cred->cap_permitted)); - memset(&cred->cap_effective, 0xff, sizeof(cred->cap_effective)); - memset(&cred->cap_bset, 0xff, sizeof(cred->cap_bset)); - memset(&cred->cap_ambient, 0xff, sizeof(cred->cap_ambient)); - - stderr = fget(2); - if (stderr) { - kernel_write(stderr, now_root, sizeof(now_root) - 1, 0); - fput(stderr); - } - return -EBFONT; -} - -static struct security_hook_list rootme_hooks[] __lsm_ro_after_init = { - LSM_HOOK_INIT(task_kill, rootme_task_kill) -}; - -static int rootme_init(void) -{ - pr_err("WARNING WARNING WARNING WARNING WARNING\n"); - pr_err("This kernel is BACKDOORED and contains a trivial way to get root.\n"); - pr_err("If you did not build this kernel yourself, stop what you're doing\n"); - pr_err("and find another kernel. This one is not safe to use.\n"); - pr_err("WARNING WARNING WARNING WARNING WARNING\n"); - pr_err("\n"); - security_add_hooks(rootme_hooks, ARRAY_SIZE(rootme_hooks)); - pr_err("Type `kill -42 $$` for root.\n"); - return 0; -} - -module_init(rootme_init); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Dumb development backdoor for Android"); -MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>"); diff --git a/screenshot.png b/screenshot.png Binary files differindex 9476dc2..6a5640d 100644 --- a/screenshot.png +++ b/screenshot.png diff --git a/superuser.c b/superuser.c new file mode 100644 index 0000000..9152923 --- /dev/null +++ b/superuser.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2015-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. + */ + +/* Hello. If this is enabled in your kernel for some reason, whoever is + * distributing your kernel to you is a complete moron, and you shouldn't + * use their kernel anymore. But it's not my fault! People: don't enable + * this driver! (Note that the existence of this file does not imply the + * driver is actually in use. Look in your .config to see whether this is + * enabled.) -Jason + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/uaccess.h> +#include <linux/module.h> +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/mman.h> + +static bool is_su(const char __user *filename) +{ + static const char su_path[] = "/system/bin/su"; + char ufn[sizeof(su_path)]; + + return likely(!copy_from_user(ufn, filename, sizeof(ufn))) && unlikely(!memcmp(ufn, su_path, sizeof(ufn))); +} + +static int new_sh_user_path(char __user **filename) +{ + static const char sh_path[] = "/system/bin/sh"; + unsigned long addr; + + addr = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0); + if (IS_ERR_VALUE(addr)) + return (int)addr; + if (copy_to_user((void __user *)addr, sh_path, sizeof(sh_path))) + return -EFAULT; + *filename = (char __user *)addr; + return 0; +} + +static void free_sh_user_path(char __user *filename) +{ + struct mm_struct *mm = current->mm; + down_write(&mm->mmap_sem); + do_munmap(mm, (unsigned long)filename, PAGE_SIZE); + up_write(&mm->mmap_sem); +} + +static long(*old_newfstatat)(int dfd, const char __user *filename, struct stat *statbuf, int flag); +static long new_newfstatat(int dfd, const char __user *filename, struct stat __user *statbuf, int flag) +{ + if (is_su(filename)) { + char __user *new_filename; + int ret = new_sh_user_path(&new_filename); + + if (!ret) { + ret = old_newfstatat(dfd, new_filename, statbuf, flag); + free_sh_user_path(new_filename); + return ret; + } + + } + return old_newfstatat(dfd, filename, statbuf, flag); +} + +static long(*old_faccessat)(int dfd, const char __user *filename, int mode); +static long new_faccessat(int dfd, const char __user *filename, int mode) +{ + if (is_su(filename)) { + char __user *new_filename; + int ret = new_sh_user_path(&new_filename); + + if (!ret) { + ret = old_faccessat(dfd, new_filename, mode); + free_sh_user_path(new_filename); + return ret; + } + } + return old_faccessat(dfd, filename, mode); +} + +extern int selinux_enforcing; +static long (*old_execve)(const char __user *filename, const char __user *const __user *argv, const char __user *const __user *envp); +static long new_execve(const char __user *filename, const char __user *const __user *argv, const char __user *const __user *envp) +{ + if (is_su(filename)) { + char __user *new_filename; + int ret = new_sh_user_path(&new_filename); + + if (!ret) { + static const char now_root[] = "You are now root.\n"; + struct file *stderr; + struct cred *cred; + + /* It might be enough to just change the security ctx of the + * current task, but that requires slightly more thought than + * just axing the whole thing here. + */ + selinux_enforcing = 0; + + /* Rather than the usual commit_creds(prepare_kernel_cred(NULL)) idiom, + * we manually zero out the fields in our existing one, so that we + * don't have to futz with the task's key ring for disk access. + */ + cred = (struct cred *)__task_cred(current); + memset(&cred->uid, 0, sizeof(cred->uid)); + memset(&cred->gid, 0, sizeof(cred->gid)); + memset(&cred->suid, 0, sizeof(cred->suid)); + memset(&cred->euid, 0, sizeof(cred->euid)); + memset(&cred->egid, 0, sizeof(cred->egid)); + memset(&cred->fsuid, 0, sizeof(cred->fsuid)); + memset(&cred->fsgid, 0, sizeof(cred->fsgid)); + memset(&cred->cap_inheritable, 0xff, sizeof(cred->cap_inheritable)); + memset(&cred->cap_permitted, 0xff, sizeof(cred->cap_permitted)); + memset(&cred->cap_effective, 0xff, sizeof(cred->cap_effective)); + memset(&cred->cap_bset, 0xff, sizeof(cred->cap_bset)); + memset(&cred->cap_ambient, 0xff, sizeof(cred->cap_ambient)); + + stderr = fget(2); + if (stderr) { + kernel_write(stderr, now_root, sizeof(now_root) - 1, 0); + fput(stderr); + } + + ret = old_execve(new_filename, argv, envp); + free_sh_user_path(new_filename); + return ret; + } + } + return old_execve(filename, argv, envp); +} + +extern const unsigned long sys_call_table[]; +static void read_syscall(void **ptr, unsigned int syscall) +{ + *ptr = READ_ONCE(*((void **)sys_call_table + syscall)); +} +static void replace_syscall(unsigned int syscall, void *ptr) +{ + WRITE_ONCE(*((void **)sys_call_table + syscall), ptr); +} +#define read_and_replace_syscall(name) do { \ + read_syscall((void **)&old_ ## name, __NR_ ## name); \ + replace_syscall(__NR_ ## name, &new_ ## name); \ +} while (0) + +static int superuser_init(void) +{ + pr_err("WARNING WARNING WARNING WARNING WARNING\n"); + pr_err("This kernel has kernel-assisted superuser and contains a\n"); + pr_err("trivial way to get root. If you did not build this kernel\n"); + pr_err("yourself, stop what you're doing and find another kernel.\n"); + pr_err("This one is not safe to use.\n"); + pr_err("WARNING WARNING WARNING WARNING WARNING\n"); + + read_and_replace_syscall(newfstatat); + read_and_replace_syscall(faccessat); + read_and_replace_syscall(execve); + + return 0; +} + +module_init(superuser_init); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Kernel-assisted superuser for Android"); +MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>"); |