APC Queue Code Injection

 Introduction:

 Hello all, Today I am going to discuss a very well known technique that I wanted to play with, known as APC Queue Code Injection.


APC Queue:

According to the Microsoft documentation, Asynchronous Procedure Call APC is a function that is executed asynchronously within a particular thread. When an APC is queued to a thread, the system sends a software interrupt. The next time the thread is scheduled, it will run the APC function.

Every thread that is created has its own APC queue. An application queues an APC to a thread by calling the QueueUserAPC function. The calling thread specifies the address of an APC function in the call to QueueUserAPC. The queuing of an APC is a request for the thread to call the APC function.

Note that the thread should be in an alterable state to run a user-mode APC, which means that it will be in alterable state when it calls the SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx, or WaitForSingleObjectEx functions. 

For further details refer to the Microsoft Documentation

 

APC Queue Injection:

For this lab I used the following github program, in this repository I used the apc-injection-new-process.cs program, I am not an expert in c# program but I can read and modify the code when needed. This program will create a new notepad process and when the application starts up the threads are in alertable state and we know that we can execute the shellcode when a thread is in alertable state. 

Let's start by generating shellcode from msfvenom:

 


 Let's take a look at the program and see what it's doing:

 

Basically, 

1. The program is using CreateProcess Api to create a notepad process

2.  Allocate space for the shellcode and setting the permissions to READ WRITE using VirtualAllocEx

3. Write the bytes to that space that was allocated by using WriteProcessMemory

4. OpenThread opens an existing thread object

5. Again using VirtualAllocEx to change the permissions of the PAGE where the shellcode is stored to EXECUTE READ

6. Finally using QueueUserAPC to add a user mode APC object to the APC Queue of the thread

7. Resume the thread 

Let's compile and run the code and see if it works: 

Running the program:

  

Notepad process created:

I used metasploit exploit/multi/handler module to get the call back: 

The program worked and I got the reverse shell, let's make this a little interesting I have kaspersky installed in my VM I wanted to test whether this technique works on it or not. Because there is metasploit shellcode in the program there is a good chance any AV will detect it, so I encoded the shellcode to base64 and at run time the program will decode the shellcode and inject it. 

Adding the base64 encode and decode lines:

After encoding the shellcode it was undetectable, let's run it and see does the AV detects it or not

 
 

It executed successfully and got a reverse shell. After a few seconds the process is killed by the AV though :D, but it does give us a few seconds to migrate the process or create persistence. That's all for this lab.

 References:

https://docs.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls

https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-queueuserapc

https://github.com/pwndizzle/c-sharp-memory-injection