mirror of
https://github.com/trufflesecurity/trufflehog.git
synced 2024-11-10 07:04:24 +00:00
extract AWS account number from ID without verification (#2091)
* added GetAccountNumFromAWSID function * refacted aws func, moved to common
This commit is contained in:
parent
737d6b764d
commit
b2042e4e03
4 changed files with 56 additions and 1 deletions
|
@ -4,6 +4,9 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/base32"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"strings"
|
||||
|
@ -64,3 +67,27 @@ func RandomID(length int) string {
|
|||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func GetAccountNumFromAWSID(AWSID string) (string, error) {
|
||||
// Function to get the account number from an AWS ID (no verification required)
|
||||
// Source: https://medium.com/@TalBeerySec/a-short-note-on-aws-key-id-f88cc4317489
|
||||
if len(AWSID) < 4 {
|
||||
return "", fmt.Errorf("AWSID is too short")
|
||||
}
|
||||
trimmed_AWSID := AWSID[4:]
|
||||
decodedBytes, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(strings.ToUpper(trimmed_AWSID))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(decodedBytes) < 6 {
|
||||
return "", fmt.Errorf("Decoded AWSID is too short")
|
||||
}
|
||||
|
||||
data := make([]byte, 8)
|
||||
copy(data[2:], decodedBytes[0:6])
|
||||
z := binary.BigEndian.Uint64(data)
|
||||
const mask uint64 = 0x7fffffffff80
|
||||
account_num := (z & mask) >> 7
|
||||
return fmt.Sprintf("%012d", account_num), nil
|
||||
}
|
||||
|
|
|
@ -139,6 +139,10 @@ func (s scanner) FromData(ctx context.Context, verify bool, data []byte) (result
|
|||
if verify {
|
||||
verified, extraData, verificationErr := s.verifyMatch(ctx, resIDMatch, resSecretMatch, true)
|
||||
s1.Verified = verified
|
||||
//It'd be good to log when calculated account value does not match
|
||||
//the account value from verification. Should only be edge cases at most.
|
||||
//if extraData["account"] != s1.ExtraData["account"] && extraData["account"] != "" {//log here}
|
||||
|
||||
//Append the extraData to the existing ExtraData map.
|
||||
// This will overwrite with the new verified values.
|
||||
for k, v := range extraData {
|
||||
|
@ -158,6 +162,14 @@ 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)
|
||||
// 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 {
|
||||
|
|
|
@ -84,7 +84,10 @@ func TestAWS_FromChunk(t *testing.T) {
|
|||
DetectorType: detectorspb.DetectorType_AWS,
|
||||
Verified: false,
|
||||
Redacted: "AKIASP2TPHJSQH3FJRUX",
|
||||
ExtraData: map[string]string{"resource_type": "Access key"},
|
||||
ExtraData: map[string]string{
|
||||
"resource_type": "Access key",
|
||||
"account": "171436882533",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
|
@ -115,6 +118,7 @@ func TestAWS_FromChunk(t *testing.T) {
|
|||
Redacted: "AKIASP2TPHJSQH3FJXYZ",
|
||||
ExtraData: map[string]string{
|
||||
"resource_type": "Access key",
|
||||
"account": "171436882533",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -187,6 +191,7 @@ func TestAWS_FromChunk(t *testing.T) {
|
|||
Redacted: "AKIASP2TPHJSQH3FJRUX",
|
||||
ExtraData: map[string]string{
|
||||
"resource_type": "Access key",
|
||||
"account": "171436882533",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -221,6 +226,7 @@ func TestAWS_FromChunk(t *testing.T) {
|
|||
Redacted: "AKIASP2TPHJSQH3FJRUX",
|
||||
ExtraData: map[string]string{
|
||||
"resource_type": "Access key",
|
||||
"account": "171436882533",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -242,6 +248,7 @@ func TestAWS_FromChunk(t *testing.T) {
|
|||
Redacted: "AKIASP2TPHJSQH3FJRUX",
|
||||
ExtraData: map[string]string{
|
||||
"resource_type": "Access key",
|
||||
"account": "171436882533",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -263,6 +270,7 @@ func TestAWS_FromChunk(t *testing.T) {
|
|||
Redacted: "AKIASP2TPHJSQH3FJRUX",
|
||||
ExtraData: map[string]string{
|
||||
"resource_type": "Access key",
|
||||
"account": "171436882533",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -150,6 +150,14 @@ 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)
|
||||
// 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 {
|
||||
|
|
Loading…
Reference in a new issue