def create_data_tuples(key): """ create the tuples for storing multiple passwords at a time """ stop = False retval = [] info("press CNTRL-C to finish") while not stop: try: information = prompt("enter password information: ") password = prompt("enter password to store with the information ({}): ".format(information), hide=True) retval.append((information, encryption.aes_encryption.AESCipher(key).encrypt(password))) except KeyboardInterrupt: stop = True print() return retval
def display_formatted_list_output(data, key, prompting=True, answer="n"): """ display decrypted data in plaintext """ separator = "-" * 30 if prompting: choice = prompt("display plaintext?[y/N] ") else: choice = answer if choice.lower().startswith("y"): warning("all output is displayed in plaintext") print(separator + "\n") for row in data: print("INFO: {}\nSTORED PASSWORD: {}\n".format( row[0], encryption.aes_encryption.AESCipher(key).decrypt(row[1]) )) print(separator) else: print(separator + "\n") for row in data: print( "INFO: {}\nSTORED PASSWORD: {}\n".format( row[0], "*" * 7 ) ) print(separator)
def compare(stored): """ compare the provided key hash with the stored key hash """ def complex_verification(provided, stored): """ a complex comparison of two different strings compares the following: * checking the length of the strings match * checking if each character in the strings matches * checking the system size of the strings * checking if the random nth end characters of the strings match """ random_int_check = random.choice(range(len(provided))) if not len(stored) == len(provided): return False for char in zip(list(provided), list(stored)): if char[0] != char[1]: return False if sys.getsizeof(provided) != sys.getsizeof(stored): return False if provided[-random_int_check] != stored[-random_int_check]: return False return True tries = 3 while True: provided_key = prompt( "enter your encryption password, {} tries left: ".format(tries), hide=True ) stored_key = base64.urlsafe_b64decode(stored) provided_key = sha256_rounds(provided_key, first_login=True) if stored_key == provided_key: if not complex_verification(provided_key, stored_key): return False return True else: tries -= 1 if tries == 0: break elif tries == 1: fatal("you have one chance left to provide the correct key or all data will be deleted") else: warning("incorrect key") return False
def store_key(path, grab_key=False): """ store the encrypted key or be prompted to create one """ if not os.path.exists(path): os.mkdir(path) password_file = "{}/.pass".format(path) key_file = "{}/.key".format(path) if not os.path.exists(password_file): provided_key = prompt( "you have not provided an encryption key, please provide one: ", hide=True ) key = base64.urlsafe_b64encode(sha256_rounds(provided_key)) encryption.aes_encryption.AESCipher(key).generate_key(provided_key) length = len(key) with open(password_file, "a+") as key_: front_salt, back_salt = os.urandom(16), os.urandom(16) key_.write("{}{}{}:{}".format(front_salt, key, back_salt, length)) write_init_file(INIT_FILE, os.listdir(MAIN_DIR), MAIN_DIR) info( "letmein has been initialized. you will need to re-run the program." ) exit(-1) else: check_for_file_change() with open(password_file) as data: retval = data.read() amount = retval.split(":")[-1] edited = retval[16:] edited = edited[:int(amount)] if grab_key: with open(key_file) as data: retval = encryption.aes_encryption.AESCipher(edited).decrypt(data.read()) else: retval = None return retval, edited
def main(): opts = AutoSploitParser().optparser() logo() info("welcome to autosploit, give us a little bit while we configure") info("checking for services") service_names = ("postgresql", "apache") for service in list(service_names): if not check_services(service): choice = prompt("it appears that service {} is not enabled, would you like us to enable it for you[y/N]".format(service)) if choice.lower().startswith("y"): if "postgre" in service: cmdline("sudo bash {}".format(START_POSTGRESQL_PATH)) else: cmdline("sudo bash {}".format(START_APACHE_PATH)) info("service started successfully") else: error("service {} is required to be started for autosploit to run, exiting".format(service.title())) sys.exit(1) if len(sys.argv) > 1: info("attempting to load API keys") loaded_tokens = load_api_keys() AutoSploitParser().parse_provided(opts) info("checking if there are multiple exploit files") loaded_exploits = load_exploits(EXPLOIT_FILES_PATH) AutoSploitParser().single_run_args(opts, loaded_tokens, loaded_exploits) else: warning("no arguments have been parsed, defaulting to terminal session. press 99 to quit and help to get help") info("checking if there are multiple exploit files") loaded_exploits = load_exploits(EXPLOIT_FILES_PATH) info("attempting to load API keys") loaded_tokens = load_api_keys() terminal = AutoSploitTerminal(loaded_tokens) terminal.terminal_main_display(loaded_exploits)
def main(): try: try: is_admin = os.getuid() == 0 except AttributeError: # we'll make it cross platform because it seems like a cool idea is_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0 if not is_admin: close("must have admin privileges to run") opts = AutoSploitParser().optparser() logo() info("welcome to autosploit, give us a little bit while we configure") misc_info("checking your running platform") platform_running = platform.system() misc_info("checking for disabled services") # according to ps aux, postgre and apache2 are the names of the services on Linux systems service_names = ("postgres", "apache2") try: for service in list(service_names): while not check_services(service): if "darwin" in platform_running.lower(): info( "seems you're on macOS, skipping service checks " "(make sure that Apache2 and PostgreSQL are running)" ) break choice = prompt( "it appears that service {} is not enabled, would you like us to enable it for you[y/N]".format( service.title() ) ) if choice.lower().startswith("y"): try: if "linux" in platform_running.lower(): cmdline("{} linux".format(START_SERVICES_PATH)) else: close("your platform is not supported by AutoSploit at this time", status=2) # moving this back because it was funky to see it each run info("services started successfully") # this tends to show up when trying to start the services # I'm not entirely sure why, but this fixes it except psutil.NoSuchProcess: pass else: process_start_command = "`sudo service {} start`" if "darwin" in platform_running.lower(): process_start_command = "`brew services start {}`" close( "service {} is required to be started for autosploit to run successfully (you can do it manually " "by using the command {}), exiting".format( service.title(), process_start_command.format(service) ) ) except Exception: pass if len(sys.argv) > 1: info("attempting to load API keys") loaded_tokens = load_api_keys() AutoSploitParser().parse_provided(opts) if not opts.exploitFile: misc_info("checking if there are multiple exploit files") loaded_exploits = load_exploits(EXPLOIT_FILES_PATH) else: loaded_exploits = load_exploit_file(opts.exploitFile) misc_info("Loaded {} exploits from {}.".format( len(loaded_exploits), opts.exploitFile)) AutoSploitParser().single_run_args(opts, loaded_tokens, loaded_exploits) else: misc_info("checking if there are multiple exploit files") loaded_exploits = load_exploits(EXPLOIT_FILES_PATH) info("attempting to load API keys") loaded_tokens = load_api_keys() terminal = AutoSploitTerminal(loaded_tokens, loaded_exploits) terminal.terminal_main_display(loaded_tokens) except Exception as e: import traceback print( "\033[31m[!] AutoSploit has hit an unhandled exception: '{}', " "in order for the developers to troubleshoot and repair the " "issue AutoSploit will need to gather your OS information, " "current arguments, the error message, and a traceback. " "None of this information can be used to identify you in any way\033[0m".format(str(e)) ) error_traceback = ''.join(traceback.format_tb(sys.exc_info()[2])) error_class = str(e.__class__).split(" ")[1].split(".")[1].strip(">").strip("'") error_file = save_error_to_file(str(error_traceback), str(e), error_class) request_issue_creation(error_file, hide_sensitive(), str(e))
def main(): try: is_admin = os.getuid() == 0 except AttributeError: # we'll make it cross platform because it seems like a cool idea is_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0 if not is_admin: close("must have admin privileges to run") opts = AutoSploitParser().optparser() logo() info("welcome to autosploit, give us a little bit while we configure") misc_info("checking your running platform") platform_running = platform.system() misc_info("checking for disabled services") # according to ps aux, postgre and apache2 are the names of the services on Linux systems service_names = ("postgres", "apache2") if "darwin" in platform_running.lower(): service_names = ("postgres", "apachectl") for service in list(service_names): while not check_services(service): choice = prompt( "it appears that service {} is not enabled, would you like us to enable it for you[y/N]" .format(service.title())) if choice.lower().startswith("y"): try: if "darwin" in platform_running.lower(): cmdline("{} darwin".format(START_SERVICES_PATH)) elif "linux" in platform_running.lower(): cmdline("{} linux".format(START_SERVICES_PATH)) else: close( "your platform is not supported by AutoSploit at this time", status=2) # moving this back because it was funky to see it each run info("services started successfully") # this tends to show up when trying to start the services # I'm not entirely sure why, but this fixes it except psutil.NoSuchProcess: pass else: process_start_command = "`sudo service {} start`" if "darwin" in platform_running.lower(): process_start_command = "`brew services start {}`" close( "service {} is required to be started for autosploit to run successfully (you can do it manually " "by using the command {}), exiting".format( service.title(), process_start_command.format(service))) if len(sys.argv) > 1: info("attempting to load API keys") loaded_tokens = load_api_keys() AutoSploitParser().parse_provided(opts) if not opts.exploitFile: misc_info("checking if there are multiple exploit files") loaded_exploits = load_exploits(EXPLOIT_FILES_PATH) else: loaded_exploits = load_exploit_file(opts.exploitFile) misc_info("Loaded {} exploits from {}.".format( len(loaded_exploits), opts.exploitFile)) AutoSploitParser().single_run_args(opts, loaded_tokens, loaded_exploits) else: warning( "no arguments have been parsed, defaulting to terminal session. press 99 to quit and help to get help" ) misc_info("checking if there are multiple exploit files") loaded_exploits = load_exploits(EXPLOIT_FILES_PATH) info("attempting to load API keys") loaded_tokens = load_api_keys() terminal = AutoSploitTerminal(loaded_tokens) terminal.terminal_main_display(loaded_exploits)
def main(): opts = AutoSploitParser().optparser() logo() info("welcome to autosploit, give us a little bit while we configure") # verify if we are running python 2.X misc_info("checking python version") if not sys.version_info[ 0] == 2: # if we are not running a python version 2.X error( "Your Python installation seems to be incompatible with AutoSploit. You should try using Python 2.x" ) exit() misc_info("checking for disabled services") # according to ps aux, postgre and apache2 are the names of the services service_names = ("postgres", "apache2") for service in list(service_names): while not check_services(service): choice = prompt( "it appears that service {} is not enabled, would you like us to enable it for you[y/N]" .format(service.title())) if choice.lower().startswith("y"): try: if "postgre" in service: cmdline("sudo bash {}".format(START_POSTGRESQL_PATH)) else: cmdline("sudo bash {}".format(START_APACHE_PATH)) # moving this back because it was funky to see it each run info("services started successfully") # this tends to show up when trying to start the services # I'm not entirely sure why, but this fixes it except psutil.NoSuchProcess: pass else: error( "service {} is required to be started for autosploit to run successfully (you can do it manually " "by using the command `sudo service {} start`), exiting". format(service.title(), service)) sys.exit(1) if len(sys.argv) > 1: info("attempting to load API keys") loaded_tokens = load_api_keys() AutoSploitParser().parse_provided(opts) misc_info("checking if there are multiple exploit files") loaded_exploits = load_exploits(EXPLOIT_FILES_PATH) AutoSploitParser().single_run_args(opts, loaded_tokens, loaded_exploits) else: warning( "no arguments have been parsed, defaulting to terminal session. press 99 to quit and help to get help" ) misc_info("checking if there are multiple exploit files") loaded_exploits = load_exploits(EXPLOIT_FILES_PATH) info("attempting to load API keys") loaded_tokens = load_api_keys() terminal = AutoSploitTerminal(loaded_tokens) terminal.terminal_main_display(loaded_exploits)
def main(): try: opt = LetMeInParser().optparse() if opt.showVersionNumber: from lib.settings import VERSION_STRING, VERSION print(VERSION.format(VERSION_STRING)) exit(0) print(BANNER) info("initializing") _, stored_password = store_key(MAIN_DIR) if not compare(stored_password): secure_delete(MAIN_DIR) warning("ALL DATA HAS BEEN REMOVED") else: stored_key, _ = store_key(MAIN_DIR, grab_key=True) info("password accepted!") conn, cursor = SQL(db_file=DATABASE_FILE).create_connection() if opt.showAllStoredPasswords: password_data = SQL(cursor=cursor).select_all_data() if password_data is not None: info("gathered {} password(s) total".format(len(password_data))) info("decrypting stored information") display_formatted_list_output( password_data, stored_key, prompting=opt.doNotPrompt, answer=opt.promptAnswer ) else: fatal("received no password data from the database, is there anything in there?") if opt.showOnlyThisPassword is not None: results = SQL(information=opt.showOnlyThisPassword, cursor=cursor).show_single_password() if len(results) == 0: warning("no information could be found with the provided string, you should check all first") else: info("found what you are looking for") try: display_formatted_list_output( results, stored_key, prompting=opt.doNotPrompt, answer=opt.promptAnswer ) except TypeError: print("INFO: {}\tSTORED PASSWORD: {}\n\n{}".format( results[0], AESCipher(stored_key).decrypt(results[1]), "-" * 30 )) if opt.storeProvidedPassword: if opt.passwordInformation is not None: password_information = opt.passwordInformation else: password_information = prompt("enter the information string associated with this password: "******"enter the password to store: ", hide=True) encrypted_password = AESCipher(stored_key).encrypt(password) status = SQL( connection=conn, cursor=cursor, information=password_information, enc_password=encrypted_password, regex=password_information ).create_new_row() if status == "ok": info("password stored successfully") elif status == "exists": warning( "provided information already exists in the database. " "if you are trying to update the information use the `-u/--update` switch" ) else: fatal("unable to add row to database, received an error: {}".format(status)) if opt.regexToSearch is not None: data = SQL(regex=opt.regexToSearch, connection=conn, cursor=cursor).display_by_regex() if len(data) == 0: error("no items matched your search") else: info("a total of {} item(s) matched your search".format(len(data))) display_formatted_list_output( data, stored_key, prompting=opt.doNotPrompt, answer=opt.promptAnswer ) if opt.updateExistingPassword is not None: apparent_possible_passwords = SQL( regex=opt.updateExistingPassword, connection=conn, cursor=cursor ).display_by_regex() if len(apparent_possible_passwords) == 0: fatal("no apparent existing passwords found with given string") else: info("{} possible passwords found to edit".format(len(apparent_possible_passwords))) for i, item in enumerate(apparent_possible_passwords): print("[{}] {}".format(i, item[0])) choice = prompt("choose an item to edit[0-{}]: ".format(len(apparent_possible_passwords) - 1)) if int(choice) in range(len(apparent_possible_passwords)): information = prompt("enter the new information for the update: ") password = prompt("enter the new password to update: ", hide=True) result = SQL( connection=conn, cursor=cursor, to_update=(information, AESCipher(stored_key).encrypt(password)), information=apparent_possible_passwords[int(choice)] ).update_existing_column() if result == "ok": info("password updated successfully") else: fatal("issue updating password: {}".format(result)) if opt.batchStore: stored_items = [] to_store = create_data_tuples(stored_key) for item in to_store: res = SQL( connection=conn, cursor=cursor, information=item[0], enc_password=item[1] ).create_new_row(regex=item[0]) stored_items.append(res) amount_stored = len([r for r in stored_items if r == "ok"]) amount_not_stored = len([r for r in stored_items if r == "exists"]) info("{} password(s) stored in database ({} already existed in database)".format( amount_stored, amount_not_stored )) if opt.cleanHomeFolder: secure_delete(MAIN_DIR) info("all data has been deleted") clear_cache(LETMEIN_CACHE) exit(0) except KeyboardInterrupt: error("user quit")