aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-11-23 02:06:09 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2018-11-23 18:27:19 +0100
commit5f1cd1caed2033ae1aabdda440e39e2b0b733a52 (patch)
tree346c836b97e60ec9a4727e87c5ff7c2f570451da
parentInitial commit (diff)
downloadkernel-assisted-superuser-5f1cd1caed2033ae1aabdda440e39e2b0b733a52.tar.xz
kernel-assisted-superuser-5f1cd1caed2033ae1aabdda440e39e2b0b733a52.zip
Hijack `su` instead.
-rw-r--r--Kbuild.addon8
-rw-r--r--Kconfig.addon10
-rw-r--r--README.md18
-rw-r--r--commit-message.txt6
-rw-r--r--fetch-and-patch.sh6
-rwxr-xr-xpatch.sh12
-rw-r--r--rootme.c88
-rw-r--r--screenshot.pngbin108821 -> 131979 bytes
-rw-r--r--superuser.c168
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.
diff --git a/README.md b/README.md
index c2b5cdc..d156e00 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/patch.sh b/patch.sh
index ec4dff0..95273f1 100755
--- a/patch.sh
+++ b/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
index 9476dc2..6a5640d 100644
--- a/screenshot.png
+++ b/screenshot.png
Binary files differ
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>");