Post

Kimsuky 5

Introduction

Kimsuky Kimsuky Waiting Period

Have you ever wondered how the APT evolve its tactics over time? Today, we embark on a new series exploring this question where we look at how the Kimsuky APT has developed over time by looking at the different TTP it employed in past and how it evolved.

The said sample we’re analysing today is not long back. We’re going to look into a sample from 2019 which employs a simple technique called “Masquerading” which gives a file two extensions. The file we have , has the name “베트남 녹지원 상춘재 행사 견적서.hwp .exe”. The HWP extension is nothing but Hangul Word Processor or think of it was Microsoft Word but for Korea.

On translating we find that the file name is “Vietnam Green Garden Sangchunjae Event Quotation Form.hwp .exe”. This sounds like a authentic document which was used in Social Engineering. On quick google search we can find that in 2019 the first lady of South Korea and Vietnamese PM met at Sangchunjae event. So it’s clear that it was used as social engineering attack through emails and the double extension was made to make it sound more authentic.

SE

Static Analysis

DIE

  • On opening the file in DiE we find that it’s a PE32 file written in Visual Studio 2012 and we have another PE file in the resources section. We can extract the PE file and begin our analysis on it. But before we do it let’s see how the original PE file loads it.
  • Let’s look at the file in the tool called Ghidra instead of our regular IDA (cuz why not xD). Ghidra tells us that there are delayed imports so this might help us later on. One quick tip in Ghidra is to make sure to always tick this column. This analyzer uses external Windows function call parameter information to populate comments next to pushed parameters. In some cases, data is labeled and commented as well.
Delayed ImportsGhidra Tip
DIPE

The main function calls a single function called FUN_00401000. On opening the function we see many Windows API being called. The function can be basically divied into two parts. The first part is used to drop the HWP and DLL file from resource section and the next part uses regsvr to install the DLL. Ghidra

The code uses many test operations to check if any of the API calls return 0 and exits if it’s so. We can manually patch these with nop instructions if we want to. Let’s see these Win Api calls individually and rename some of the variables to better understand the disassembly.

  • GetModuleFileNameA - Retrieves the fully qualified path for the file that contains the specified module. The module must have been loaded by the current process.
    1
    2
    3
    4
    5
    
    DWORD GetModuleFileNameA(
    [in, optional] HMODULE hModule,
    [out]          LPSTR   lpFilename,
    [in]           DWORD   nSize
    );
    
  • GetCurrentDirectory function - Retrieves the current directory for the current process.
    1
    2
    3
    4
    
    DWORD GetCurrentDirectory(
    [in]  DWORD  nBufferLength,
    [out] LPTSTR lpBuffer
    );s
    
  • FindExecutableA function - Retrieves the name of and handle to the executable (.exe) file associated with a specific document file.
    1
    2
    3
    4
    5
    
    HINSTANCE FindExecutableA(
    [in]           LPCSTR lpFile,
    [in, optional] LPCSTR lpDirectory,
    [out]          LPSTR  lpResult
    );
    
  • ShellExecuteA function - Performs an operation on a specified file.
    1
    2
    3
    4
    5
    6
    7
    8
    
    HINSTANCE ShellExecuteA(
    [in, optional] HWND   hwnd,
    [in, optional] LPCSTR lpOperation,
    [in]           LPCSTR lpFile,
    [in, optional] LPCSTR lpParameters,
    [in, optional] LPCSTR lpDirectory,
    [in]           INT    nShowCmd
    );
    

    Ghidra

We can match these parameters with the code and rename these variables. Since now we’ve the basic understaning of the working of the first part. Let’s move to the second part. Ghidra

Looking at the disassembly the do-while loop is nothing but a strcpy function that copies the string \Microsoft into the variable puVar9. You can convert the values into character and find the same as indicated by Ghidra. The file that is dropped is named as NewAct.dat but it’s actually a DLL and it is registered using regsvr32.

Dropped DLL

The dropped DLL file has 53/70 detections on Virustotal. The DLL is again compiled using Visual Studio 2012. It has 3 exports DllInstall, DllRegisterServer and checkdrive. Let’s run Capa and Floss on them to see what’s up with the sample Floss Floss Capa

As we can find that there are many WinApi calls and we can see the attack matrix and the capabilities of the sample. Let’s see the exports function of this DLL.

Export Functions

DLLInstall The DLLInstall function first removes all the “*.wsf” files from the current directory and then calls the other export function called “checkdrive”.

64Proc The “checkdrive” function in itself is a big function and the first thing it does is that it checks if the system is 64 bit or 32 bit using IsWow64Processs. If the process is not 64 bit it proceeds to call a function which injects the DLL into the explorer.exe .

DLL InjectionUsing LoadLibrary
DIPE

But what happens if the OS is actually 64 bit ? Then as we look below , the else part of the check is ran .

Download Lyric.datC2 URL
DIPE

If we dig deep into the calls of the function we can find the complete URL being called with User-Data etc. http[:]//antichrist.or.kr/data/cheditor/dir1/F.php

Other than this when the DLL is injected it tries to create mutexs and tries communicating with the C2 server for further instructions. The data that is downloaded is decoded using XOR. Some of the working are below. The C2 server as of now doesn’t have the files like the .wsf we saw earlier that were being used in the attack here.

"Mutex "Check"

Upon injection, the DLL initiates execution within the DllMain function. This entry point assesses the host process’s identity. If determined to be “explorer.exe”, the DLL proceeds to establish a mutex and spawns a thread for malicious operations. Conversely, if the process is neither “explorer.exe” nor “rundll32.exe”, the DLL recursively reinvokes itself via “rundll32.exe” to re-evaluate the environment. Should the host process be identified as “notepad.exe”, the DLL terminates its execution. It also maintains persistence by adding the AutoRun registry keys.

"Persist"

Conclusion

  • By appending the .exe extension to a seemingly innocuous .hwp file (a Hangul Word Processor document), they created a deceptive file that appeared to be a harmless document. This social engineering tactic is designed to trick users into opening the file, unknowingly executing the malicious code within.
  • The core of the attack involves DLL injection and establishing persistence. The malicious code injects a DLL into the explorer.exe process, which is a critical system process running in the background. This allows the attacker to gain control over this process and execute their malicious code.

To ensure continued operation even after a system reboot, the attackers create mutexes. A mutex is a synchronization object used to coordinate access to shared resources. In this case, the mutex acts as a flag to indicate whether the malicious code is already running. If the mutex doesn’t exist, the code proceeds to execute. If it does, the code assumes it’s already running and terminates.

IOC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
MD5
35d60d2723c649c97b414b3cb701df1c
SHA-1
9944ce9354fb8961826339770ffc118000058271
SHA-256
6dfce07abc39e5d6aebd74a1850ad65cc6ce10a8540b551c4f6d441ec4cf48ab 



 DOMAIN
    antichrist.or.kr 

IP
    114.207.244.99 

NewAct.dat
MD5
e54b370d96ca0e2ecc083c2d42f05210
SHA-1
03c35e4c6a641373db665e7d58cea421188fbc82
SHA-256
1050935f6acee3afda3876478718632b968c986eb9c59fc2e27599c1515515f5 

Virustotal

AnyRun

Triage

Thank You for reading this till the end ❤

Discord somedieyoungzz

Twitter https://twitter.com/IdaNotPro

This post is licensed under CC BY 4.0 by the author.