Skip to content

Commit

Permalink
Add a helper to retrieve the AWS account ID associated with a given a…
Browse files Browse the repository at this point in the history
…ccess key ID (#920)

* Adapt the AWS Key ID decoding blog post to a helper

* Appease the linter

* Appease the linter again

* Move to panther_default; set up default_test.py

* We don't need the separate Makefile target
  • Loading branch information
Evan Gibler authored Oct 30, 2023
1 parent d0529d4 commit 596cbc1
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
16 changes: 16 additions & 0 deletions global_helpers/default_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env python
# Unit tests for functions inside panther_default

import os
import sys
import unittest

sys.path.append(os.path.dirname(__file__))
import panther_default as p_d # pylint: disable=C0413


class TestAWSKeyAccountID(unittest.TestCase):
def test_aws_key_account_id(self):
aws_key_id = "ASIAY34FZKBOKMUTVV7A"
account_id = p_d.aws_key_account_id(aws_key_id)
self.assertEqual(account_id, "609629065308")
21 changes: 21 additions & 0 deletions global_helpers/panther_default.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#


import base64
import binascii


def example_helper():
return True

Expand Down Expand Up @@ -63,3 +67,20 @@ def aws_event_tense(event_name):
return tensed
# If the event pattern doesn't exist, return original
return event_name


# Adapted from https://medium.com/@TalBeerySec/a-short-note-on-aws-key-id-f88cc4317489
def aws_key_account_id(aws_key: str):
"""retrieve the AWS account ID associated with a given access key ID"""
key_no_prefix = aws_key[4:] # remove the four-character prefix
base32_key = base64.b32decode(key_no_prefix) # remainder of the key is base32-encoded
decoded_key = base32_key[0:6] # retrieve the 10-byte string

# Convert the 10-byte string to an integer
key_id_int = int.from_bytes(decoded_key, byteorder="big", signed=False)
mask = int.from_bytes(binascii.unhexlify(b"7fffffffff80"), byteorder="big", signed=False)

# Do a bitwise AND with the mask to retrieve the account ID
# (divide the 10-byte key integer by 128 and remove the fractional part(s))
account_id = (key_id_int & mask) >> 7
return str(account_id)

0 comments on commit 596cbc1

Please sign in to comment.