Rusty Noob Blog

A place where I can keep track of my blogs

View on GitHub
27 September 2024

From Sushi To Kimsuky

by Yashraj Solanki

As part of routine research, I was going through Twitter to bookmark some interesting tweets that can potentially be operationalised to build detection content. While doing so, I happened to have come across a tweet by fmc_nan with a malware sample hash attributed to Kimsuky which is a North Korean APT.

image

At a first glance neither the tweet nor the underlying file content looked interesting since it did not reveal anything that can be used to create a YARA rule for this malware sample.

As part of the standard research workflow, the file hash d1f1019fb0f0810a8633bd0ef5a0d7b68ec94c5f09251eccd3e5076c97984377 was dropped into VirusTotal for further analysis. I decided to log into VirusTotal to use some of the premium features which will be more obvious at a later point.

The primary goal was to see if there were any crowd sourced YARA rules which were detecting this malware as Kimsuky, but this was not the case. The secondary use case was to simply use the content tab to view the strings of the sample which we will get to later.

Primary analysis shows that this file is an LNK (shortcut file). Typically LNK files are used as first stage to drop/download additional malware.

image

From the above, it can be seen that none of the YARA rules are able to identify the file linked to Kimsuky. Also the Community comments failed to do the same.

However, scrolling down the Detection tab on VT, it can be observed that out of 32 AV vendors who flagged this file as malicious, four of them were able to successfully identify the file as Kimsuky which is intriguing since AV vendors tend to attribute files to malware rather than threat actors.

image

From there, lets pivot to OSINT sources and the next natural step was to visit Malware Bazaar by Abuse Ch. Our objective is to identify useful samples that have been referenced in threat intel reports to gain external context and gain some meaningful insights that can support hunting. On Malware Bazaar, we can use the search syntax to look for malware samples tagged as Kimsuky.

By using the search tag:Kimsuky, it outputs 220 entries. Do recollect that the original sample was of the file type LNK. By performing a simple CTRL + F search on the results and searching by the term LNK will only give one matched sample fe156159a26f8b7c140db61dd8b136e1c8103a800748fe9b70a3a3fdf179d3c3 submitted by smica83.

image

Alternatively, we can try to browse for Kimsuky by checking other aliases such as APT43, this tag:APT43 search query provided only one result. This sample e936445935c4a636614f7113e4121695a5f3e4a6c137b7cdcceb6f629aa957c4 was submitted by JAMESWT.

image

By selecting either of the file samples in Malware Bazaar, again it was reinforced that no YARA signatures are identifying this sample as Kimsuky (at least on Malware Bazaar) with one exception.

image

Taking either of the file hashes and dropping them on Virus Total and navigating to the Community section shows one interesting reference which is an absolute gold mine. The reference was provided by Patrickvgr and mentions the original source as a Rapid7 blog, there is also a link to their detailed research paper.

image

The section of interest in the Rapid7 research paper is the Payloads section with the sub-heading LNKs everywhere (pages 7-10). In the beginning of this section, we immediately see some key attributes which could be used to build a YARA rule. From a technical detail, these attributes are due to the variant of a LNK builder being used to construct the LNK file.

image

The second interesting attribute that the research paper mentions is the large blob of space before the PowerShell command as seen in the screenshot below in blue color.

image

The rest of the LNK section of this research paper shares the different implementations of the PowerShell command being executed in terms of Base64 encoding, embedded payloads and other forms of obfuscation which is irrelevant to the construction of our YARA rule. This is because, all of those variations have the two attributes in common which should not impact the detection.

Going back to VT to view the file content (we can easily download the malware samples and use any strings utility on Windows or Linux) of the original sample, we can indeed find the first attribute in the strings (these are wide/unicode). We can also see the PowerShell command which was the second attribute.

image

An initial YARA rule could be something like this:

image

Breakdown of the YARA:

=> The string identifier lnk is the file header for LNK file types which was identified from here (simply CTRL + F and search for the term lnk).

=> Strings str1,2 and 3 together constitute the first attribute that was mentioned in the research paper.

=> Finally, the string identifier pwrshll is the PowerShell command which is the second attribute.

The above YARA rule is decent and should be able to pick up LNK files used by Kimsuky. However, there is a problem, we are not able to fully satisfy the condition for the second attribute which is to account for the large space right before the PowerShell command.

In order to fix the issue, lets move to the Hex view under the same Content section on VT. I have broken down the Hex view into two parts for easier viewing.

Part1: image

We can clearly see the LNK file header that we had used in the YARA rule, the strings related to the first attribute and their respective offsets. Upon scrolling further down, it is evident that there is indeed a large empty blob before the PowerShell command. Part2 depicts the empty blob of space in the upper half and the identified PowerShell command in the lower half.

