Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@DavidWittman
Created April 14, 2016 22:34
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save DavidWittman/792dc6ebe8342ed674cfce3f84b2edab to your computer and use it in GitHub Desktop.
Save DavidWittman/792dc6ebe8342ed674cfce3f84b2edab to your computer and use it in GitHub Desktop.
Parses the output from AWS credential reports and displays users which have been inactive for 60+ days.
#!/usr/bin/env python
# Parses the output from AWS credential reports and displays
# users which have been inactive for 60+ days.
#
# Usage:
# audit_iam_accounts.py credential_report.csv <days>
#
import csv
import sys
from datetime import datetime, timedelta
from prettytable import PrettyTable
class IAMUser(object):
DATE_FORMAT = '%Y-%m-%dT%H:%M:%S+00:00'
def __init__(self, data, inactive_days=60):
self.data = data
self.inactive_days = inactive_days
self.mfa_active = self._parse_bool(data['mfa_active'])
self.name = data['user']
self.created_at = self._parse_date(data['user_creation_time'])
self.password_last_used = \
self._parse_date(data['password_last_used'])
self.access_key_1_active = self._parse_bool(data['access_key_1_active'])
self.access_key_1_last_used = \
self._parse_date(data['access_key_1_last_used_date'])
self.access_key_2_active = self._parse_bool(data['access_key_2_active'])
self.access_key_2_last_used = \
self._parse_date(data['access_key_2_last_used_date'])
def _parse_bool(self, boolstring):
if boolstring == 'true':
return True
else:
return False
def _parse_date(self, datestring):
epoch = datetime.fromtimestamp(0)
return (epoch if (datestring == 'N/A' or datestring == 'no_information')
else datetime.strptime(datestring, self.DATE_FORMAT))
def is_inactive(self):
inactive_date = datetime.now() - timedelta(days=self.inactive_days)
if (self.password_last_used < inactive_date and
self.access_key_1_last_used < inactive_date and
self.access_key_2_last_used < inactive_date):
return True
return False
def main():
filename = sys.argv[1]
try:
inactive_days = int(sys.argv[2])
except:
inactive_days = 60
try:
user_report = csv.DictReader(open(filename))
except Exception as e:
print("Error parsing CSV File: %s" % e)
sys.exit(1)
pt = PrettyTable()
pt.field_names = [
"User",
"MFA Enabled",
"Password Last Used",
"Key 1 Last Used",
"Key 2 Last Used"
]
for user_data in user_report:
user = IAMUser(user_data, inactive_days)
if user.is_inactive():
row = [user.name, user.mfa_active, user.password_last_used]
if user.access_key_1_active:
row.append(user.access_key_1_last_used)
else:
row.append('inactive')
if user.access_key_2_active:
row.append(user.access_key_2_last_used)
else:
row.append('inactive')
pt.add_row(row)
print(pt)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment