Skip to content

Conversation

@tomsonpl
Copy link
Contributor

@tomsonpl tomsonpl commented Nov 20, 2025

LNK Files Artifact (Windows)

Windows LNK (shortcut) files are critical forensic artifacts for detecting persistence mechanisms, user activity tracking, and malware execution. Attackers frequently abuse LNK files placed in Startup folders to achieve persistence, or craft malicious shortcuts that execute LOLBins with obfuscated payloads.

Why Two Separate Queries?

This PR introduces two complementary LNK detection queries to address a known osquery limitation:

Query Approach Use Case
lnk_forensics_windows_elastic Metadata-based enumeration Comprehensive visibility into all LNK files with timestamps, hashes, locations
lnk_yara_detection_windows_elastic Content-based YARA scanning Detects malicious patterns directly in LNK binary content

The osquery shortcut_target_path Bug

During development, we discovered that osquery's shortcut_target_path field (and related shortcut metadata fields) always returns empty despite being documented as available since osquery 5.11.0. This affects:

  • shortcut_target_path
  • shortcut_target_type
  • shortcut_target_location
  • shortcut_start_in
  • shortcut_run
  • shortcut_comment

Issue filed: osquery/osquery#8725

Solution: Dual-Query Approach

  1. Forensics Query (lnk_forensics_windows_elastic): Provides comprehensive LNK file enumeration with location-based detection, file metadata, and hash enrichment. The shortcut-related ECS fields are mapped but may return empty until osquery fixes the underlying bug.

  2. YARA Query (lnk_yara_detection_windows_elastic): Bypasses the shortcut_target_path limitation entirely by scanning the raw LNK binary content with YARA rules. This provides immediate detection capability for malicious LNK patterns.


Core Forensic Artifacts Coverage

# Artifact OS Query File Description
1 LNK Files Windows lnk_forensics_windows_elastic a1b2c3d4 Comprehensive LNK enumeration with metadata
2 LNK Files Windows lnk_yara_detection_windows_elastic b2c3d4e5 YARA-based malicious pattern detection

Queries by Platform


🪟 Windows - LNK Forensics (Metadata-Based Enumeration)

Description

Comprehensive Windows LNK shortcut file forensics across all critical locations: user/system Startup folders (persistence), Desktop folders, Recent Items (user activity), Quick Launch, SendTo menu, and Start Menu Programs. Enriched with hash values for LNK files themselves. Uses the users table to dynamically enumerate all user directories.

Detection Focus:

  • LNK files in persistence locations (Startup folders)
  • Risky executables (cmd.exe, powershell.exe, wscript.exe, rundll32.exe, mshta.exe, certutil.exe, bitsadmin.exe)
  • Suspicious command-line arguments (encoded commands, download cradles, UNC paths, hidden windows)
  • Large LNK files (>20KB) that may contain embedded payloads
  • HTTP/HTTPS URLs indicating remote payload retrieval

Locations Covered:

  • User Startup (%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup)
  • System Startup (C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup)
  • User/Public Desktop
  • Recent Items
  • Quick Launch
  • SendTo menu
  • Start Menu Programs

Known Limitation: shortcut_target_path and dependent fields may return empty due to osquery parsing issue. Use lnk_yara_detection_windows_elastic for content-based detection that bypasses this limitation.

Result:
Screenshot 2025-11-28 at 19 52 33

Platform

windows

Interval

3600 seconds (1 hour)

Query ID

lnk_forensics_windows_elastic

ECS Field Mappings

  • file.pathpath
  • file.namefilename
  • file.directorydirectory
  • file.sizesize
  • file.createdbtime
  • file.mtimemtime
  • file.accessedatime
  • file.ctimectime
  • file.typetype
  • file.hash.md5md5
  • file.hash.sha1sha1
  • file.hash.sha256sha256
  • file.extensionextension
  • file.code_signature.subject_nameauthenticode_subject
  • file.code_signature.issuerauthenticode_issuer
  • file.code_signature.statusauthenticode_result
  • process.executableshortcut_target_path (may be empty)
  • process.command_linecombined_command (may be empty)
  • user.idshellbags_sid (may be empty)
  • registry.pathshellbags_source (may be empty)

