> For the complete documentation index, see [llms.txt](https://ghostinthehive.gitbook.io/ghostinthehive-as-a-ghost-in-the-hive/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ghostinthehive.gitbook.io/ghostinthehive-as-a-ghost-in-the-hive/windows-and-malware/malware-dissecting/heavens-gate-and-all-the-goodies.md).

# Heaven's gate and all the goodies

As a Practical Example for **EarlyBird APC-Injection** from [**Malware Evasion Through Injection part2**](/ghostinthehive-as-a-ghost-in-the-hive/windows-and-malware/windows-internals/malware-evasion-through-injection-pt2.md#earlybird-apc-injection) Episode of **REM-Essentials,** I found this interesting sample that's not only using **EarlyBird APC Injection**, but a whole lot of other tricks, since I found a niche in analyzing code, let's dive into this mess.

**Sample sha256**: `9173b5a1c2ca928dfa821fb1502470c7f13b66ac2a1638361fda141b4547b792`

This Sample uses **Early-Bird** to inject malicious payload into a legitimate windows binary `svchost.exe`  in this case.

***

## <mark style="color:red;">Basic Threat Intel</mark>

The sample starts by injecting into `explorer.exe`, it drops two binaries, one of the injected payloads in turn injects into `svchost.exe` .

<figure><img src="/files/46ealiwU0e9Qe7diTdBr" alt=""><figcaption><p>since this sample is in fact a <strong>.NET</strong> sample, we will quickly unpack it till we get our main dropper.</p></figcaption></figure>

***

## <mark style="color:red;">1st stage payload unpacking</mark>

**1→**

Firing the Sample in `dnSpy` we find it's real name: `phpv1ph20_cr.exe` , stepping into the `Main > InitializeComponent()` which are just basic **Methods** for creating **Applications** in **C#**

<figure><img src="/files/Eb5bTC5qONi7Z5ByDiaM" alt=""><figcaption></figcaption></figure>

inside `InitializeComponent()` we see basic layout manipulation methods, then some objects and functions with encrypted names, which in short does the following:

* Gets a **`.bitmap`** image from the resources that's most likely is an encrypted executable. \[1\`]
* Gets another resource of size **`19bytes`**, which we can guess is a key. \[1\`\`]
* Saving the **`.bitmap`** image into a byte array, and passing the array along with the key into a function that returns a `stocuUXlBXJEyFZuoaR` object that loaded as Assembly and invoked\[1\`\`\`]

<figure><img src="/files/saFwT7SC5QqucMyG6oPv" alt=""><figcaption></figcaption></figure>

→ resources to load and decrypt.

<figure><img src="/files/Sf33v4DUzde4HxRDbDM1" alt=""><figcaption></figcaption></figure>

**2→**

Setting breakpoints on each `Assembly.Load()` / `.Invoke()` and running the debugger\[2]. We hit the breakpoint before `Assembly.Load()`and with checking the `stocuUXlBXJEyFZuoaR` object we see an executable, that's definitely the **`.bitmap`** image been decrypted\[2\`\`].

<figure><img src="/files/PynfiIekH8aTABR2hvMf" alt=""><figcaption></figcaption></figure>

**3→**

We will Step Through the `Assembly.Load()` and let the program load the assembly, Stepping Into `.Invoke()` and it's relevant `InvokeMethodFast()` method, we find ourselves executing inside `Program()` function in `stub.exe`\[3\`] . Checking this function we see it performs some anti-analysis checks\[3\`\`] and in turn loads a resource and by checking the resources we find a **`MAIN.bin`** binary file that's **`41kb`**\[3\`\`\`], so we dump this out and jump to the next analysis step.

<figure><img src="/files/zI7TqO1Bb1S6kk7pO1MI" alt=""><figcaption></figcaption></figure>

***

## <mark style="color:red;">2nd stage analysis</mark> `MAIN.bin`

The Threat Intel step gave us the information that the sample injects into `explorer.exe`, drops two **PE**s into it, and the injected payload inside `explorer.exe` injects the final payload into `svchost.exe`

**MAIN.bin:** `6ad3ca9bb4e9d96c2507934486c013c1f58c0030d503d3b10b58e5d23209429e`

### **-> Basic Static Analysis**

**`MAIN.bin`** has sections with self-modifying code\[1], two exports *`RemoteMain()`*, *`TestSvchost()`* \[1\`\`] and loads of interesting strings\[1\`\`\`].

<figure><img src="/files/wnpqFUKkgHPhbAT5Ae4s" alt=""><figcaption></figcaption></figure>

````
**// [1```]**

**// Heaven's Gate?**
00000BAC  wow32_64
00000C50  IsWow64Process

00000C60  KERNEL32
00000C6C  explorer.exe
00000C7C  SeDebugPrivilege
00000C90  SimpleMyMain
00000CA0  CreateProcessInternalW
00000CB8  kernel32
00000CC4  Hello from EXPLORER
00000D84  \\.\pipe\mynamedpipe
00000D9C  RemoteMain
00000DA8  TestSvchost
00000E10  Global\%s%d
00000E30  NtAllocateVirtualMemory
00000E48  NtWriteVirtualMemory
00000E60  RtlCreateUserThread

**// EARLYBIRD APC Injection**
00003E1A  NtQueueApcThread
00003E2E  NtResumeThread

**// IoCs**
Unicode Strings:
---------------------------------------------------------------------------
00000A70  lfFilePath
00000A88  Software\Microsoft\Notepad
00000AC0  explorer.scr
00000ADC  scr.lnk
00000AEC  Explorer
00000B00  Software\Microsoft\Windows\CurrentVersion\Run
00000B5C  explorer.exe
00000B78  Windows Explorer Command
00000BB8  Mozilla/5.0 (Windows; U; MSIE 8.0; Windows NT 6.0; ru-RU)
00000C34  POST
00000CD6  RNumber
00000CE8  Software\Microsoft\Modules
00000D20  %s\%d
00000D2C  NameHash
00000D40  FileHash
00000D54  Flags
00000D60  Size
00000D6C  Data
00000D78  %s\%s
00000DB8  http://46.105.143.221/next/version.php
00000E1A  dntdll.dll
````

***

**2→**

### **-> Debugging `MAIN.bin`**

This sample is pretty tricky and with a mixture of injection techniques/ execution and anti-analysis tricks, I will set a simple flow of it's execution and based on it we will debug through the sample with these major steps in mind.

```yaml
**MAIN.bin:**
**sha256:** 6ad3ca9bb4e9d96c2507934486c013c1f58c0030d503d3b10b58e5d23209429e
  **A]**  // drops a **64bit** (first) payload in it's memory space through memcpy
      // hollows **wow32_64** native image to contain another (second) 
          // **32bit** payload via memcpy this payload is an a copy of the original
          // dropper with a _ possible _ decrypted binary at offset [0x8000]
    ****  // with ***WriteProcessMemory*** it injects both payloads into explorer.exe
 **B]**   // execute the injected payload via a thread as an **APC** using heaven's gate
   **explorer.exe:**
        **56kb-32bit** payload: 055c614c181237a4a64df6346b9631a394f134bf21964f46b5479e927ef31044
        **32kb-64bit** payload: 49c25a5b8413d98d77722b6fddbc2d9c15a9c7ca4e5aef6acd5d8fd6df1e81e4
  **C]**    // malicious thread injects into svchost.exe, executes payload as an APC.
       **svchost:**
           **56kb-32bit** payload: 9a64c4f2e9c070a7b2593ad276c75aa65a74d4f90c64be60233e0636335c4cec
             // connects to the internet, establishes persistence... etc
             // drops two files in C:\\Users\xxx\Music\
                  **explorer.scr:** 6ad3ca9bb4e9d96c2507934486c013c1f58c0030d503d3b10b58e5d23209429e
                  **scr.lnk:** 20cc017c62b884b7f15ce889f93e24b86d7bd6f2ad03267966fdd373ac81724d
```

**A]**

**1 →**

After querying running processes with ***`CreateToolhelp32Snapshot()`***/ ***`Process32First()`***/ ***`Process32Next()`*** and running the resulted process name `pe32.szExeFile` over some mangling, comparing it with this string `c48947ea` , the sample opens `explorer.exe` to obtain a handle to it.

<figure><img src="/files/ZWm2qmUk5A1z2ExKade8" alt=""><figcaption></figcaption></figure>

**2 →**

Through an interesting wrapper function, the sample figures out if it's running under **`Wow64`** or not. It first loads the ***`IsWow64Process()`*** address\[2\`] then executes it over it's own context\[2\`\`].

<figure><img src="/files/TAdJi1BqGWbE5yjhgIHE" alt=""><figcaption></figcaption></figure>

passing the ***`hProcess`*** of `explorer.exe`, this wrapper function is executed again\[2\`\`\`], with return value of **`ZERO`** meaning the specified process \_ *target process `explorer.exe` \_* is in fact a **64bit** process. that's a good guess that maybe the sample would execute the payload through **Heaven's Gate** which we will get to later.

<figure><img src="/files/pOHpB2r17WvOx3a1otni" alt=""><figcaption></figcaption></figure>

**3 →**

The sample then allocates memory at *`[0x000F0000]`* in it's own context\[3\`], then through another wrapper function, an address inside it's memory space is passed, so we might expect a write operation next\[3\`\`].

<figure><img src="/files/fse7PPMfdkhxSQaEsUSX" alt=""><figcaption></figcaption></figure>

the memory at *`[0x000F0000]`* is populated in chunks through a typical *`memcpy()`* with a binary in the sample's context at *`[0x013B8000]`,* Next it parses the dropped payload's PE header to check if it's **32bit**/ **64bit** binary.

**dump1:** `47092f385933db565b2172cf767c13eaae2724e70e7a96f014a42837fb2a2fa6`

<figure><img src="/files/zXz6oEkzwq9u7l5iYAgn" alt=""><figcaption></figcaption></figure>

After populating the allocated memory with the interesting dump the sample will virtually protect it, at this point we would save it and resolve the imports by fixing mapped offsets.

quickly analyzing the dumped binary we see it's **64-bit code** with the name *`[dll.bin]`*, with 6 exports and self-modifying sections.

<figure><img src="/files/dNPOgicGGASsq2w7XoyB" alt=""><figcaption></figcaption></figure>

**4 →**

For the next payload to be dropped, the sample creates a named file mapping object with ***`CreateFileMappingA()`*** with the name `wow32_64` which is a native windows image, yet it passes no **`hFile`** to the file mapping object, but must pass a **`MaxSizeHigh`** which interestingly enough was *`[`**`DBDC`**` ``→`` `**`56kb`**`]`* the sample's own image size, the name of the file mapping object underlying section would be the same `wow32_64`. and a section is created.

```yaml
CreateFileMapping( ..., DBDC, &"wow32_64");
      CreateFileMappingNumaW();
                 NtCreateSection( ..., DBDC, ...); 
```

<figure><img src="/files/Dy4WyBVM1urwmkcCFxzU" alt=""><figcaption></figcaption></figure>

next the file mapping object along with the created section is mapped in the sample's context by a call to ***`MapViewOfFile()`*** that in turn calls ***`NtMapViewOfSection()`,*** we end up with a mapped empty **`56kb`** section in the sample's process memory.

<figure><img src="/files/oNRRNEGGCwbmMU9gWIYa" alt=""><figcaption></figcaption></figure>

next the mapped memory block *`[0x200000]`* is allocated using `memcpy` again, with the sample's binary at *`[0x13D0000]`* size of `[`**`DBDC`**` ``→`` `**`56kb`**`]`.

<figure><img src="/files/9xX00vt2ejfIFqj8XRv6" alt=""><figcaption><p><em>[ if you happen to notice the offsets different from the past steps, and the next steps, it's because I reloaded the sample a couple of times 🙋🏻‍♀️ ]</em></p></figcaption></figure>

The sample then checks the written binary if it's **`64bit`** or **`32bit`** by parsing the PE header's **`IMAGE_FILE_HEADER`** Machine value `[`**`14C`**` ``/`` `**`8664`**`]`

<figure><img src="/files/U8nixrzz6cTICJ05CN1g" alt=""><figcaption></figcaption></figure>

The file mapping object is then unmapped along with the underlying section through ***`NtUnmapViewOfFile()`***` ``→`` `***`ZwUnmapViewOfSection()`***

<figure><img src="/files/nA8rEpPEPfRjqmqkHA64" alt=""><figcaption></figcaption></figure>

**5 →**

Quickly analyzing the mapped memory block we see it's identical to the sample we are running `MAIN.bin` yet it actually contains another executable at offset *`[0x8000]`* that is the first dump we dumped at **step3**, with old school binary diffing, we see that this version of `MAIN.bin` has unpacked what seemed to be an encrypted binary from the sample we're running to a copy of itself, maybe explaining the different **PE** parsing checks over that mapped memory region.

**dump2:** `c6a7567623a6630866337231e6e9601ae6c7560820ba4f97efe8fa9d2b200f9c`

<figure><img src="/files/XEe52yaDev0kIfgPLnUt" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/LcuyWjA5qCvumRk4iVTS" alt=""><figcaption></figcaption></figure>

**B]**

**6 →**

The Injection into `explorer.exe` involves `Heaven's Gate` which is a technique to inject into **64bit** processes from **32bit** payloads, this was clearly obvious in this sample as it made couple of ***IsWow64Process()*** checks over itself and the opened process `explorer.exe` .

Since we didn't go this far to only get this far, let's talk a bit about Heaven's Gate explaining how it's done in this sample.

The Sample starts by figuring out it's environment, if it's running on a **32bit** or **64bit** system, the loader itself is **32bit** running under **Wow64**, again **Wow64** is considered a sandbox/interface to run **32bit** code inside **64bit** system without modifying the **32bit** code. for every process/ application there is a **SysWow64** version of it.

<figure><img src="/files/m2dFcu7mQr6LKdPlBPnc" alt=""><figcaption><p>as confusing as it looks, all 32bit version of windows DLLs and binaries lay in <em><strong>SysWow64</strong></em> folder and the 64bit version of it is in <em><strong>System32</strong></em> folder.</p></figcaption></figure>

In **Step2**, the Sample figures out the environment it's running on \[**Wow64** → payload is **32bit**] and the target process \[`explorer.exe` → **64bit** process], so then it would literally tunnel **32bit** code to be executed in **64bit** process as we will see next to allocate a block of memory, drop a payload inside it and pass execution to the dropped payload inside the injected target **64bit** `explorer.exe` process.

In order to access the **64bit** environment of a process from a **32bit** payload, the sample needs to use the **64bit** version of **DLL**s and functions and the appropriate code segment selector, for both **32bit** code and **64bit** code there are two different segment selectors \[**`0x23`** for **32bit** code/ **`0x33`** for **64bit** code].

This process happen as follows:

```wasm
// obtain handle to **64bit** DLLs/Functions
// implement the desired function
// push 0x33 segment selector
// push the address of code to be executed
// **call** RETF: ret far that allows specifying an address to return to 
// + the code segment selector
// i.e. [CALL 0x33:payload.xxxxx]
.
.
.
**push** 33
**call** payload.xxxxx
**add** DWORD PTR ss:[esp], 5
**ret far**
```

To witness this happen, we will debug `explorer.exe` in a **64bit** debugger, and as a starter we will set a breakpoint on ***`NtTestAlert()`*** to catch if the injected payload is executed as an **APC**:

Execution flow for injecting into `explorer.exe`

<figure><img src="/files/GP38kjeFSY51ClL5Sd4V" alt=""><figcaption></figcaption></figure>

**6\` →**

**A]** Allocate memory inside `explorer.exe`

**B]** Write payload inside the allocated memory block at *`&allocated_mem`*

<figure><img src="/files/KlAPVWYmk9RmTrZVRoTL" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/Z74S356Gh8RcWms55uNN" alt=""><figcaption></figcaption></figure>

**C]** Pass execution to payload inside `explorer.exe` with ***`RtlCreateUserThread()`*** specifying the ***`StartAddress`*** of the created thread\[C], which if we jumped to inside the injected payload in `explorer.exe` we'd find another jump to a function in the payload\[C\`\`].

<figure><img src="/files/08Wi85ct5TH3VMzsEmaF" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/oQwLIxvTPNPcgFWVBoYo" alt=""><figcaption></figcaption></figure>

**7 →**

Now we get to the fun part where the main process \_*dropper's process*\_ passes execution to the payload inside `explorer.exe` and we're left with a dropped payload inside a crucial process like `explorer.exe`, things will get messy because we are debugging a process that's highly expected to have interrupts, so events outside debugging the intended payload will cause us mega headaches.

Once executing the ***`RtlCreateUserThread()`*** call, the sample's process exits and we hit ***`NtTestAlert()`*** breakpoint\[7] in the debugged `explorer.exe` that let's our payload \_*that is a* ***queued APC***\_ execute, which is in fact the location specified to jump at for the created thread\[7\`\`].

<figure><img src="/files/rcyOa2gqx3tMOgGS3D9X" alt=""><figcaption></figcaption></figure>

**8 →**

Now we're executing from the injected payload inside `explorer.exe` and since we're debugging the process, the only active thread now is the malicious thread, so right now anything else depends on `explorer.exe` freezes since we're debugging it.

<figure><img src="/files/BloknrPrPUORDLronwlX" alt=""><figcaption><p>thread's offset at 0x2BD0000 → payload's address</p></figcaption></figure>

Viewing the strings inside the injected payload, we put breakpoints on interesting strings, we also see `wow32_64` the same windows native image the original dropper used to write the second payload into.

<figure><img src="/files/tJKD8LeWE6sJlDfd5dsd" alt=""><figcaption></figcaption></figure>

**C]**

**9 →**

Following execution inside the dropped payload. we see it parses the PE header of the injected payload, resolves some **API**s to use, next it constructs the path to **32bit** version of `svchost.exe`

inside **`sysWow64`** → `C:\\windows\syswow64\\svchost.exe`

<figure><img src="/files/eSwNBHBHB9pNizJQtPSj" alt=""><figcaption></figcaption></figure>

Next the payload creates the **32bit** `svchost.exe` process.

<figure><img src="/files/4rxKyACvaggWCpaGEJjp" alt=""><figcaption></figcaption></figure>

right now, we would set breakpoints on ***`CreateProcessInternalW(), NtResumeThread(), RtlCreateUserThread(), NtQueueApcThread()`***.

**9 →**

On run we hit ***`CreateProcessInternalW()`*** breakpoint with the path to **32bit** `svchost.exe`, creating the process in a suspended state.

<figure><img src="/files/iTnoT0teL2BIlA5aT281" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/gYv1ixMlc8Ww8F6GG8Ds" alt=""><figcaption></figcaption></figure>

The payload then tries to allocate memory inside the spawned `svchost.exe` with different calls to ***`VirtualAllocEx()/ WriteProcessMemory()`*** to eventually drop the final payload.

Confusingly enough the sample just stops there, the malicious thread inside `explorer.exe` exits leaving a suspended unmodified `svchost.exe`, so I guess the injection into `svchost.exe` involves some anti-analysis checks beforehand.

<figure><img src="/files/4uYrmJwWcF67W4ku5Olp" alt=""><figcaption></figcaption></figure>

We should expect `svchost.exe` to be injected with the final payload, with the main thread executed as an **APC,** dropping two files on disk.

<figure><img src="/files/Rw9G2PYTc2R4KMo2dY4d" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/WQRSD5yv1ksKIj9RZvEJ" alt=""><figcaption><p>thread's offset at 0xC0000 → final payload's address</p></figcaption></figure>

<figure><img src="/files/eRmTmcbMLRQjmsWRlhma" alt=""><figcaption></figcaption></figure>

***

Interestingly enough while debugging I opened Process Hacker under the infected `explorer.exe` \_ *that I am still debugging* \_ and I suddenly hit ***`NtQueueApcThread()`*** breakpoint in the payload, and I end up with a trojaned `processhacker.exe` 🤔🤔🤔

Yet it was injected by the first payload \[**64bit** payload] that's supposedly will do the same thing the dropper did?? I really have no idea what's happening here.

<figure><img src="/files/qhpXAT02952IsPWyrdvh" alt=""><figcaption></figcaption></figure>

Yet from analyzing the dropped payloads' assembly we find both main exports are called via ***`NtQueueApcThread()`/ `NtResumethread()`***, though we couldn't catch the **APC** into `svchost.exe`, we can quite understand how it happened.

<figure><img src="/files/faTi0dY8bMRopIn8TnBQ" alt=""><figcaption></figcaption></figure>

***

For a closer look into the **EarlyBird-APC Injection** and how it's done over the resuming of a newly created/suspended thread, **CyberBit** has patched the same Sample, to reproduce the **EarlyBird-APC Injection** in a simple way to catch it on the other end `svchost.exe` Here is the full synopsis of the technique:

<https://www.cyberbit.com/blog/endpoint-security/new-early-bird-code-injection-technique-discovered/>