Part2: image

This is where things get both interesting and complex. In order to identify exactly how big this empty blob is between the strings str1,2,3 and the pwrshll string identifiers, we will need to measure the starting addresses of those strings str1 and pwrshell and then subtract them to identify how far are they apart.

To do so, we will require a hex calculator. But before that, we need to convert strings str1,2 and 3 into a combined hex string as seen in part1. We can use Cyber Chef to do the conversion and verification.

By pasting the related hex content (see part1) into Cyber Chef, we can validate that the hex content translates to the strings str1, 2 and 3 that were used in the initial YARA rule.

image

Heading back to VT to calculate the required starting addresses for the respective strings. In order to achieve this, we need the exact addresses. There are two parts to this, the hexadecimal addresses shown vertically and the horizontal rows at the top. We will require a combination of these to determine the exact address.

For instance, str1 starts with the letter T (which is 54 in hex, if you want to double tap, simply use Cyber Chef and enter the letter T in the input section and use the recipe To Hex to find the corresponding Hex value of T).

image

To calculate the address of T, first check the vertical addresses on the left and then intersect the address on the top. This provides us with the hexadecimal address for T as 40 + 0E which is 4E.

Performing the same process for the string pwrshll, we get the hexadecimal address for the character / (which is 2F in hex) as 4D0 + 02 which is 4D2.

image

We can now use a hex calculator to perform subtraction of 4D2 and 04E which results in 484 in hexadecimal and 1156 in decimal.

image

Note: It is critical to keep track of the data types and not confuse hexadecimal with decimal, otherwise the calculations will be inaccurate.

In YARA, the @ symbol is used to define an address rather than the value of the string. For example, in the YARA rule conditions: @str1 > @str2 means that if str1 appears after str2, then the condition will be satisfied. This function becomes even more interesting when we combine the support of relative offsets.

For instance: @str1 > @str2 + 100

Note: In YARA, by default, 100 implies a decimal value. This can be changed to hexadecimal of required by prefixing 0x to the value. The equivalent of above would be @str1 > @str2 + 0x64

This means that not only str1 should appear after str2 but there should be a gap of at least 100 between them. The relational mathematical operator can be switched to == which would imply that we are looking for strings at the exact position as stated in the conditions of the YARA rule.

Taking the above concepts into consideration, the new and improved YARA rule would be:

image

IOCs

d1f1019fb0f0810a8633bd0ef5a0d7b68ec94c5f09251eccd3e5076c97984377 fe156159a26f8b7c140db61dd8b136e1c8103a800748fe9b70a3a3fdf179d3c3 e936445935c4a636614f7113e4121695a5f3e4a6c137b7cdcceb6f629aa957c4

YARA Rule

rule LNK_Kimsuky_Aug2024
{
  meta:
    description = "Detects LNK files used by North Korean APT Kimsuky"
    Reference = "https://www.rapid7.com/globalassets/_pdfs/whitepaperguide/rapid7-Kimsukys-Phishing-and-Payload-Tactics_wp.pdf"
    Filehash1 = "d1f1019fb0f0810a8633bd0ef5a0d7b68ec94c5f09251eccd3e5076c97984377"
    Filehash2 = "e936445935c4a636614f7113e4121695a5f3e4a6c137b7cdcceb6f629aa957c4"
    Filehash3 = "3065b8e4bb91b4229d1cea671e8959da8be2e7482067e1dd03519c882738045e"
    author = "@RustyNoob619"
    date = "2024-08-03"

  strings:
    $lnk = {4c	00	00	00	01	14	02	00}

    $hex = {54 00 79	00	70	00	65	00	3a	00	20	00	54	00	65	00	78	00 
          74 00	20	00	44	00	6f	00	63	00	75	00	6d	00	65	00   //Type: Text Document
          6e 00	74	00	0a	00	53	00	69	00	7a	00	65	00	3a	00  // Size: 5.23 KB
          20 00	35	00	2e	00	32	00	33	00	20	00	4b	00	42	00 //  Date modified: 01/02/2020 11:23
          0a 00	44	00	61	00	74	00	65	00	20	00	6d	00	6f	00
          64 00	69	00	66	00	69	00	65	00	64	00	3a	00	20	00
          30 00	31	00	2f	00	30	00	32	00	2f	00	32	00	30	00
          32 00	30	00	20	00	31	00	31	00	3a	00	32	00	33	00}
    
    $pwrshll = "/c powershell" wide

  condition:
    $lnk at 0
    and $hex
    and @pwrshll == @hex + 1156 // Large amount of space added before the actual command 
}  
tags: