-
-
Save mpurzynski/31aa853cb8d131cd3ee9c6bb95ac49d3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This Source Code Form is subject to the terms of the Mozilla Public | |
| # License, v. 2.0. If a copy of the MPL was not distributed with this | |
| # file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| # Copyright (c) 2017 Mozilla Corporation | |
| # | |
| # Contributors: | |
| # Michal Purzynski [email protected] | |
| import sys | |
| import os | |
| import re | |
| sys.path.append(os.path.join(os.path.dirname(__file__), "../../lib")) | |
| from utilities.toUTC import toUTC | |
| import pdb | |
| class message(object): | |
| def __init__(self): | |
| ''' | |
| takes an incoming sshd message | |
| and sets the doc_type | |
| ''' | |
| self.registration = ['sshd'] | |
| self.priority = 5 | |
| def onMessage(self, message, metadata): | |
| self.accepted_regex = re.compile('^(?P<authstatus>\w+) (?P<authmethod>\w+) for (?P<username>[a-zA-Z0-9\@._-]+) from (?P<sourceipaddress>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) port (?P<sourceport>\d{1,5}) ssh2(\:\sRSA\s)?(?:(?P<rsakeyfingerprint>(\w+\:){15}\w+))?$') | |
| self.session_opened_regex = re.compile('^pam_unix\(sshd\:session\)\: session (opened|closed) for user (?P<username>[a-zA-Z0-9\@._-]+)(?: by \(uid\=\d*\))?$') | |
| self.postponed_regex = re.compile('^Postponed (?P<authmethod>\w+) for (?P<username>[a-zA-Z0-9\@._-]+) from (?P<sourceipaddress>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) port (?P<sourceport>\d{1,5}) ssh2(?: \[preauth\])?$') | |
| self.starting_session_regex = re.compile('^Starting session: (?P<sessiontype>\w+)(?: on )?(?P<device>pts/0)? for (?P<username>[a-zA-Z0-9\@._-]+) from (?P<sourceipaddress>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) port (?P<sourceport>\d{1,5})$') | |
| self.session_closed_regex = re.compile('^pam_unix\(sshd\:session\)\: session closed for user (?P<username>[a-zA-Z0-9\@._-]+)$') | |
| # pam_unix(sshd:session): session closed for user bro | |
| if 'details' in message: | |
| if 'program' in message['details']: | |
| if message['details']['program'] == 'sshd': | |
| msg_unparsed = message['summary'] | |
| if msg_unparsed.startswith('Accepted'): | |
| accepted_search = re.search(self.accepted_regex, msg_unparsed) | |
| if accepted_search: | |
| message['details']['authstatus'] = accepted_search.group('authstatus') | |
| message['details']['authmethod'] = accepted_search.group('authmethod') | |
| message['details']['username'] = accepted_search.group('username') | |
| message['details']['sourceipaddress'] = accepted_search.group('sourceipaddress') | |
| message['details']['sourceport'] = accepted_search.group('sourceport') | |
| message['details']['rsakeyfingerprint'] = accepted_search.group('rsakeyfingerprint') | |
| if msg_unparsed.startswith('pam_unix'): | |
| session_opened_search = re.search(self.session_opened_regex, msg_unparsed) | |
| if session_opened_search: | |
| message['details']['username'] = session_opened_search.group('username') | |
| if msg_unparsed.startswith('Postponed'): | |
| postponed_search = re.search(self.postponed_regex, msg_unparsed) | |
| if postponed_search: | |
| message['details']['username'] = postponed_search.group('username') | |
| message['details']['authmethod'] = postponed_search.group('authmethod') | |
| if msg_unparsed.startswith('Starting session'): | |
| starting_session_search = re.search(self.starting_session_regex, msg_unparsed) | |
| if starting_session_search: | |
| message['details']['sessiontype'] = starting_session_search.group('sessiontype') | |
| message['details']['username'] = starting_session_search.group('username') | |
| message['details']['sourceipaddress'] = starting_session_search.group('sourceipaddress') | |
| message['details']['sourceport'] = starting_session_search.group('sourceport') | |
| message['details']['device'] = starting_session_search.group('device') | |
| return (message, metadata) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This Source Code Form is subject to the terms of the Mozilla Public | |
| # License, v. 2.0. If a copy of the MPL was not distributed with this | |
| # file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| # Copyright (c) 2017 Mozilla Corporation | |
| # | |
| # Contributors: | |
| # Michal Purzynski [email protected] | |
| import os | |
| import sys | |
| sys.path.append(os.path.join(os.path.dirname(__file__), "../../../mq/plugins")) | |
| from parse_sshd import message | |
| import copy | |
| accept_message = {} | |
| accept_message['_type'] = 'event' | |
| accept_message = {} | |
| accept_message['utctimestamp'] = '2017-08-24T22:49:42+00:00' | |
| accept_message['timestamp'] = '2017-08-24T22:49:42+00:00' | |
| accept_message['receivedtimestamp'] = '2017-08-24T22:49:42+00:00' | |
| accept_message['category'] = 'syslog' | |
| accept_message['processid'] = '0' | |
| accept_message['severity'] = '7' | |
| accept_message['hostname'] = 'syslog1.private.scl3.mozilla.com' | |
| accept_message['mozdefhostname'] = 'mozdef4.private.scl3.mozilla.com' | |
| accept_message['eventsource'] = 'systemlogs' | |
| accept_message['details'] = {} | |
| accept_message['details']['processid'] = '5413' | |
| accept_message['details']['Random'] = '9' | |
| accept_message['details']['sourceipv4address'] = '10.22.74.208' | |
| accept_message['details']['hostname'] = 'mysuperhost.somewhere.com' | |
| accept_message['details']['program'] = 'sshd' | |
| accept_message['details']['sourceipaddress'] = '10.22.74.208' | |
| # Short username, RSA fpr present | |
| class TestSSHDAcceptedMessageV1(): | |
| def setup(self): | |
| self.msgobj = message() | |
| self.msg = copy.deepcopy(accept_message) | |
| self.msg['summary'] = 'Accepted publickey for user1 from 10.22.74.208 port 26388 ssh2: RSA 1f:c9:4c:90:bc:fb:72:c7:4d:02:da:07:ed:fe:07:ac' | |
| def test_onMessage(self): | |
| metadata = {} | |
| metadata['doc_type'] = 'event' | |
| (retmessage, retmeta) = self.msgobj.onMessage(self.msg, metadata) | |
| assert retmessage is not None | |
| assert retmeta is not None | |
| assert retmessage['details']['username'] == 'user1' | |
| assert retmessage['details']['rsakeyfingerprint'] == '1f:c9:4c:90:bc:fb:72:c7:4d:02:da:07:ed:fe:07:ac' | |
| assert retmessage['details']['authmethod'] == 'publickey' | |
| assert retmessage['details']['sourceport'] == '26388' | |
| assert retmessage['details']['authstatus'] == 'Accepted' | |
| assert retmessage['details']['sourceipaddress'] == '10.22.74.208' | |
| # Long username | |
| class TestSSHDAcceptedMessageV2(): | |
| def setup(self): | |
| self.msgobj = message() | |
| self.msg = copy.deepcopy(accept_message) | |
| self.msg['summary'] = 'Accepted publickey for [email protected] from 10.22.74.208 port 26388 ssh2: RSA 1f:c9:4c:90:bc:fb:72:c7:4d:02:da:07:ed:fe:07:ac' | |
| def test_onMessage(self): | |
| metadata = {} | |
| metadata['doc_type'] = 'event' | |
| (retmessage, retmeta) = self.msgobj.onMessage(self.msg, metadata) | |
| assert retmessage is not None | |
| assert retmeta is not None | |
| assert retmessage['details']['username'] == '[email protected]' | |
| assert retmessage['details']['rsakeyfingerprint'] == '1f:c9:4c:90:bc:fb:72:c7:4d:02:da:07:ed:fe:07:ac' | |
| assert retmessage['details']['authmethod'] == 'publickey' | |
| assert retmessage['details']['sourceport'] == '26388' | |
| assert retmessage['details']['authstatus'] == 'Accepted' | |
| assert retmessage['details']['sourceipaddress'] == '10.22.74.208' | |
| # Short username, RSA fpr missing | |
| class TestSSHDAcceptedMessageV3(): | |
| def setup(self): | |
| self.msgobj = message() | |
| self.msg = copy.deepcopy(accept_message) | |
| self.msg['summary'] = 'Accepted publickey for user1 from 10.22.74.208 port 26388 ssh2' | |
| def test_onMessage(self): | |
| metadata = {} | |
| metadata['doc_type'] = 'event' | |
| (retmessage, retmeta) = self.msgobj.onMessage(self.msg, metadata) | |
| assert retmessage is not None | |
| assert retmeta is not None | |
| assert retmessage['details']['username'] == 'user1' | |
| assert retmessage['details']['rsakeyfingerprint'] is None | |
| assert retmessage['details']['authmethod'] == 'publickey' | |
| assert retmessage['details']['sourceport'] == '26388' | |
| assert retmessage['details']['authstatus'] == 'Accepted' | |
| assert retmessage['details']['sourceipaddress'] == '10.22.74.208' | |
| # PAM session opened for user | |
| class TestSSHDPAMSessionOpenedMessageV1(): | |
| def setup(self): | |
| self.msgobj = message() | |
| self.msg = copy.deepcopy(accept_message) | |
| self.msg['summary'] = 'pam_unix(sshd:session): session opened for user user1 by (uid=0)' | |
| def test_onMessage(self): | |
| metadata = {} | |
| metadata['doc_type'] = 'event' | |
| (retmessage, retmeta) = self.msgobj.onMessage(self.msg, metadata) | |
| assert retmessage is not None | |
| assert retmeta is not None | |
| assert retmessage['details']['username'] == 'user1' | |
| # PAM session closed for user | |
| class TestSSHDPAMSessionClosedMessageV1(): | |
| def setup(self): | |
| self.msgobj = message() | |
| self.msg = copy.deepcopy(accept_message) | |
| self.msg['summary'] = 'pam_unix(sshd:session): session closed for user user1' | |
| def test_onMessage(self): | |
| metadata = {} | |
| metadata['doc_type'] = 'event' | |
| (retmessage, retmeta) = self.msgobj.onMessage(self.msg, metadata) | |
| assert retmessage is not None | |
| assert retmeta is not None | |
| assert retmessage['details']['username'] == 'user1' | |
| # Postponed preauth - short, simple username | |
| class TestSSHDPostponedMessageV1(): | |
| def setup(self): | |
| self.msgobj = message() | |
| self.msg = copy.deepcopy(accept_message) | |
| self.msg['summary'] = 'Postponed publickey for user1 from 10.22.75.209 port 37486 ssh2' | |
| def test_onMessage(self): | |
| metadata = {} | |
| metadata['doc_type'] = 'event' | |
| (retmessage, retmeta) = self.msgobj.onMessage(self.msg, metadata) | |
| assert retmessage is not None | |
| assert retmeta is not None | |
| assert retmessage['details']['username'] == 'user1' | |
| assert retmessage['details']['authmethod'] == 'publickey' | |
| # Postponed preauth - long, simple username | |
| class TestSSHDPostponedMessageV2(): | |
| def setup(self): | |
| self.msgobj = message() | |
| self.msg = copy.deepcopy(accept_message) | |
| self.msg['summary'] = 'Postponed publickey for user1 from 10.22.75.209 port 37486 ssh2 [preauth]' | |
| def test_onMessage(self): | |
| metadata = {} | |
| metadata['doc_type'] = 'event' | |
| (retmessage, retmeta) = self.msgobj.onMessage(self.msg, metadata) | |
| assert retmessage is not None | |
| assert retmeta is not None | |
| assert retmessage['details']['username'] == 'user1' | |
| assert retmessage['details']['authmethod'] == 'publickey' | |
| # Postponed preauth - long username | |
| class TestSSHDPostponedMessageV3(): | |
| def setup(self): | |
| self.msgobj = message() | |
| self.msg = copy.deepcopy(accept_message) | |
| self.msg['summary'] = 'Postponed publickey for [email protected] from 10.22.75.209 port 37486 ssh2 [preauth]' | |
| def test_onMessage(self): | |
| metadata = {} | |
| metadata['doc_type'] = 'event' | |
| (retmessage, retmeta) = self.msgobj.onMessage(self.msg, metadata) | |
| assert retmessage is not None | |
| assert retmeta is not None | |
| assert retmessage['details']['username'] == '[email protected]' | |
| assert retmessage['details']['authmethod'] == 'publickey' | |
| # Starting session | |
| class TestSSHDStartingSessionV1(): | |
| def setup(self): | |
| self.msgobj = message() | |
| self.msg = copy.deepcopy(accept_message) | |
| self.msg['summary'] = 'Starting session: command for user1 from 10.22.128.93 port 51748' | |
| def test_onMessage(self): | |
| metadata = {} | |
| metadata['doc_type'] = 'event' | |
| (retmessage, retmeta) = self.msgobj.onMessage(self.msg, metadata) | |
| assert retmessage is not None | |
| assert retmeta is not None | |
| assert retmessage['details']['username'] == 'user1' | |
| assert retmessage['details']['sessiontype'] == 'command' | |
| assert retmessage['details']['sourceipaddress'] == '10.22.128.93' | |
| assert retmessage['details']['sourceport'] == '51748' | |
| # Starting session | |
| class TestSSHDStartingSessionV2(): | |
| def setup(self): | |
| self.msgobj = message() | |
| self.msg = copy.deepcopy(accept_message) | |
| self.msg['summary'] = 'Starting session: shell on pts/0 for user2 from 10.22.252.6 port 59983' | |
| def test_onMessage(self): | |
| metadata = {} | |
| metadata['doc_type'] = 'event' | |
| (retmessage, retmeta) = self.msgobj.onMessage(self.msg, metadata) | |
| assert retmessage is not None | |
| assert retmeta is not None | |
| assert retmessage['details']['username'] == 'user2' | |
| assert retmessage['details']['sessiontype'] == 'shell' | |
| assert retmessage['details']['sourceipaddress'] == '10.22.252.6' | |
| assert retmessage['details']['sourceport'] == '59983' | |
| assert retmessage['details']['device'] == 'pts/0' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment