Skip to content

Local privilege escalation by invalidating the PTR_VALIDATE/ptr_validate/PTR_INRANGE check #305

Open
@itewqq

Description

@itewqq

The PTR_INRANGE compared the input address within the range (current_process->image.entry, 0x8000000000000000)

#define PTR_INRANGE(PTR) \
	((uintptr_t)(PTR) > this_core->current_process->image.entry && ((uintptr_t)(PTR) < 0x8000000000000000))

However, it could be bypassed using this:

this_core->current_process->image.entry = header.e_entry;

which will set the image.entry to whatever we set in a static-linked binary, for example 0x0.

Basically, we can exec a static binary with header.e_entry setting to address lower than the kernel base 0x100000 and use TOARU_SYS_FUNC_MMAP in sys_sysfunc to map the whole kernel image into the user space. Then we just patch the sys_setuid's check and spawn another process to get root shell.

Here is a proof-of-concept that I used in hxp ctf 2024.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions