Description
Process and prioritize alerts generated by canary token activations. Each alert represents a specific file being opened, credential being used, or URL being accessed, providing precise intelligence about adversary activity and interests.
Rationale
Canary tokens generate highly specific alerts that tell you exactly what was accessed and from where. Processing these alerts effectively requires understanding the context of each token: where it was placed, what it was designed to detect, and what adversary behavior it indicates. This context transforms a raw alert into actionable intelligence.
Supporting Basis
Literature-informed designThe sources generate and deliver alerts from decoy access; the wider processing workflow is an author-defined operational record.
- Bowen, B.M. et al. Baiting Inside Attackers Using Decoy Documents. SecureComm 2009, 51–70.Peer reviewed
- Yuill, J.; Zappe, M.; Denning, D.; Feer, F. Honeyfiles: Deceptive Files for Intrusion Detection. IEEE SMC Information Assurance Workshop 2004, 116–122.Peer reviewed
These sources establish design lineage and scope. They do not validate this record's operational effectiveness, planning estimates, environment labels, or ATT&CK relationships.
Implementation Steps
Configure canary callback infrastructure
Set up and validate the callback mechanism for all deployed canary tokens. Ensure reliable delivery through firewalls and proxy servers.
Build alert enrichment pipeline
Enrich canary alerts with context from the token inventory: token type, placement location, intended detection purpose, and expected adversary behavior.
Define triage procedures
Create triage procedures for different canary alert types. A triggered AWS key token may require different response urgency than a triggered document token.
Integrate with incident management
Connect canary alert processing to incident management workflows so that verified alerts automatically create incidents with appropriate context.
Technical Implementation Examples(1)
Canary Token Callback Server
Flask-based callback server that processes canary token triggers and forwards alerts to SIEM
"""
Canary Token Callback Server.
Receives HTTP callbacks when canary tokens are triggered,
enriches with inventory context, and forwards to SIEM.
"""
from flask import Flask, request, Response
import json
import logging
from datetime import datetime
import requests
app = Flask(__name__)
# Load token inventory for enrichment
with open("canary_inventory.json") as f:
TOKEN_INVENTORY = {t["token_id"]: t for t in json.load(f)}
SIEM_WEBHOOK = "https://siem.shadow-mgmt.internal/api/webhook/canary"
# Structured logging
logging.basicConfig(
filename="/var/log/canary-server/alerts.json",
format="%(message)s",
level=logging.INFO,
)
@app.route("/t/<token_id>/<path:resource>", methods=["GET", "HEAD"])
def canary_callback(token_id, resource):
"""Handle canary token callback."""
# Enrich with inventory context
token_info = TOKEN_INVENTORY.get(token_id, {})
alert = {
"timestamp": datetime.utcnow().isoformat() + "Z",
"alert_type": "canary_token_triggered",
"severity": "critical",
"token_id": token_id,
"token_type": token_info.get("type", "unknown"),
"placement": token_info.get("placement", "unknown"),
"description": token_info.get("description", ""),
"source_ip": request.remote_addr,
"user_agent": request.headers.get("User-Agent", ""),
"referer": request.headers.get("Referer", ""),
"method": request.method,
"resource_requested": resource,
"all_headers": dict(request.headers),
}
# Log the alert
logging.info(json.dumps(alert))
# Forward to SIEM
try:
requests.post(
SIEM_WEBHOOK,
json=alert,
timeout=5,
headers={"X-Alert-Source": "shadow-cdf-canary"},
)
except requests.RequestException:
pass # Do not fail - log is the source of truth
# Return a 1x1 transparent GIF (for image-based tokens)
gif = (
b"GIF89a\x01\x00\x01\x00\x80\x00\x00"
b"\xff\xff\xff\x00\x00\x00!"
b"\xf9\x04\x00\x00\x00\x00\x00,"
b"\x00\x00\x00\x00\x01\x00\x01\x00"
b"\x00\x02\x02D\x01\x00;"
)
return Response(gif, mimetype="image/gif")
@app.route("/dns/<token_id>", methods=["POST"])
def dns_canary_callback(token_id):
"""Handle DNS-based canary callback (from DNS server log parsing)."""
token_info = TOKEN_INVENTORY.get(token_id, {})
alert = {
"timestamp": datetime.utcnow().isoformat() + "Z",
"alert_type": "dns_canary_triggered",
"severity": "high",
"token_id": token_id,
"placement": token_info.get("placement", "unknown"),
"queried_hostname": request.json.get("hostname", ""),
"source_ip": request.json.get("source_ip", ""),
}
logging.info(json.dumps(alert))
return "", 204
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8443, ssl_context="adhoc")MITRE ATT&CK Mappings
| Technique | Tactic | Relationship |
|---|---|---|
| T1083File and Directory Discovery | Discovery | detects |
| T1005Data from Local System | Collection | detects |
Considerations
- Some canary tokens may fire due to automated processes: antivirus scanners opening files, backup systems traversing directories, or web crawlers following links. Build exclusion rules for known benign triggers.
- Canary alerts include source IP information. Cross-reference with known internal IP assignments to determine if the interaction originated from inside or outside the environment.
- Maintain the token inventory meticulously. An alert from an unknown token is harder to investigate than one with full placement context.
Supported Environments
Tools & Resources
- Canary token management platforms
- Webhook processing services
- SIEM integration
- Incident management platforms
Related Techniques
Quick Stats
- Phase
- Detect
- Difficulty
- foundational
- Detection Value
- critical
- Cost
- minimal
- Time
- 1-3 days
- ATT&CK Mappings
- 2