MITRE ATT&CK Coverage

  • T1547.001 - Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder
  • T1204.002 - User Execution: Malicious File
  • T1021 - Remote Services (Lateral Movement)
  • T1059.001 - Command and Scripting Interpreter: PowerShell
  • T1059.003 - Command and Scripting Interpreter: Windows Command Shell
  • T1105 - Ingress Tool Transfer

SQL Query

-- Windows LNK Shortcut File Forensics with Suspicious Pattern Detection + Shellbags Enrichment
-- Source: file table with native Windows shortcut parsing + shellbags registry data + authenticode signatures
-- Focus: Risky executables, malicious arguments, large files, persistence mechanisms
-- Scope: Comprehensive coverage of forensically significant LNK locations (startup, desktop, recent, quick launch, sendto, start menu)
-- Related: Use lnk_yara_detection_windows_elastic for content-based YARA scanning of LNK binary patterns
-- Note: shortcut_target_path may return empty due to osquery parsing issue; YARA query bypasses this limitation

WITH user_lnk_paths AS (
    -- Per-user LNK locations
    SELECT
        u.username,
        u.directory || '\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup' AS user_startup,
        u.directory || '\Desktop' AS user_desktop,
        u.directory || '\AppData\Roaming\Microsoft\Windows\Recent' AS user_recent,
        u.directory || '\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch' AS user_quicklaunch,
        u.directory || '\AppData\Roaming\Microsoft\Windows\SendTo' AS user_sendto,
        u.directory || '\AppData\Roaming\Microsoft\Windows\Start Menu\Programs' AS user_startmenu
    FROM users u
    WHERE u.directory LIKE 'C:\Users\%'
      AND u.username NOT IN ('Default', 'Default User', 'Public', 'All Users')
),
lnk_files AS (
    -- User Startup folders (highest priority - persistence)
    SELECT f.*, 'user_startup' AS location_type
    FROM user_lnk_paths p
    CROSS JOIN file f
    WHERE f.directory = p.user_startup AND f.filename LIKE '%.lnk'

    UNION ALL

    -- System-wide Startup folder (persistence)
    SELECT f.*, 'system_startup' AS location_type
    FROM file f
    WHERE f.directory = 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup'
      AND f.filename LIKE '%.lnk'

    UNION ALL

    -- User Desktop folders
    SELECT f.*, 'user_desktop' AS location_type
    FROM user_lnk_paths p
    CROSS JOIN file f
    WHERE f.directory = p.user_desktop AND f.filename LIKE '%.lnk'

    -- ... (additional locations: public_desktop, recent_items, quick_launch, sendto, user_startmenu, system_startmenu)
),
lnk_enriched AS (
    SELECT
        lnk.path, lnk.filename, lnk.directory, lnk.size,
        lnk.btime, lnk.mtime, lnk.atime, lnk.ctime, lnk.type,
        lnk.shortcut_target_path, lnk.shortcut_target_type,
        lnk.shortcut_target_location, lnk.shortcut_start_in,
        lnk.shortcut_run, lnk.shortcut_comment, lnk.location_type,
        'lnk' AS extension,
        CASE
            WHEN lnk.shortcut_target_path IS NOT NULL AND lnk.shortcut_comment IS NOT NULL
            THEN lnk.shortcut_target_path || ' ' || lnk.shortcut_comment
            WHEN lnk.shortcut_target_path IS NOT NULL THEN lnk.shortcut_target_path
            ELSE lnk.shortcut_comment
        END AS combined_command
    FROM lnk_files lnk
)
SELECT
    lnk.*, h.md5, h.sha1, h.sha256,
    a.subject_name AS authenticode_subject,
    a.issuer_name AS authenticode_issuer,
    a.result AS authenticode_result,
    sb.sid AS shellbags_sid, sb.source AS shellbags_source,
    -- Detection flags
    CASE WHEN lnk.size > 20000 THEN 1 ELSE 0 END AS large_size_flag,
    CASE WHEN lnk.location_type IN ('user_startup', 'system_startup') THEN 1 ELSE 0 END AS startup_persistence_flag,
    -- Additional risky_executable_flag, suspicious_arguments_flag, http_download_flag, unc_path_flag
FROM lnk_enriched lnk
LEFT JOIN hash h ON lnk.path = h.path
LEFT JOIN authenticode a ON a.path = lnk.shortcut_target_path
LEFT JOIN shellbags sb ON sb.path = lnk.shortcut_start_in
WHERE (
    lnk.location_type IN ('user_startup', 'system_startup')
    OR lnk.size > 20000
    OR lnk.shortcut_target_path LIKE '%\cmd.exe'
    OR lnk.shortcut_target_path LIKE '%\powershell.exe'
    -- ... (additional suspicious pattern filters)
)
AND lnk.filename NOT IN ('Excel.lnk', 'Word.lnk', 'Microsoft Edge.lnk', ...)
ORDER BY
    CASE WHEN lnk.location_type IN ('user_startup', 'system_startup') THEN 1 ELSE 2 END,
    lnk.mtime DESC;

🪟 Windows - LNK YARA Detection (Content-Based Scanning)

Description

YARA-based content detection of suspicious Windows LNK shortcut files. Scans LNK binary content directly for malicious patterns, bypassing osquery's shortcut_target_path parsing issues. Returns only files matching suspicious patterns.

Detection Focus:

  • LOLBins embedded in LNK files (powershell, cmd, wscript, mshta, rundll32, certutil, bitsadmin)
  • Encoded commands (-enc, -e flags)
  • Hidden execution (-W Hidden, ExecutionPolicy Bypass)
  • Download cradles (DownloadString, Invoke-WebRequest, Invoke-Expression)
  • Network indicators (HTTP/HTTPS URLs)

Technical Notes:

  • YARA table requires JOIN pattern (not IN subquery) for path constraints
  • Hash enrichment uses scalar subqueries (LEFT JOIN breaks YARA constraints)
  • Provides immediate detection capability despite osquery shortcut parsing bug

Result:
Screenshot 2025-11-28 at 19 49 03

Platform

windows

Interval

3600 seconds (1 hour)

Query ID

lnk_yara_detection_windows_elastic

ECS Field Mappings

  • file.pathpath
  • rule.namematches
  • threat.indicator.matched.atomicstrings
  • file.hash.md5md5
  • file.hash.sha256sha256
  • threat.indicator.type"file" (static value)
  • event.category"malware" (static value)
  • event.type"indicator" (static value)
  • file.directorylocation_type

MITRE ATT&CK Coverage

  • T1547.001 - Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder
  • T1204.002 - User Execution: Malicious File
  • T1059.001 - Command and Scripting Interpreter: PowerShell
  • T1059.003 - Command and Scripting Interpreter: Windows Command Shell
  • T1027 - Obfuscated Files or Information
  • T1105 - Ingress Tool Transfer

SQL Query

-- YARA-based LNK Suspicious Pattern Detection
-- Source: yara table with inline signature rule scanning LNK binary content
-- Purpose: Content-based detection of malicious LNK files (complements lnk_forensics_windows_elastic)
-- Note: For comprehensive LNK enumeration with metadata, use lnk_forensics_windows_elastic query
-- Technical: YARA table requires JOIN (not IN subquery); hash uses scalar subqueries

WITH lnk_paths AS (
    -- User-specific Startup and Desktop folders
    SELECT f.path
    FROM users u
    CROSS JOIN file f
    WHERE (
        f.directory = u.directory || '\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup'
        OR f.directory = u.directory || '\Desktop'
    )
    AND u.directory LIKE 'C:\Users\%'
    AND u.username NOT IN ('Default', 'Default User', 'Public', 'All Users')
    AND f.filename LIKE '%.lnk'

    UNION ALL

    -- System-wide Startup folder (persistence)
    SELECT f.path
    FROM file f
    WHERE f.directory = 'C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup'
    AND f.filename LIKE '%.lnk'

    UNION ALL

    -- Public Desktop
    SELECT f.path
    FROM file f
    WHERE f.directory = 'C:\Users\Public\Desktop'
    AND f.filename LIKE '%.lnk'
)
SELECT
    y.path,
    y.matches,
    y.strings,
    -- Hash enrichment via scalar subqueries (JOIN breaks YARA constraints)
    (SELECT md5 FROM hash WHERE path = y.path) AS md5,
    (SELECT sha256 FROM hash WHERE path = y.path) AS sha256,
    CASE
        WHEN y.path LIKE '%Startup%' THEN 'startup'
        WHEN y.path LIKE '%Desktop%' THEN 'desktop'
        ELSE 'other'
    END AS location_type
FROM lnk_paths lp
-- JOIN required for YARA path constraint (IN subquery doesn't push constraints)
JOIN yara y ON y.path = lp.path
WHERE y.sigrule = 'rule Suspicious_LNK {
    strings:
        // LOLBins - Living Off The Land Binaries
        $ps = "powershell" nocase
        $cmd = "cmd.exe" nocase
        $ws = "wscript" nocase
        $cs = "cscript" nocase
        $mshta = "mshta" nocase
        $rundll = "rundll32" nocase
        $certutil = "certutil" nocase
        $bitsadmin = "bitsadmin" nocase
        // Encoded/Hidden execution
        $enc = "-enc" nocase
        $hidden = "-W Hidden" nocase
        $bypass = "ExecutionPolicy Bypass" nocase
        // Download cradles
        $dl = "DownloadString" nocase
        $iwr = "Invoke-WebRequest" nocase
        $iex = "Invoke-Expression" nocase
        // Network indicators
        $http = "http://" nocase
        $https = "https://" nocase
    condition:
        any of them
}'
AND y.matches IS NOT NULL
AND y.matches != ''
ORDER BY
    -- Priority: Startup locations first (persistence)
    CASE WHEN y.path LIKE '%Startup%' THEN 1 ELSE 2 END;

Testing Results

Both queries were validated on Windows 10/11 with test LNK files:

Test File Location Forensics Query YARA Query Notes
SuspiciousUpdate.lnk User Startup Startup location triggers forensics
CertUpdate.lnk User Startup Startup location triggers forensics
SystemUpdate.lnk System Startup Startup location triggers forensics
FakeInstaller.lnk Desktop cmd.exe detected by YARA only
LargeArgs.lnk Desktop cmd.exe detected by YARA only
RemoteApp.lnk Desktop mshta detected by YARA only
MyNotes.lnk Desktop Legitimate, no patterns
Microsoft Edge.lnk Public Desktop Legitimate, excluded

Related Links


This PR was AI assisted with Claude Code

@tomsonpl tomsonpl marked this pull request as ready for review November 20, 2025 11:22
@tomsonpl tomsonpl requested a review from a team as a code owner November 20, 2025 11:22
@tomsonpl tomsonpl requested review from joeypoon and pzl and removed request for a team November 20, 2025 11:22
@elasticmachine
Copy link

💚 Build Succeeded

@andrewkroh andrewkroh added Integration:osquery_manager Osquery Manager documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. labels Nov 20, 2025
@tomsonpl tomsonpl changed the title lnk artifact [Osquery_manager] LNK artifacts saved query Nov 20, 2025
@andrewkroh andrewkroh added the Team:Defend Workflows Security team for Endpoint and OSQuery workflows [elastic/security-defend-workflows] label Nov 25, 2025
@raqueltabuyo
Copy link

Verify if the folders for LNK files are only startup or Desktop, I believe you can store LNK files anywhere.

@tomsonpl
Copy link
Contributor Author

I think there's a limitation or a BUG in osquery itself, created an issue: osquery/osquery#8725 let's see what they say :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation. Applied to PRs that modify *.md files. Integration:osquery_manager Osquery Manager Team:Defend Workflows Security team for Endpoint and OSQuery workflows [elastic/security-defend-workflows]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants