CanaryTokens: Reverse engineering .exe CanaryTokens to reveal the callback tripwire.
Introduction
Canarytokens are stealthy tripwires that call home to it’s hosting infrastructure when a protected asset is accessed. This post will walk through specifically how one of the most well known canary token provider (Thinkst) EXE‑wrapped tokens embed their trigger, how attackers or red teamers might extract and analyze it without firing the alert, and finally discuss how defenders could advance these tokens to strengthen their real world usability.
Background: EXE Canarytokens
To begin this investigation we will first need to create our target executable. This can be done with the following very basic powershell script.
Write-Host "Hello world!"
Then we will use the ‘ps2exe’ module to convert our powershell script (hello.ps1) into an exe file using this command:
Invoke-ps2exe .\hello.ps1 .\hello.exe
Once completed we can now upload our executable to Thinkst canary token site so it can transform the file into a canary token.
After entering our target email address and short title i.e. “fake financial program” we can now download the file to the system.
Now anytime this file is run directly or indirectly an alert will be triggered which will notify the owner (in this case me) that the file has been accessed.
Now we have our token setup and a basic overview of canary token functionality we can dive into extracting the callback and detection methods.
Dynamic analysis
The simplest method to find the callback domain is to simply execute the binary whilst having a network sniffer such as wireshark running simultaneously.
As shown in the screenshot above this captured the DNS query sent across the network to the callback domain.
-
uz5aaidu34...
– Unique token identifier -
.canarytokens.net
– Site hosting the canary tokens in this case
However, of course this will alert the canary owner that the file has been accessed so in real world usage wouldn’t be a great idea to go for. Yet, in our scenario this is purely testing so will be fine to trigger in order to show the process.
Static analysis
At first I thought the callback would be embedded into the executable code itself but this isn’t the case. Instead the tokens work by re‑signing the binary with a special certificate whose AIA/OCSP/CRL fields point at a unique *.canarytokens.com URL. When Windows validates the signature at runtime it fetches these URLs, alerting your canary console with no extra code required inside the .text section.
Extracting these certificates from the binary can be done in numerous different ways. Here I will focus on using one tool “certutil” that is built into windows for practicality. To run this we first navigate to the binarys directory and pass into the powershell interface:
certutil -dump hello.exe
// Write how this still causes canary to trigger
Silent static detection
There are several ways to view the certificates embedded into binaries, however this section will focus only on quiet methods that don’t require extra tooling to be installed. This is to make it more realistic to real world read teaming situations where staying undeteced is crucial.
The first static method that can be used is extracting the strings from the binary by using the following command:
strings hello.exe | grep "http"
As shown this returns any strings that contain http so we can filter out uneccessary strings. To further filter if this is a bigger file you could pass the suspected site name, word canary, or use regex to match token identifiers urls.
Similarly in windows environments the “findstr” command can be used to carry out this analysis without triggering the binary and/or requiring any extra tools (to decrease chances of being detected.
type hello.exe | findstr /i "http"
There are various other ways such as self built scripts, pe viewers, reverse engineering softwares (ghidra, ida etc.). However, the method above is the most logical way based on the real-world scenario of an attacker being in an environment. This is because it takes advantage of native OS commands rather than requiring extra dependencies, thus making it the most practical.
Countermeasures: Evading Static Detection
The first method possbile that doesn’t rely on modifying the actual canary token fundamentals itself, would be to build detections. These would focus on the previous static methods discussed against the known canary files. Utilizing the file name or file hash to check proccesses attempting to run “strings” or “findstr” against the binaries (canarytokens) would be a clear indicator that someone is attempting to unravel extra details.
As an example with KQL we could use the following query:
let MD5HashList = dynamic([]);
let SHA1HashList = dynamic([]);
let SHA256HashList = dynamic([]);
let Timescale = 90d;
let FileEvents = view() {
DeviceFileEvents
| where TimeGenerated >= ago(Timescale)
| where MD5 in (MD5HashList) or SHA1 in (SHA1HashList) or SHA256 in (SHA256HashList)
| where InitiatingProcessCommandLine in~("strings", "findstr", "grep")
| project TimeGenerated, ActionType, DeviceName, InitiatingProccessAccountName, InitiatingProccessAccountUpn, InitiatingProcessParentFileName, InitiatingProcessFileName, FileName, FolderPath
};
let ProcessEvents = view() {
DeviceProcessEvents
| where TimeGenerated >= ago(Timescale)
| where MD5 in (MD5HashList) or SHA1 in (SHA1HashList) or SHA256 in (SHA256HashList)
| where InitiatingProcessCommandLine in~("strings", "findstr", "grep")
| project TimeGenerated, ActionType, DeviceName, InitiatingProccessAccountName, InitiatingProccessAccountUpn, InitiatingProcessParentFileName, InitiatingProcessFileName, FileName, FolderPath
};
union withsource="SourceTable" isfuzzy=true
FileEvents
ProcessEvents
Outside of detection rules, another approach is to modify the core structure of canary tokens.
One way of doing this is to obfuscate the callback by splitting the url into multiple fragments stored in separate certificate fields, unused OIDs, or even benign-looking metadata strings. At runtime, the executable reassembles these fragments into the real URL before initiating the connection, meaning that offline scanners would not see the full address without understanding the reconstruction logic.
Conclusion
This blog has demonstrated how EXE Canarytokens work fundamentally by leveraging the Authenticode trust chain. Then covered red team interests such as static analysis to avoid being caught, and blue team for how advanced obfuscation could be employed to avoid unmasking. Ultimately, this writeup has showcased the evasion strategies—underscoring the cat‑and‑mouse nature of deception tooling.