Skip to content

Commit

Permalink
added a method to disable a service, fixed what happens when the remo…
Browse files Browse the repository at this point in the history
…te reg is disabled
  • Loading branch information
ghost-ng committed Jan 13, 2024
1 parent 5571fb6 commit 84448a3
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 13 deletions.
4 changes: 3 additions & 1 deletion TODO..md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@
- sc modify

### Test
- test on a domain
- test on a domain

### General
2 changes: 1 addition & 1 deletion src/slingerpkg/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = '0.5.1'
__version__ = '0.6.0'
__package__ = 'slinger'
97 changes: 88 additions & 9 deletions src/slingerpkg/lib/dcetransport.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,21 @@ def _enable_remote_registry(self):
self.rrpstarted = True
else:
print_info("Trying to start RemoteRegistry service")
response = self._start_service('RemoteRegistry', bind=False)
self.rrpstarted = True
self.rrpshouldStop = True
print_good("Remote Registry service started")
self._connect('svcctl')
response = self._start_service('RemoteRegistry', bind=True)
if response == "DISABLED":
self.rrpshouldDisable = True
print_bad("Remote Registry service is disabled")
self._connect('svcctl')
print_info("Trying to enable RemoteRegistry service")
_ = self._enable_service("RemoteRegistry")
_ = self._start_service('RemoteRegistry', bind=False)
print_info("Checking the status of the RemoteRegistry service")
response = self._checkServiceStatus("RemoteRegistry")
if response:
self.rrpshouldStop = True
self.rrpstarted = True
print_good("Remote Registry service started")

def _close_scm_handle(self, serviceHandle):
try:
Expand All @@ -128,6 +139,10 @@ def _disconnect(self):
self._connect('svcctl')
self._stop_service("RemoteRegistry")
print_info("Remote Registy state restored -> STOPPED")
if self.rrpshouldDisable:
self._connect('svcctl')
self._disable_service("RemoteRegistry")
print_info("Remote Registy state restored -> DISABLED")
self.dce.disconnect()
self.is_connected = False

Expand Down Expand Up @@ -270,6 +285,54 @@ def _enum_services(self):
self._close_scm_handle(self.scManagerHandle)
return response

def _disable_service(self, service_name):
if not self.is_connected:
raise Exception("Not connected to remote host")
self.bind_override = True
self._bind(scmr.MSRPC_UUID_SCMR)
ans = scmr.hROpenSCManagerW(self.dce)
self.scManagerHandle = ans['lpScHandle']
ans = scmr.hROpenServiceW(self.dce, self.scManagerHandle, service_name + '\x00')
self.serviceHandle = ans['lpServiceHandle']
try:
response = scmr.hRChangeServiceConfigW(self.dce, self.serviceHandle, dwStartType=scmr.SERVICE_DISABLED)
self._close_scm_handle(self.serviceHandle)
if response['ErrorCode'] == 0:
return True
else:
return False
except Exception as e:
print_debug(str(e), sys.exc_info())
if "ERROR_ACCESS_DENIED" in str(e):
print_bad("Unable to change service configuration, access denied")
else:
print_bad("An error occurred: " + str(e))
return False

def _enable_service(self, service_name):
if not self.is_connected:
raise Exception("Not connected to remote host")
self.bind_override = True
self._bind(scmr.MSRPC_UUID_SCMR)
ans = scmr.hROpenSCManagerW(self.dce)
self.scManagerHandle = ans['lpScHandle']
ans = scmr.hROpenServiceW(self.dce, self.scManagerHandle, service_name + '\x00')
self.serviceHandle = ans['lpServiceHandle']
try:
response = scmr.hRChangeServiceConfigW(self.dce, self.serviceHandle, dwStartType=scmr.SERVICE_AUTO_START)
self._close_scm_handle(self.serviceHandle)
if response['ErrorCode'] == 0:
return True
else:
return False
except Exception as e:
print_debug(str(e), sys.exc_info())
if "ERROR_ACCESS_DENIED" in str(e):
print_bad("Unable to change service configuration, access denied")
else:
print_bad("An error occurred: " + str(e))
return False

def _get_service_details(self, service_name):
if not self.is_connected:
raise Exception("Not connected to remote host")
Expand Down Expand Up @@ -303,11 +366,27 @@ def _start_service(self, service_name, bind=True):
raise e
return
serviceHandle = ans['lpServiceHandle']
response = scmr.hRStartServiceW(self.dce, serviceHandle)
self._close_scm_handle(serviceHandle)
if service_name == "RemoteRegistry":
self.rrpstarted = True
return response
try:
response = scmr.hRStartServiceW(self.dce, serviceHandle)
self._close_scm_handle(serviceHandle)
if service_name == "RemoteRegistry":
self.rrpstarted = True
if response['ErrorCode'] == 0:

return True
except Exception as e:
if "ERROR_SERVICE_DISABLED" in str(e):
return "DISABLED"
elif "ERROR_SERVICE_ALREADY_RUNNING" in str(e):
return "RUNNING"
elif "ERROR_ACCESS_DENIED" in str(e):
print_bad("Unable to start service, access denied")
return False
else:
print_debug(str(e), sys.exc_info())
return False



def _stop_service(self, service_name):
if not self.is_connected:
Expand Down
92 changes: 91 additions & 1 deletion src/slingerpkg/lib/scm.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,90 @@ def start_service_handler(self, args):
service_arg = args.serviceid if args.serviceid else args.service_name
self.start_service(service_arg)

def enable_service_handler(self, args):
if not self.services_list and args.serviceid:
print_warning("No services have been enumerated. Run enumservices first.")
else:
service_arg = args.serviceid if args.serviceid else args.service_name
self.enable_service(service_arg)

def disable_service_handler(self, args):
if not self.services_list and args.serviceid:
print_warning("No services have been enumerated. Run enumservices first.")
else:
service_arg = args.serviceid if args.serviceid else args.service_name
self.disable_service(service_arg)

def disable_service(self, service_arg):
self.setup_dce_transport()
self.dce_transport._connect('svcctl')

# lookup taskpath and task name from dict with task_id
service_name = None
if type(service_arg) is int:
print_info("Looking up service ID...")
count = 1
#print_log("Searching through %d services" % len(self.services_list))
for service in self.services_list:
#print_info("Checking service %d" % count)
if count == service_arg:
service_name = service[1]
break
count += 1
else:
service_name = service_arg

if service_name is None:
print_warning("Service name not found")
return
else:
print_info("Chosen Service: " + service_name)
try:
response = self.dce_transport._disable_service(service_name)
if response:
print_good("Service disabled successfully")
else:
print_log(f"Error disabling service '{service_name}': {response['ErrorCode']}")
except Exception as e:
print_bad("Unable to disable service: " + service_name)
print_bad("An error occurred:" + str(e))
print_debug('', sys.exc_info())

def enable_service(self, service_arg):
self.setup_dce_transport()
self.dce_transport._connect('svcctl')
service_name = None
if type(service_arg) is int:
print_info("Looking up service ID...")
count = 1
#print_log("Searching through %d services" % len(self.services_list))
for service in self.services_list:
#print_info("Checking service %d" % count)
if count == service_arg:
service_name = service[1]
break
count += 1
else:
service_name = service_arg

if service_name is None:
print_warning("Service name not found")
return
else:
print_info("Chosen Service: " + service_name)

try:
print_info(f"Trying to enable service {service_name}")
response = self.dce_transport._enable_service(service_name)
if response:
print_good("Service enabled successfully")
else:
print_log(f"Error enabling service '{service_name}': {response['ErrorCode']}")
except Exception as e:
print_bad("Unable to enable service: " + service_name)
print_bad("An error occurred:" + str(e))
print_debug('', sys.exc_info())

def start_service(self, service_arg):
self.setup_dce_transport()
self.dce_transport._connect('svcctl')
Expand Down Expand Up @@ -70,7 +154,13 @@ def start_service(self, service_arg):
print_info("Chosen Service: " + service_name)
try:
response = self.dce_transport._start_service(service_name)
if response['ErrorCode'] == 0:
if response == "DISABLED":
print_warning("Failed to start service: " + service_name)
print_warning("Service disabled")
return
elif response is False:
return
elif response is True:
print_good("Service started successfully")
else:
print_log(f"Error starting service '{service_name}': {response['ErrorCode']}")
Expand Down
10 changes: 9 additions & 1 deletion src/slingerpkg/lib/winreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,15 @@ def setup_remote_registry(self, args):
try:
print_info("Starting Remote Registry service")
response = self.dce_transport._start_service('RemoteRegistry')
print_good("Remote Registry service started")
if response == "DISABLED":
print_info("Trying to enable the Remote Registry service")
self.dcetransport._connect('winreg')
ans = self.dce_transport._enable_service('RemoteRegistry')

if ans != False:
print_good("Remote Registry service started")
else:
print_bad("Failed to start Remote Registry service")

except Exception as e:

Expand Down
14 changes: 14 additions & 0 deletions src/slingerpkg/utils/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,20 @@ def setup_cli_parser(slingerClient):
svcstopgroup.add_argument('-i', '--serviceid', type=int, help='Specify the ID of the service to stop')
svcstopgroup.add_argument('service_name', type=str, nargs='?', help='Specify the name of the service to stop')

# Subparser for 'serviceenable' command
parser_svcenable = subparsers.add_parser('serviceenable', help='Enable a service', description='Enable a specified service on the remote server', epilog='Example Usage: serviceenable -i 123 OR svcenable Spooler', aliases=['svcenable','enableservice', 'enablesvc'])
parser_svcenable.set_defaults(func=slingerClient.enable_service_handler)
svcenablegroup = parser_svcenable.add_mutually_exclusive_group(required=True)
svcenablegroup.add_argument('-i', '--serviceid', type=int, help='Specify the ID of the service to enable')
svcenablegroup.add_argument('service_name', type=str, nargs='?', help='Specify the name of the service to enable')

# Subparser for 'servicedisable' command
parser_svcdisable = subparsers.add_parser('servicedisable', help='Disable a service', description='Disable a specified service on the remote server', epilog='Example Usage: servicedisable -i 123 OR svcdisable Spooler', aliases=['svcdisable','disableservice', 'disablesvc'])
parser_svcdisable.set_defaults(func=slingerClient.disable_service_handler)
svcdisablegroup = parser_svcdisable.add_mutually_exclusive_group(required=True)
svcdisablegroup.add_argument('-i', '--serviceid', type=int, help='Specify the ID of the service to disable')
svcdisablegroup.add_argument('service_name', type=str, nargs='?', help='Specify the name of the service to disable')

# Subparser for 'servicedel' command
parser_svcdelete = subparsers.add_parser('servicedel', help='Delete a service', description='Delete a specified service on the remote server', epilog='Example Usage: servicedelete -i 123 OR svcdelete Spooler', aliases=['svcdelete','servicedelete'])
svcdeletegroup = parser_svcdelete.add_mutually_exclusive_group(required=True)
Expand Down

0 comments on commit 84448a3

Please sign in to comment.