From fdad053694b878a7f3b9d27febba4164e778f622 Mon Sep 17 00:00:00 2001 From: Aaron Lichtman Date: Fri, 3 May 2019 02:42:06 -0500 Subject: [PATCH] Add crontab persistence and LoginHook persistence (#29) * Add crontab persistence #17 * Shorten URL * Add LoginHook persistence method * Add comment for removal --- src/persistence/macOS/LoginHook.py | 37 ++++++++++++++++++++++++++++++ src/utils/utils.py | 13 +++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/persistence/macOS/LoginHook.py diff --git a/src/persistence/macOS/LoginHook.py b/src/persistence/macOS/LoginHook.py new file mode 100644 index 0000000..10123a2 --- /dev/null +++ b/src/persistence/macOS/LoginHook.py @@ -0,0 +1,37 @@ +# This approach is explained in Patrick Wardle's "Methods of Malware +# Persistence on macOS" paper on page 18. +# +# NOTE: Untested. + + +import os +import sys +sys.path.insert(0, "../..") +from utils.print import * +from utils.utils import choice + + +def main(): + action = choice("Establish persistence or remove persistence?", [" Establish", " Remove"]) + + if action == "establish": + print_blue("Establishing macOS persistence with LoginHook") + command = "sudo defaults write com.apple.loginwindow LoginHook" + path = input("Enter the path of a script you'd like to run on login.") + if not os.path.isfile(path): + print_red("ERROR: {} is not a file.".format(path)) + sys.exit(1) + + # TODO: Print stdout, stderr + run_cmd("{} {}".format(command, path)) + print_green("Persistence established.") + elif action == "remove": + print_blue("Removing macOS persistence with LoginHook") + command = "sudo defaults delete com.apple.loginwindow LoginHook" + # TODO: Print stdout, stderr + run_cmd("{} {}".format(command)) + print_green("Persistence removed.") + + +if __name__ == '__main__': + main() diff --git a/src/utils/utils.py b/src/utils/utils.py index 62486f1..821e21e 100644 --- a/src/utils/utils.py +++ b/src/utils/utils.py @@ -1,5 +1,7 @@ +import inquirer import platform import subprocess as sp +from colorama import Fore, Style def get_os_name(): @@ -16,3 +18,14 @@ def run_cmd(command): else: process = sp.run(command, stdout=sp.PIPE, stderr=sp.DEVNULL) return process + + +def choice(question, choices): + """ + Displays list of choices and returns the one that was selected. + """ + choice_prompt = [inquirer.List('choice', + message=Fore.GREEN + Style.BRIGHT + question + Fore.BLUE, + choices=choices) + ] + return inquirer.prompt(choice_prompt).get('choice').strip()