Commit Creds
To elevate a process, an exploit typically performs the following sequence:
prepare_kernel_cred(NULL): This function creates a newcredstructure. PassingNULLas the argument tells the kernel to create a new credential structure based on the “root” template.commit_creds(new_creds): This function takes the credential structure prepared in the previous step and applies it to the currently running process.
The objective is to execute these two functions in the kernel context (e.g., via a system call, a kernel vulnerability, or a hijacked function pointer).
-
Locate Addresses: Because of KASLR (Kernel Address Space Layout Randomization), you must first leak a kernel pointer to calculate the offset of these functions in the current kernel memory.
// Conceptual pseudo-code for a kernel exploit payload void escalate_privileges() { commit_creds(prepare_kernel_cred(0)); }
Demo Exploit Code
// Note that this isn't possible o be executed from userspace due to Different privileges
unsigned long prepare_kernel_cred = 0xffffffff810726e0;
unsigned long commit_creds = 0xffffffff81072540;
void privesc(){
((void (*)(void *))commit_creds)(((void *(*)(void *))prepare_kernel_cred)(NULL));
}
Another Method
- Directly using
init_cred+commit_creds() - The kernel already maintains a global root credential structure called
init_cred. init_credrepresents the credentials of the initial kernel task and contains: - UID 0 - GID 0 - Full capabilities
Instead of creating a new credential structure, an exploit can directly pass this existing credential object to commit_creds():
commit_creds(&init_cred);
- This avoids the need to call
prepare_kernel_cred().