- 
      
- 
        Save taeyu7720/1edb9088569ec49bc6ab7370a1bf1fa3 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.
  
        
  
    
      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
    
  
  
    
  | #!/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