Skip to content

Instantly share code, notes, and snippets.

@wdormann
Last active April 30, 2021 13:07
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save wdormann/0464e45bf48a8fe791553af710218a51 to your computer and use it in GitHub Desktop.
Save wdormann/0464e45bf48a8fe791553af710218a51 to your computer and use it in GitHub Desktop.
List privileged services that don't come with Windows 10 - deprecated
# DON'T USE THIS VERSION!
# Try https://gist.github.com/wdormann/89ed779933fe205fb52ecf3eacf5ff40 instead
import os
import subprocess
# See: https://blogs.msmvps.com/erikr/2007/09/26/set-permissions-on-a-specific-service-windows/
svcinfo = {}
FNULL = open(os.devnull, 'w')
win10builtin = ['AppVClient', 'ClickToRunSvc', 'COMSysApp', 'diagnosticshub.standardcollector.service',
'msiserver', 'ose', 'perceptionsimulation', 'SecurityHealthService', 'Sense',
'SensorDataService', 'SgrmBroker', 'Spooler', 'ssh-agent', 'TieringEngineService',
'TrustedInstaller', 'UevAgentService', 'vds', 'VSS', 'wbengine', 'WinDefend', 'wmiApSrv',
'WSearch']
def sliceperms(permstring):
permparts = []
if permstring:
parts = int(len(permstring))
# print('%s parts' % parts)
for i in range(0, parts, 2):
# print(permstring[i:i+2])
permparts.append(permstring[i:i + 2])
return permparts
def getsvcacls(svcname):
svcacl = None
try:
svcacl = subprocess.check_output(['sc', 'sdshow', svcname], stderr=FNULL).decode('utf-8',
'backslashreplace').strip()
except subprocess.CalledProcessError:
pass
return svcacl
def whichfile(file):
if file:
fullpath = ''
try:
fullpath = subprocess.check_output(['where', file, ], stderr=FNULL).decode('utf-8',
'backslashreplace').strip()
except subprocess.CalledProcessError:
pass
return fullpath
def svchosttarget(svcname):
parsed = ''
svctarget = ''
try:
parsed = subprocess.check_output(['reg', 'query',
r'HKLM\SYSTEM\CurrentControlSet\Services\%s\Parameters' %
svcname], stderr=FNULL).decode('utf-8', 'backslashreplace')
except subprocess.CalledProcessError:
pass
for line in parsed.splitlines():
if ' servicedll ' in line.lower():
lineparts = line.split(' REG_EXPAND_SZ ')
svctarget = os.path.expandvars((lineparts[-1]))
if not os.path.exists(svctarget):
svctarget = whichfile(svctarget)
return svctarget
def checkservices():
nameindex = None
dispnameindex = None
privindex = None
stateindex = None
pathindex = None
startmodeindex = None
parsed = subprocess.check_output(['wmic', 'service', 'get', 'name,startname,displayname,state,pathname,startmode,'
'DesktopInteract',
'/format:csv'], stderr=FNULL).decode(
'utf-8', 'backslashreplace')
for line in parsed.splitlines():
if line:
columns = line.split(',')
if line.startswith('Node,'):
nameindex = columns.index('Name')
dispnameindex = columns.index('DisplayName')
privindex = columns.index('StartName')
stateindex = columns.index('State')
pathindex = columns.index('PathName')
startmodeindex = columns.index('StartMode')
desktopindex = columns.index('DesktopInteract')
else:
reasons = []
svcname = columns[nameindex]
svcdict = {}
svcdict['priv'] = columns[privindex]
svcdict['dispname'] = columns[dispnameindex]
svcdict['state'] = columns[stateindex]
svcdict['path'] = columns[pathindex]
svcdict['startmode'] = columns[startmodeindex]
svcdict['desktop'] = columns[desktopindex]
if svcdict['desktop'].lower() == 'true':
svcdict['desktop'] = True
else:
svcdict['desktop'] = False
if 'svchost.exe' in svcdict['path']:
realtarget = svchosttarget(svcname)
if realtarget:
# print('%s uses svchost: %s' % (svcname,realtarget))
svcdict['path'] = realtarget
elif '"' in svcdict['path']:
# Quoted path
splitpath = svcdict['path'].split('"')
if len(splitpath) > 2 and splitpath[2]:
# Quoted path with arguments
svcdict['path'] = '"%s"' % splitpath[1]
else:
# Quoted path without arguments
pass
else:
# Non-quoted path
splitpath = svcdict['path'].split()
if len(splitpath) > 1:
# Non-quoted path with arguments
svcdict['path'] = splitpath[0]
svcinfo[svcname] = svcdict
if (svcdict['priv'].lower() == 'localsystem') and not svcdict[
'path'].endswith('lsass.exe') and svcdict['path'].lower().replace('"', '').endswith('.exe'):
reasons.append('User-controlled and high-privileged')
reasons = ', '.join(reasons)
if reasons and svcname not in win10builtin:
print('Service: %s' % svcname)
print('Display name: %s' % svcinfo[svcname]['dispname'])
print('Privilege: %s' % svcinfo[svcname]['priv'])
print('Path: %s' % svcinfo[svcname]['path'])
print('')
if __name__ == "__main__":
checkservices()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment