Back to Intelligence

Kimsuky 'Operation GitPower' Evolves: AI-Generated Decoys, GitHub PAT C2, and LNK-Based PowerShell Loaders — OTX Detection Pack

SA
Security Arsenal Team
September 7, 2026
10 min read

Threat Summary

Live AlienVault OTX telemetry confirms that Kimsuky — the North Korea-nexus APT group tracked under aliases including Thallium, Velvet Chollima, and APT43 — has materially evolved its long-running Operation GitPower campaign. Between August 11–19, 2026, researchers collected thirteen distinct LNK variants disguised as financial statements, business contracts, and corporate documents, all employing a novel C2 channel: GitHub Personal Access Tokens (PATs) used to authenticate against legitimate GitHub repositories acting as dead-drop resolvers and command channels.

The most significant evolution is Kimsuky's adoption of an AI agent ('opencode') to mass-generate convincing decoy documents. This represents an operational inflection point: the actor can now produce localized, contextually appropriate lures at scale — finance-themed lures for banks, policy documents for government ministries — without human authoring bottlenecks. Combined with obfuscated PowerShell loaders delivered through custom decoders and dedicated anti-analysis routines, this campaign demonstrates a deliberate investment in evading both signature-based and behavioral detection.

Targeting: Finance and Government sectors (consistent with Kimsuky's historic mandate of espionage against South Korean, Japanese, and Western foreign-policy and financial entities).

Objective: Long-dwell cyber espionage — initial access via weaponized LNK, staged PowerShell payload delivery, and resilient C2 riding on trusted GitHub infrastructure to blend with legitimate developer traffic.

Threat Actor / Malware Profile

Adversary: Kimsuky (APT43 / Thallium)

Kimsuky is a DPRK state-sponsored group active since at least 2012, primarily tasked with intelligence collection supporting North Korean strategic interests. The group is known for spearphishing excellence, extensive use of script-based loaders (PowerShell, VBScript, HTA), and abuse of legitimate cloud services (Google Drive, OneDrive, GitHub) for C2 and staging.

Attack Chain — Operation GitPower (2026 Evolution)

StageBehavior
DeliverySpearphishing emails carrying ZIP/compressed attachments containing weaponized .lnk files themed as financial and business documents
Decoy GenerationAI agent 'opencode' used to programmatically generate convincing decoy documents, improving lure credibility and campaign throughput
ExecutionLNK shortcut invokes powershell.exe (typically with -enc, -w hidden, or abbreviated flags) to execute embedded or staged commands
DecodingObfuscated PowerShell loaders deobfuscated at runtime via custom decoder routines (character substitution, base64 layering, string concatenation)
C2GitHub Personal Access Tokens (PATs) authenticate against attacker-controlled GitHub repositories; issue comments, gist content, or raw file blobs serve as command channels and payload staging
Anti-AnalysisNew routines observed in August 2026 samples: sandbox/debugger checks, analysis-environment detection, delayed execution, and conditional payload decryption

Why GitHub PAT C2 Matters

Using PATs over api.github.com provides three operational advantages to the actor:

  1. Reputation laundering — GitHub is whitelisted in nearly every enterprise egress policy, especially in finance and government organizations with developer populations.
  2. Encrypted, authenticated channel — all C2 rides TLS to a trusted domain; token-based auth prevents casual inspection of the malicious repositories.
  3. Rapid infrastructure rotation — PATs and repos can be burned and replaced in minutes with zero hosting cost.

Detection implication: network-layer blocking of github.com is not viable. Detection must pivot to behavioral signals — Office/LNK child processes spawning PowerShell, PowerShell reaching GitHub API endpoints, and token-authenticated API patterns.

IOC Analysis

The OTX pulse publishes 17 indicators, dominated by file hashes:

  • 1× SHA-256 (f1bd58...fe91091) — likely a primary LNK sample or loader; the highest-fidelity pivot for retro-hunting in EDR telemetry and malware sandboxes.
  • 6× MD5 hashes — variant LNK files and loader components from the August 11–19 collection window. MD5s are brittle (single-byte changes break them) but excellent for confirming known-bad samples in email gateways, download caches, and quarantine stores.

Notably absent: network IOCs (IPs/domains). This is consistent with the campaign's C2 design — traffic goes to api.github.com / raw.githubusercontent.com, so traditional network blocklisting yields nothing. SOC teams must instead:

  1. Ingest hashes into EDR blocklists and retro-hunt across email attachment stores, browser download directories, and %TEMP% / %APPDATA% write events.
  2. Hunt behaviorally for the GitHub-PAT C2 pattern: non-browser processes (powershell.exe, cmd.exe, wscript.exe) establishing TLS sessions to api.github.com or raw.githubusercontent.com.
  3. Detonate the hashes in a sandbox (ANY.RUN, Hybrid Analysis, Joe Sandbox) to extract the GitHub account/repo names and PAT strings, which become far more durable pivots than the file hashes themselves.
  4. Coordinate with GitHub Trust & Safety to suspend identified PATs and repositories, severing C2.

Detection Engineering

YAML
---
title: Kimsuky Operation GitPower - Malicious LNK Spawning PowerShell Loader
id: 9c2a1f44-7b3e-4d51-9a01-6f2b8c4d5e10
status: experimental
description: Detects LNK-driven execution chains consistent with Kimsuky Operation GitPower where a shortcut file launches hidden or encoded PowerShell loaders
author: Security Arsenal Threat Intelligence
references:
  - https://www.genians.co.kr/blog/threat_intelligence/ai-agent-opencode
  - https://otx.alienvault.com/pulse/
date: 2026/09/08
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|endswith:
      - '\explorer.exe'
      - '\cmd.exe'
      - '\msedge.exe'
      - '\chrome.exe'
      - '\OUTLOOK.EXE'
  selection_image:
    Image|endswith:
      - '\powershell.exe'
      - '\pwsh.exe'
  selection_flags:
    CommandLine|contains:
      - ' -enc '
      - ' -e '
      - ' -w hidden'
      - ' -WindowStyle Hidden'
      - 'FromBase64String'
      - 'IEX'
      - 'DownloadString'
  condition: selection_parent and selection_image and 1 of selection_flags
falsepositives:
  - Administrative scripts launched manually via shortcuts
level: high
tags:
  - attack.execution
  - attack.t1059.001
  - attack.t1204.002
---
title: Kimsuky Operation GitPower - Non-Browser Process Contacting GitHub API (PAT-Based C2)
id: 3e7b9d12-5c4a-4f68-8b22-1a9c0d6e7f31
status: experimental
description: Detects script interpreters and LOLBins establishing connections to GitHub API/raw endpoints, consistent with Kimsuky's GitHub PAT-based C2 channel
author: Security Arsenal Threat Intelligence
references:
  - https://www.genians.co.kr/blog/threat_intelligence/ai-agent-opencode
date: 2026/09/08
logsource:
  category: network_connection
  product: windows
detection:
  selection_process:
    Image|endswith:
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\cmd.exe'
      - '\wscript.exe'
      - '\cscript.exe'
      - '\mshta.exe'
      - '\rundll32.exe'
      - '\curl.exe'
      - '\wget.exe'
  selection_domain:
    DestinationHostname|contains:
      - 'api.github.com'
      - 'raw.githubusercontent.com'
      - 'gist.github.com'
      - 'objects.githubusercontent.com'
  condition: selection_process and selection_domain
falsepositives:
  - Developer tooling, package managers, and CI agents on engineering workstations - baseline per host role
level: high
tags:
  - attack.command_and_control
  - attack.t1102
  - attack.t1071.001
---
title: Kimsuky Operation GitPower - Encoded or Obfuscated PowerShell with Custom Decoder Patterns
id: 7f1d5a83-2e9b-4c74-b133-8d4e6f0a2c59
status: experimental
description: Detects obfuscated PowerShell command lines containing string-manipulation and decoding routines matching Kimsuky custom decoder behavior, including anti-analysis sleep/delay patterns
author: Security Arsenal Threat Intelligence
references:
  - https://www.genians.co.kr/blog/threat_intelligence/ai-agent-opencode
date: 2026/09/08
logsource:
  category: process_creation
  product: windows
detection:
  selection_image:
    Image|endswith:
      - '\powershell.exe'
      - '\pwsh.exe'
  selection_obfuscation:
    CommandLine|contains:
      - '-replace'
      - '[char]'
      - 'Join-String'
      - '-join'
      - 'Reverse'
      - 'Start-Sleep'
      - 'FromBase64String'
      - '.Substring('
      - 'GetEnumerator'
  condition: selection_image and 2 of selection_obfuscation
falsepositives:
  - Legitimate administrative one-liners with string manipulation; tune per environment
level: medium
tags:
  - attack.defense_evasion
  - attack.t1027
  - attack.t1059.001
KQL — Microsoft Sentinel / Defender
// Kimsuky Operation GitPower Hunt: LNK-launched PowerShell + GitHub PAT C2
// Microsoft Sentinel / Microsoft 365 Defender
let ioc_hashes = dynamic([
  "f1bd5817678f498966f033f61b617dee5c8e81191901fea7c4a89146bfe91091",
  "10780939962b54addc9d31f57d80edfc",
  "1523a2fcc901965ab4568d9fe829e4af",
  "500e0bc0d7579fb338912770964076fe",
  "685bfc6b2c29fbc16cfad908894add55",
  "7a53089053b1381742856a5cf2b95f8b",
  "8db2f20b719dcb7029d6296505622093",
  "900e832c10d851bbdef3fb191a15db0e"
]);
let github_c2 = dynamic(["api.github.com", "raw.githubusercontent.com", "gist.github.com", "objects.githubusercontent.com"]);
// Part 1: Known-bad hash sightings in file events
let HashHits =
  DeviceFileEvents
  | where TimeGenerated > ago(14d)
  | where SHA256 in~ (ioc_hashes) or MD5 in~ (ioc_hashes)
  | project TimeGenerated, DeviceName, FileName, FolderPath, SHA256, MD5, InitiatingProcessFileName;
// Part 2: LNK-triggered PowerShell with obfuscation flags
let LnkChains =
  DeviceProcessEvents
  | where TimeGenerated > ago(14d)
  | where FileName in~ ("powershell.exe", "pwsh.exe")
  | where InitiatingProcessCommandLine has_any (".lnk")
     or ProcessCommandLine has_any (" -enc ", "FromBase64String", " -w hidden", "WindowStyle Hidden", "IEX")
  | project TimeGenerated, DeviceName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, AccountName;
// Part 3: Non-browser processes talking to GitHub API (PAT C2 behavior)
let GithubC2 =
  DeviceNetworkEvents
  | where TimeGenerated > ago(14d)
  | where RemoteUrl has_any (github_c2)
  | where InitiatingProcessFileName in~ ("powershell.exe","pwsh.exe","cmd.exe","wscript.exe","cscript.exe","mshta.exe","rundll32.exe","curl.exe","wget.exe")
  | project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteUrl, RemoteIP, RemotePort;
HashHits
| union LnkChains, GithubC2
| sort by TimeGenerated desc
PowerShell
# Kimsuky Operation GitPower - Endpoint IOC & Behavior Hunt
# Run elevated across endpoints (or via EDR Live Response / GPO scheduled task)
# Checks: known-bad hashes, suspicious LNK files, encoded PowerShell artifacts, GitHub API connections

$ErrorActionPreference = 'SilentlyContinue'
$report = @()

$badMD5 = @(
  '10780939962b54addc9d31f57d80edfc','1523a2fcc901965ab4568d9fe829e4af',
  '500e0bc0d7579fb338912770964076fe','685bfc6b2c29fbc16cfad908894add55',
  '7a53089053b1381742856a5cf2b95f8b','8db2f20b719dcb7029d6296505622093',
  '900e832c10d851bbdef3fb191a15db0e'
)
$badSHA256 = @('f1bd5817678f498966f033f61b617dee5c8e81191901fea7c4a89146bfe91091')

Write-Host "[1] Hash sweep of user-writable directories..."
$searchPaths = @("$env:TEMP","$env:APPDATA","$env:LOCALAPPDATA","$env:USERPROFILE\Downloads","$env:USERPROFILE\Desktop","C:\ProgramData")
foreach ($p in $searchPaths) {
  Get-ChildItem -Path $p -Recurse -File -Include *.lnk,*.ps1,*.zip -ErrorAction SilentlyContinue | ForEach-Object {
    $m = (Get-FileHash $_.FullName -Algorithm MD5).Hash.ToLower()
    $s = (Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLower()
    if ($badMD5 -contains $m -or $badSHA256 -contains $s) {
      $report += [PSCustomObject]@{Check='HashMatch'; Path=$_.FullName; MD5=$m; SHA256=$s; Detail='KNOWN KIMSUKY IOC'}
    }
  }
}

Write-Host "[2] Scanning .lnk files for PowerShell targets..."
$wsh = New-Object -ComObject WScript.Shell
foreach ($p in $searchPaths) {
  Get-ChildItem -Path $p -Recurse -Filter *.lnk -ErrorAction SilentlyContinue | ForEach-Object {
    $sc = $wsh.CreateShortcut($_.FullName)
    if ($sc.TargetPath -match 'powershell|pwsh|mshta|wscript' -or $sc.Arguments -match '-enc|FromBase64String|IEX|hidden') {
      $report += [PSCustomObject]@{Check='SuspiciousLNK'; Path=$_.FullName; MD5=''; SHA256=''; Detail="Target=$($sc.TargetPath) Args=$($sc.Arguments)"}
    }
  }
}

Write-Host "[3] Checking active connections to GitHub API endpoints..."
$conns = Get-NetTCPConnection -State Established | Where-Object { $_.RemotePort -eq 443 }
foreach ($c in $conns) {
  $proc = Get-Process -Id $c.OwningProcess -ErrorAction SilentlyContinue
  if ($proc.ProcessName -match 'powershell|pwsh|cmd|wscript|cscript|mshta|rundll32|curl|wget') {
    try {
      $dns = (Resolve-DnsName $c.RemoteAddress -ErrorAction Stop).NameHost
    } catch { $dns = '' }
    if ($dns -match 'github|githubusercontent' -or $c.RemoteAddress -match '^140\.82\.|^185\.199\.') {
      $report += [PSCustomObject]@{Check='GithubC2'; Path=$proc.Path; MD5=''; SHA256=''; Detail="$($proc.ProcessName) -> $($c.RemoteAddress):443 ($dns)"}
    }
  }
}

Write-Host "[4] Checking PowerShell history for obfuscation artifacts..."
Get-ChildItem "$env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine" -Filter *.txt -Recurse | ForEach-Object {
  $hits = Select-String -Path $_.FullName -Pattern '-enc |FromBase64String|Start-Sleep|-replace|\[char\]' -AllMatches
  if ($hits) { $report += [PSCustomObject]@{Check='PSHistory'; Path=$_.FullName; MD5=''; SHA256=''; Detail="$(($hits | Measure-Object).Count) suspicious lines"} }
}

Write-Host "`n===== KIMSUKY GITPOWER HUNT RESULTS ====="
if ($report.Count -eq 0) { Write-Host "No indicators found on $env:COMPUTERNAME" }
else { $report | Format-Table -AutoSize; $report | Export-Csv ".\kimsuky_hunt_$env:COMPUTERNAME.csv" -NoTypeInformation }

Response Priorities

Immediate (0–4 hours)

  • Ingest all 17 IOC hashes into EDR blocklists, email gateway attachment filtering, and web proxy download inspection. Retro-hunt 30 days of file-creation telemetry for the SHA-256 and MD5 values.
  • Deploy the Sigma rules above to your SIEM; prioritize alerting on script interpreters connecting to api.github.com / raw.githubusercontent.com.
  • Block .lnk attachments at the email perimeter for Finance and Government business units; quarantine ZIP archives containing shortcut files.
  • Sweep user Download/Desktop/Temp directories using the PowerShell hunt script on any host that received finance-themed email attachments in the August–September 2026 window.

24 Hours

  • Credential exposure assessment: Kimsuky operations routinely pair initial access with credential harvesting and session-token theft. Force password resets and revoke active sessions for any user whose host tripped a hunt rule; prioritize privileged and finance-operations accounts.
  • Audit GitHub API egress: review proxy/ZTNA logs for PAT-authenticated requests (Authorization headers against api.github.com) from non-developer endpoints; extract repo/account names and submit takedown requests to GitHub Trust & Safety.
  • Detonate collected samples in an isolated sandbox to recover C2 repository names, PAT strings, and second-stage payloads; feed new indicators back into detection.
  • Review mailbox rules and OAuth grants on potentially compromised accounts — Kimsuky has historically abused inbox forwarding rules for persistent collection.

1 Week

  • Enforce LNK execution policy: use WDAC/AppLocker to block PowerShell child processes spawned from Explorer via .lnk execution, and enable PowerShell Script Block Logging + AMSI fleet-wide if not already present.
  • GitHub egress segmentation: route developer GitHub API traffic through an authenticated proxy and alert on GitHub API access from non-developer VLANs/device classes.
  • Decoy-resilience awareness training for Finance and Government staff — specifically addressing AI-generated, contextually accurate lure documents, which defeat legacy "spot the typo" heuristics.
  • Tabletop the PAT-C2 scenario: validate that IR runbooks cover legitimate-service C2 takedowns (GitHub/Drive/Gist) and that legal/comms paths for third-party abuse reports are pre-approved.

Related Resources

Security Arsenal Incident Response Managed SOC & MDR Services AlertMonitor Threat Detection From The Dark Side Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.