Identify some canary tokens without detonation (#2500)
Lint / golangci-lint (push) Waiting to run
Lint / semgrep (push) Waiting to run
Release / Release (push) Waiting to run
Scan for secrets / test (push) Waiting to run
Snifftest / Run Snifftest (push) Waiting to run
Test / test (push) Waiting to run
Test / test-community (push) Waiting to run

* Identify canary tokens

* Update README.md

* Update README.md

---------

Co-authored-by: dylanTruffle <[email protected]>
This commit is contained in:
Dustin Decker
2024-02-21 09:42:21 -08:00
committed by GitHub
co-authored by dylanTruffle
parent 76d9e794bf
commit d53b83b58e
2 changed files with 54 additions and 10 deletions
+5
View File
@@ -397,6 +397,11 @@ If you're incorporating TruffleHog into a standalone workflow and aren't running
Depending on the event type (push or PR), we calculate the number of commits present. Then we add 2, so that we can reference a base commit before our code changes. We pass that integer value to the `fetch-depth` flag in the checkout action in addition to the relevant branch. Now our checkout process should be much shorter. Depending on the event type (push or PR), we calculate the number of commits present. Then we add 2, so that we can reference a base commit before our code changes. We pass that integer value to the `fetch-depth` flag in the checkout action in addition to the relevant branch. Now our checkout process should be much shorter.
### Canary detection
TruffleHog statically detects [https://canarytokens.org/](https://canarytokens.org/) and lets you know when they're present without setting them off. You can learn more here: [https://trufflesecurity.com/canaries](https://trufflesecurity.com/canaries)
![image](https://github.com/trufflesecurity/trufflehog/assets/52866392/74ace530-08c5-4eaf-a169-84a73e328f6f)
### Advanced Usage ### Advanced Usage
```yaml ```yaml
+49 -10
View File
@@ -39,6 +39,39 @@ var resourceTypes = map[string]string{
"ASIA": "Temporary (AWS STS) access key IDs", "ASIA": "Temporary (AWS STS) access key IDs",
} }
var thinkstCanaryList = map[string]struct{}{
"052310077262": {},
"171436882533": {},
"534261010715": {},
"595918472158": {},
"717712589309": {},
"819147034852": {},
"992382622183": {},
}
const thinkstMessage = "This is an AWS canary token generated at canarytokens.org, and was not set off; learn more here: https://trufflesecurity.com/canaries"
var thinkstKnockoffsCanaryList = map[string]struct{}{
"044858866125": {},
"251535659677": {},
"344043088457": {},
"351906852752": {},
"390477818340": {},
"426127672474": {},
"427150556519": {},
"439872796651": {},
"445142720921": {},
"465867158099": {},
"637958123769": {},
"693412236332": {},
"732624840810": {},
"735421457923": {},
"959235150393": {},
"982842642351": {},
}
const thinkstKnockoffsMessage = "This is an off brand AWS Canary inspired by canarytokens.org. It wasn't set off; learn more here: https://trufflesecurity.com/canaries"
func New(opts ...func(*scanner)) *scanner { func New(opts ...func(*scanner)) *scanner {
scanner := &scanner{ scanner := &scanner{
skipIDs: map[string]struct{}{}, skipIDs: map[string]struct{}{},
@@ -85,7 +118,6 @@ func (s scanner) Keywords() []string {
"AKIA", "AKIA",
"ABIA", "ABIA",
"ACCA", "ACCA",
"ASIA",
} }
} }
@@ -137,7 +169,22 @@ func (s scanner) FromData(ctx context.Context, verify bool, data []byte) (result
}, },
} }
if verify { account, err := common.GetAccountNumFromAWSID(resIDMatch)
if err == nil {
s1.ExtraData["account"] = account
}
if _, ok := thinkstCanaryList[account]; ok {
s1.ExtraData["is_canary"] = "true"
s1.ExtraData["message"] = thinkstMessage
s1.Verified = true
}
if _, ok := thinkstKnockoffsCanaryList[account]; ok {
s1.ExtraData["is_canary"] = "true"
s1.ExtraData["message"] = thinkstKnockoffsMessage
s1.Verified = true
}
if verify && !s1.Verified {
isVerified, extraData, verificationErr := s.verifyMatch(ctx, resIDMatch, resSecretMatch, true) isVerified, extraData, verificationErr := s.verifyMatch(ctx, resIDMatch, resSecretMatch, true)
s1.Verified = isVerified s1.Verified = isVerified
// It'd be good to log when calculated account value does not match // It'd be good to log when calculated account value does not match
@@ -165,14 +212,6 @@ func (s scanner) FromData(ctx context.Context, verify bool, data []byte) (result
} }
} }
// If we haven't already found an account number for this ID (via API), calculate one.
if _, ok := s1.ExtraData["account"]; !ok {
account, err := common.GetAccountNumFromAWSID(resIDMatch)
if err == nil {
s1.ExtraData["account"] = account
}
}
results = append(results, s1) results = append(results, s1)
// If we've found a verified match with this ID, we don't need to look for any more. So move on to the next ID. // If we've found a verified match with this ID, we don't need to look for any more. So move on to the next ID.
if s1.Verified { if s1.Verified {