Last active
February 4, 2020 11:19
-
-
Save nwithan8/0bb885e71b50e17e092ef7274420a4a6 to your computer and use it in GitHub Desktop.
Check files in a directory for potential keys, token, secrets or other sensitive values
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 python3 | |
| # TO RUN: python3 creds_checker.py PATH/TO/DIRECTORY/TO/CHECK | |
| import os | |
| import argparse | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument('directory', help="Directory to check") | |
| args = parser.parse_args() | |
| files = list() | |
| letters_and_numbers = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz12345678900-_" | |
| def get_files(path): | |
| global files | |
| for (dirpath, dirnames, filenames) in os.walk(path): | |
| files += [os.path.join(dirpath, file) for file in filenames] | |
| def parse(filePath): | |
| lines = {} | |
| words = {} | |
| with open(filePath, 'r') as f: | |
| line_counter = 0 | |
| word_counter = 0 | |
| for line in f: | |
| lines[line_counter] = line | |
| phrases = line.split() | |
| for phrase in phrases: | |
| for char in phrase: | |
| increment = False | |
| if char not in letters_and_numbers: | |
| increment = True | |
| word_counter += 1 | |
| item_entry = words.get(word_counter) | |
| if item_entry: | |
| words[word_counter][0] += str(char) | |
| else: | |
| words[word_counter] = ["", ""] | |
| words[word_counter] = [str(char), line_counter] | |
| if increment: | |
| word_counter += 1 | |
| word_counter += 1 | |
| line_counter += 1 | |
| f.close() | |
| return words, lines | |
| def check(words, lines, filename): | |
| for key, word in words.items(): | |
| lower_word = str(word[0]).lower() | |
| # if lower_word in ['key', 'token', 'secret']: | |
| # print("'{}' in {}".format(word[0], filename)) | |
| # line = lines[word[1]] | |
| # print('Line {}: {}'.format(get_key(lines, line), line)) | |
| if len(lower_word) > 10: | |
| if alphanumeric(lower_word): | |
| print("Possible '{}' in {}".format(word[0], filename)) | |
| line = lines[word[1]] | |
| print('Line {}: {}'.format(get_key(lines, line), line)) | |
| if lower_word.isnumeric(): | |
| print("Possible '{}' in {}".format(word[0], filename)) | |
| line = lines[word[1]] | |
| print('Line {}: {}'.format(get_key(lines, line), line)) | |
| def check_line(lines, filename): | |
| for key, value in lines.items(): | |
| if any(keyword in value for keyword in ['key', 'token', 'secret']): | |
| print(filename) | |
| print('Line {}: {}'.format(key, value)) | |
| def get_key(list, target): | |
| for key, value in list.items(): | |
| if value == target: | |
| return key | |
| def alphanumeric(word): | |
| letters = False | |
| numbers = False | |
| for char in word: | |
| if char.isalpha(): | |
| letters = True | |
| if char.isdigit(): | |
| numbers = True | |
| if letters and numbers: | |
| return True | |
| return False | |
| get_files(args.directory) | |
| for file in files: | |
| if file.split('.')[-1] not in ['pyc']: | |
| words, lines = parse(file) | |
| check(words, lines, file) | |
| # check_line(lines, file) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment