From ebc6eab54a11fd7ad9dd1959cdc29f314efd9d82 Mon Sep 17 00:00:00 2001 From: jmmille <4968945+jmmille@users.noreply.github.com> Date: Mon, 7 Oct 2019 22:45:31 -0400 Subject: [PATCH] Add AWS Access Key ID Analyzer --- pastepwn/analyzers/__init__.py | 4 +- pastepwn/analyzers/awsaccesskeyanalyzer.py | 16 +++++ .../tests/awsaccesskeyanalyzer_test.py | 65 +++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 pastepwn/analyzers/awsaccesskeyanalyzer.py create mode 100644 pastepwn/analyzers/tests/awsaccesskeyanalyzer_test.py diff --git a/pastepwn/analyzers/__init__.py b/pastepwn/analyzers/__init__.py index 5a94eca..1a64e69 100644 --- a/pastepwn/analyzers/__init__.py +++ b/pastepwn/analyzers/__init__.py @@ -28,6 +28,7 @@ from .adobekeyanalyzer import AdobeKeyAnalyzer from .facebookaccesstokenanalyzer import FacebookAccessTokenAnalyzer from .base64analyzer import Base64Analyzer +from .awsaccesskeyanalyzer import AWSAccessKeyAnalyzer __all__ = ( 'AlwaysTrueAnalyzer', @@ -57,5 +58,6 @@ 'PrivateKeyAnalyzer', 'EmailPasswordPairAnalyzer', 'FacebookAccessTokenAnalyzer', - 'Base64Analyzer' + 'Base64Analyzer', + 'AWSAccessKeyAnalyzer' ) diff --git a/pastepwn/analyzers/awsaccesskeyanalyzer.py b/pastepwn/analyzers/awsaccesskeyanalyzer.py new file mode 100644 index 0000000..d6bcefc --- /dev/null +++ b/pastepwn/analyzers/awsaccesskeyanalyzer.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +from .regexanalyzer import RegexAnalyzer + + +class AWSAccessKeyAnalyzer(RegexAnalyzer): + """ + Analyzer to match AWS Access Key via regex + + Keys are 20 character alphanumeric /+= + """ + name = "AWSAccessKeyAnalyzer" + + def __init__(self, actions): + # https://people.eecs.berkeley.edu/~rohanpadhye/files/key_leaks-msr15.pdf + regex = r"\b(A3T[A-Z0-9]|AKIA|AGPA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}\b" + super().__init__(actions, regex) diff --git a/pastepwn/analyzers/tests/awsaccesskeyanalyzer_test.py b/pastepwn/analyzers/tests/awsaccesskeyanalyzer_test.py new file mode 100644 index 0000000..6ddc1ce --- /dev/null +++ b/pastepwn/analyzers/tests/awsaccesskeyanalyzer_test.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +import unittest +from unittest import mock + +from pastepwn.analyzers.awsaccesskeyanalyzer import AWSAccessKeyAnalyzer + + +class TestAWSAccessKeyAnalyzer(unittest.TestCase): + def setUp(self): + self.analyzer = AWSAccessKeyAnalyzer(None) + self.paste = mock.Mock() + + def test_match_positive(self): + """Test if positives are recognized""" + # obtained by pastebin search + self.paste.body = "AKIAIX2GUZJMJFDZON4A" + self.assertTrue(self.analyzer.match(self.paste)) + + # obtained by pastebin search + self.paste.body = "AKIAJ5OVIVTO7XQ7UWOQ" + self.assertTrue(self.analyzer.match(self.paste)) + + # obtained by pastebin search + self.paste.body = "AKIAJM4DOPAAJWLUJ2PQ" + self.assertTrue(self.analyzer.match(self.paste)) + + # obtained by pastebin search + self.paste.body = "AKIAIKSA47YZNJAY2H6A" + self.assertTrue(self.analyzer.match(self.paste)) + + self.paste.body = "my super cool hash is AKIAJM4DOPAAJWLUJ2PQ and here's some more text" + self.assertTrue(self.analyzer.match(self.paste)) + + self.paste.body = "AWS Access Key ID [None]: AKIAIX2GUZJMJFDZON4A" + self.assertTrue(self.analyzer.match(self.paste)) + + # Newline-separated valid hashes + self.paste.body = "AKIAIKSA47YZNJAY2H6A\nAKIAJM4DOPAAJWLUJ2PQ" + self.assertTrue(self.analyzer.match(self.paste)) + + def test_match_negative(self): + """Test if negatives are not recognized""" + self.paste.body = "" + self.assertFalse(self.analyzer.match(self.paste)) + + self.paste.body = None + self.assertFalse(self.analyzer.match(self.paste)) + + # Invalid character '-' + self.paste.body = "AKIAIX2GUZJMJFD-ON4A" + self.assertFalse(self.analyzer.match(self.paste)) + + # Different prefix + self.paste.body = "AKIBIX2GUZJMJFDZON4A" + self.assertFalse(self.analyzer.match(self.paste)) + + # Invalid length + self.paste.body = "AKIAIX2GUZJMJFDZON4" + self.assertFalse(self.analyzer.match(self.paste)) + self.paste.body = "AKIAIX2GUZJMJFDZON4AA" + self.assertFalse(self.analyzer.match(self.paste)) + + +if __name__ == '__main__': + unittest.main()