Skip to content

Commit

Permalink
Merge branch 'master' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
d-Rickyy-b committed Oct 9, 2019
2 parents 1ec069c + bd31646 commit 518bc0d
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pastepwn/analyzers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
from .adobekeyanalyzer import AdobeKeyAnalyzer
from .facebookaccesstokenanalyzer import FacebookAccessTokenAnalyzer
from .base64analyzer import Base64Analyzer
from .awsaccesskeyanalyzer import AWSAccessKeyAnalyzer
from .googleoauthkeyanalyzer import GoogleOAuthKeyAnalyzer
from .slackwebhookanalyzer import SlackWebhookAnalyzer
from .awssessiontokenanalyzer import AWSSessionTokenAnalyzer

__all__ = (
Expand Down Expand Up @@ -59,5 +62,8 @@
'EmailPasswordPairAnalyzer',
'FacebookAccessTokenAnalyzer',
'Base64Analyzer',
'AWSAccessKeyAnalyzer',
'GoogleOAuthKeyAnalyzer',
'SlackWebhookAnalyzer'
'AWSSessionTokenAnalyzer'
)
16 changes: 16 additions & 0 deletions pastepwn/analyzers/awsaccesskeyanalyzer.py
Original file line number Diff line number Diff line change
@@ -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)
8 changes: 8 additions & 0 deletions pastepwn/analyzers/googleoauthkeyanalyzer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from .regexanalyzer import RegexAnalyzer


class GoogleOAuthKeyAnalyzer(RegexAnalyzer):

def __init__(self, actions):
regex = r"[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com"
super().__init__(actions, regex)
16 changes: 16 additions & 0 deletions pastepwn/analyzers/slackwebhookanalyzer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
from .regexanalyzer import RegexAnalyzer


class SlackWebhookAnalyzer(RegexAnalyzer):
"""Analyzer to match (likely) Slack Webhook URLs"""

def __init__(self, action):
"""
Analyzer to match (likely) Slack Webhook URLs
:param action: Single action or list of actions to be executed when a paste matches
"""

regex = r'https://hooks.slack.com/services/T[a-zA-Z0-9_]{8}/B[a-zA-Z0-9_]{8}/[a-zA-Z0-9_]{24}'

super().__init__(action, regex)
65 changes: 65 additions & 0 deletions pastepwn/analyzers/tests/awsaccesskeyanalyzer_test.py
Original file line number Diff line number Diff line change
@@ -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()
57 changes: 57 additions & 0 deletions pastepwn/analyzers/tests/googleoauthkeyanalyzer_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import unittest
from unittest import mock

from pastepwn.analyzers.googleoauthkeyanalyzer import GoogleOAuthKeyAnalyzer


class TestGoogleOAuthKeyAnalyzer(unittest.TestCase):

def setUp(self):
self.analyzer = GoogleOAuthKeyAnalyzer(None)
self.paste = mock.Mock()

def test_match_positive(self):
"""Test if positives are recognized"""
# google key dump
self.paste.body = "6243-jhgcawesuycgaweiufyugfaiwyesfbaw.apps.googleusercontent.com"
self.assertTrue(self.analyzer.match(self.paste))

# google key dump
self.paste.body = "6243-IUFHERIUFHASOEIRUFGHDOZIFUGVDHSF.apps.googleusercontent.com"
self.assertTrue(self.analyzer.match(self.paste))

# google key dump
self.paste.body = "6243-18723612873612873621367128736128.apps.googleusercontent.com"
self.assertTrue(self.analyzer.match(self.paste))

# google key dump
self.paste.body = "1-jhgcawesuycgaweiufyugfaiwyesfbaw.apps.googleusercontent.com"
self.assertTrue(self.analyzer.match(self.paste))

# google key dump
self.paste.body = "6242345234234234234234234233-jhgcawesuycgaweiufyugfaiwyesfbaw.apps.googleusercontent.com"
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 length
self.paste.body = "6243-jhgcawesuycgaweiufyugfaisfbaw.apps.googleusercontent.com"
self.assertFalse(self.analyzer.match(self.paste))

# Invalid numbers
self.paste.body = "-jhgcawesuycgaweiufyugfaiwyesfbaw.apps.googleusercontent.com"
self.assertFalse(self.analyzer.match(self.paste))

# Invalid domain
self.paste.body = "6243-jhgcawesuycgaweiufyugfaiwyesfbaw.apps.google.com"
self.assertFalse(self.analyzer.match(self.paste))


if __name__ == '__main__':
unittest.main()
63 changes: 63 additions & 0 deletions pastepwn/analyzers/tests/slackwebhookanalyzer_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
import unittest
from unittest import mock

from pastepwn.analyzers.slackwebhookanalyzer import SlackWebhookAnalyzer


class TestSlackWebhookAnalyzer(unittest.TestCase):
def setUp(self):
self.analyzer = SlackWebhookAnalyzer(None)
self.paste = mock.Mock()

def test_match_positive(self):
"""Test if positives are recognized"""
# slack webhook url (sample)
self.paste.body = "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
self.assertTrue(self.analyzer.match(self.paste))

# slack webhook url (manually generated)
self.paste.body = "https://hooks.slack.com/services/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"
self.assertTrue(self.analyzer.match(self.paste))

# slack webhook url (randomly generated)
self.paste.body = "https://hooks.slack.com/services/TwLj3Aeic/B2RnzBQQp/7JkqKP9XxuqN3WFDn3tUA8NJ"
self.assertTrue(self.analyzer.match(self.paste))

# slack webhook url (randomly generated)
self.paste.body = "https://hooks.slack.com/services/TafdGEj9a/B9BdR2SLM/yJAk3gcguM8YzFEpaPnSvZ4Q"
self.assertTrue(self.analyzer.match(self.paste))

# part of a sentence
self.paste.body = "here is the webhook url: The slack webhook key is " \
"https://hooks.slack.com/services/T00000000/B00000000"\
"/XXXXXXXXXXXXXXXXXXXXXXXX! how about that!"
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))

# Other Slack URL (api docs)
self.paste.body = "https://api.slack.com/incoming-webhooks"
self.assertFalse(self.analyzer.match(self.paste))

# Invalid Character
self.paste.body = "https://hooks.slack.com/services/T00!00000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
self.assertFalse(self.analyzer.match(self.paste))

# Invalid Length
self.paste.body = "https://hooks.slack.com/services/T00000000/B0000000/XXXXXXXXXXXXXXXXXXXXXXXX"
self.assertFalse(self.analyzer.match(self.paste))

# Invalid Format (/services/Z... vs /services/T...)
self.paste.body = "https://hooks.slack.com/services/Z00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
self.assertFalse(self.analyzer.match(self.paste))


if __name__ == '__main__':
unittest.main()

0 comments on commit 518bc0d

Please sign in to comment.