NanoCore: Clipboard Capture — Detection

NanoCore Image

NanoCore inserts itself into the clipboard viewer chain with SetClipboardViewer, so Windows notifies it on every copy. It forwards the message down the chain afterwards, so clipboard behaviour looks completely normal to the user.

MITRE ATT&CK: T1115

Technique write-up: NanoCore_ClipboardLogging

Detection Indicators

Indicator Value
Log path KB_<Environment.TickCount>.dat — under C:\Users\Public\ in this build, configuration-dependent
Naming literal KB_ prefix, decimal tick count, .dat extension
Location any user-writable staging directory — Public, %APPDATA%, %TEMP%, ProgramData
Window hidden — the form is minimised and Visible forced to false on every change
API user32!SetClipboardViewer
Message WM_DRAWCLIPBOARD (0x0308), with WM_CHANGECBCHAIN (0x030D) forwarded on
Capture limit text truncated at 128,000 characters
Window minimised and hidden, so the viewer is invisible in the UI

The KB_<ticks>.dat name is shared by all three NanoCore collection TTPs, so one broadened file rule covers keystrokes, clipboard and DNS — but see the caveat below before weighting it.

⚠️ The output path is not a reliable indicator on its own. The recreated test case hardcodes C:\Users\Public\KB_<TickCount>.dat, but where NanoCore stages collected data is configuration-dependent — %APPDATA% is at least as common in the wild, and the naming convention changes between builds. The file rule below is deliberately broadened across every plausible staging directory, and it is supporting evidence. The API-level rules are what actually identify the technique.

Log Sources

Detection Engineering with Defender XDR

Same log artefact as the other two collectors.

// Supporting evidence, not proof - see the caveat above.
let staging = dynamic([@"\users\public\", @"\appdata\roaming\", @"\appdata\local\",
                       @"\programdata\", @"\windows\temp\"]);
DeviceFileEvents
| where tolower(FolderPath) has_any (staging)
| where FileName matches regex @"^KB_[0-9]+\.dat$"
      or (FileName endswith ".dat" and tolower(InitiatingProcessFolderPath) has_any (staging))
| project Timestamp, DeviceName, AccountName, ActionType, FileName, FolderPath,
          InitiatingProcessFileName, InitiatingProcessFolderPath, InitiatingProcessCommandLine
| order by Timestamp desc

Detection Engineering with Sysmon

Sysmon file-create on the same path, with the writing image.

WindowsEvent //(sysmon)
| where EventID == 11   // FileCreate
| extend TargetFilename = tostring(EventData.TargetFilename), Image = tostring(EventData.Image)
| where TargetFilename has_any (@"\Users\Public\", @"\AppData\", @"\ProgramData\")
| where TargetFilename endswith ".dat" or TargetFilename endswith ".log"
| where Image has_any (@"\AppData\", @"\Temp\", @"\Users\Public\")
| project TimeGenerated, Computer, Image, TargetFilename

Detection Engineering with SIGMA

Full rule: sigma_nanocore_collector_staging_file.yml — one file shared by all three collectors, kept with the keylogger so the rule has a single id

detection:
    selection_name:
        TargetFilename|re: '(?i)\\KB_[0-9]+\.dat$'
    selection_location:
        TargetFilename|contains:
            - '\Users\Public\'
            - '\AppData\Roaming\'
            - '\AppData\Local\'
            - '\ProgramData\'
    condition: all of selection_*

Detection Engineering with YARA

Rule: nanocore_clipboard_viewer.yar

$legacy1 = "SetClipboardViewer"   $legacy2 = "ChangeClipboardChain"
$modern  = "AddClipboardFormatListener"
$read1   = "GetClipboardData"     $read2 = "Clipboard.GetText"

The rule covers both the legacy viewer chain this sample uses and the modern AddClipboardFormatListener API, since a rebuild would likely move to the latter.

Notes and tuning

SetClipboardViewer produces no event either, and because the sample passes messages down the chain there is no functional side effect a user would notice.

The strongest additional signal is behavioural: a process that both reads the clipboard and writes to disk shortly after, with no window. Defender’s DeviceEvents surfaces some clipboard access under ClipboardCopy-style action types depending on sensor version — check what your tenant emits before relying on it.

Credential managers are the main benign clipboard-chain participant; baseline those first.

Disclaimer

For educational purposes only!!!