T1614.001

System Language Discovery

Adversaries may attempt to gather information about the system language of a victim in order to infer the geographical location of that host. This information is commonly used by ransomware families and targeted malware to implement geofencing logic — avoiding infection of systems in CIS or Eastern European countries to reduce law enforcement scrutiny. Real-world examples include Ryuk querying HKLM\SYSTEM\CurrentControlSet\Control\Nls\Language for values 0x419 (Russian), 0x422 (Ukrainian), or 0x423 (Belarusian) before aborting; DarkSide, Maze, Avaddon, and Cuba using GetKeyboardLayoutList or GetUserDefaultUILanguage API calls; IcedID executing cmd.exe /c chcp >&2 to retrieve the active code page; and Cuckoo Stealer checking the $LANG environment variable on macOS. Detection pivots to process creation events capturing these discovery commands, registry queries to NLS language keys, and scripting-layer invocations of locale APIs.

Microsoft Sentinel / Defender
kusto
// T1614.001 — System Language Discovery
// Detects language geofencing checks used by ransomware and targeted malware
// Covers: chcp, reg.exe NLS queries, PowerShell locale APIs, wmic locale, locale command
let SuspiciousParents = dynamic([
    "wscript.exe", "cscript.exe", "mshta.exe", "rundll32.exe",
    "regsvr32.exe", "msbuild.exe", "installutil.exe", "excel.exe",
    "winword.exe", "powerpnt.exe", "outlook.exe"
]);
// Pattern 1: chcp execution from suspicious script-interpreter or Office parent
// Matches IcedID: cmd.exe /c chcp >&2
let ChcpSuspicious = DeviceProcessEvents
| where Timestamp > ago(24h)
| where (FileName =~ "chcp.com") or
        (FileName =~ "cmd.exe" and ProcessCommandLine has "chcp" and ProcessCommandLine has ">&")
| where InitiatingProcessFileName has_any (SuspiciousParents)
       or (ProcessCommandLine has "chcp" and ProcessCommandLine has ">&2")
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
          InitiatingProcessFileName, InitiatingProcessCommandLine,
          InitiatingProcessParentFileName, InitiatingProcessId
| extend DetectionType = "ChcpCodePageCheck";
// Pattern 2: reg.exe querying NLS Language registry keys
// Matches Ryuk: HKLM\SYSTEM\CurrentControlSet\Control\Nls\Language
let RegNlsQuery = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName =~ "reg.exe"
| where ProcessCommandLine has_any (["Nls\\Language", "Nls\\Locale", "Nls\\CodePage",
                                      "InstallLanguage", "CurrentControlSet\\Control\\Nls"])
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
          InitiatingProcessFileName, InitiatingProcessCommandLine,
          InitiatingProcessParentFileName, InitiatingProcessId
| extend DetectionType = "RegistryNlsQuery";
// Pattern 3: PowerShell invoking language/locale discovery APIs or registry paths
// Matches: DarkSide, Maze, Cuba PowerShell dropper stages
let PsLangApi = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName in~ ("powershell.exe", "pwsh.exe")
| where ProcessCommandLine has_any ([
    "GetUserDefaultUILanguage",
    "GetSystemDefaultUILanguage",
    "GetKeyboardLayoutList",
    "GetUserDefaultLangID",
    "InstalledUICulture",
    "CurrentUICulture",
    "Get-WinSystemLocale",
    "Get-Culture",
    "Nls\\Language",
    "OSLanguage",
    "[System.Globalization.CultureInfo]",
    "Win32_OperatingSystem"
  ])
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
          InitiatingProcessFileName, InitiatingProcessCommandLine,
          InitiatingProcessParentFileName, InitiatingProcessId
| extend DetectionType = "PowerShellLangAPI";
// Pattern 4: WMIC querying OS locale or language properties
let WmicLang = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName =~ "wmic.exe"
| where ProcessCommandLine has "os" and
        ProcessCommandLine has_any (["Locale", "OSLanguage", "CodeSet", "CountryCode"])
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
          InitiatingProcessFileName, InitiatingProcessCommandLine,
          InitiatingProcessParentFileName, InitiatingProcessId
| extend DetectionType = "WmicLocaleQuery";
// Pattern 5: locale command on Linux endpoints (MDE for Linux / Defender for Endpoint)
let LocaleCmd = DeviceProcessEvents
| where Timestamp > ago(24h)
| where FileName =~ "locale" and FolderPath has_any ("/usr/bin", "/bin")
| where InitiatingProcessFileName in~ ("bash", "sh", "zsh", "python3", "python", "perl", "ruby")
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
          InitiatingProcessFileName, InitiatingProcessCommandLine,
          InitiatingProcessParentFileName, InitiatingProcessId
| extend DetectionType = "LinuxLocaleCommand";
union ChcpSuspicious, RegNlsQuery, PsLangApi, WmicLang, LocaleCmd
| sort by Timestamp desc
medium severity medium confidence

Data Sources

Process: Process Creation Command: Command Execution Microsoft Defender for Endpoint

Required Tables

DeviceProcessEvents

False Positives

  • Software installers legitimately checking system locale to present appropriate language packs or regional configuration options during setup
  • Internationalization (i18n) testing tools and localization verification scripts querying language settings as part of their normal function
  • IT diagnostics, asset management, and helpdesk scripts enumerating locale for inventory or troubleshooting regional configuration issues
  • chcp used in legitimate batch automation scripts for console encoding management, such as setting UTF-8 (codepage 65001) for correct output display
  • Monitoring and observability agents collecting system locale data as part of hardware/software inventory for CMDB or ITSM platforms

Unlock Pro Content

Get the full detection package for T1614.001 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections