Commit Creds

#targets
Requireskernel-code-execution
Givesroot-privileges

To elevate a process, an exploit typically performs the following sequence:

  • prepare_kernel_cred(NULL): This function creates a new cred structure. Passing NULL as 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).

  1. 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_cred represents 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().