138 lines
4.3 KiB
Python
138 lines
4.3 KiB
Python
# Contributed by Kelly Kranabetter.
|
|
import os
|
|
import sys
|
|
|
|
import ntsecuritycon
|
|
import pywintypes
|
|
import win32security
|
|
import winerror
|
|
|
|
# get security information
|
|
# name=r"c:\autoexec.bat"
|
|
# name= r"g:\!workgrp\lim"
|
|
name = sys.argv[0]
|
|
|
|
if not os.path.exists(name):
|
|
print(name, "does not exist!")
|
|
sys.exit()
|
|
|
|
print("On file ", name, "\n")
|
|
|
|
# get owner SID
|
|
print("OWNER")
|
|
try:
|
|
sd = win32security.GetFileSecurity(name, win32security.OWNER_SECURITY_INFORMATION)
|
|
sid = sd.GetSecurityDescriptorOwner()
|
|
print(" ", win32security.LookupAccountSid(None, sid))
|
|
except pywintypes.error as exc:
|
|
# in automation and network shares we see:
|
|
# pywintypes.error: (1332, 'LookupAccountName', 'No mapping between account names and security IDs was done.')
|
|
if exc.winerror != winerror.ERROR_NONE_MAPPED:
|
|
raise
|
|
print("No owner information is available")
|
|
|
|
# get group SID
|
|
try:
|
|
print("GROUP")
|
|
sd = win32security.GetFileSecurity(name, win32security.GROUP_SECURITY_INFORMATION)
|
|
sid = sd.GetSecurityDescriptorGroup()
|
|
print(" ", win32security.LookupAccountSid(None, sid))
|
|
except pywintypes.error as exc:
|
|
if exc.winerror != winerror.ERROR_NONE_MAPPED:
|
|
raise
|
|
print("No group information is available")
|
|
|
|
# get ACEs
|
|
sd = win32security.GetFileSecurity(name, win32security.DACL_SECURITY_INFORMATION)
|
|
dacl = sd.GetSecurityDescriptorDacl()
|
|
if dacl == None:
|
|
print("No Discretionary ACL")
|
|
else:
|
|
for ace_no in range(0, dacl.GetAceCount()):
|
|
ace = dacl.GetAce(ace_no)
|
|
print("ACE", ace_no)
|
|
|
|
print(" -Type")
|
|
for i in (
|
|
"ACCESS_ALLOWED_ACE_TYPE",
|
|
"ACCESS_DENIED_ACE_TYPE",
|
|
"SYSTEM_AUDIT_ACE_TYPE",
|
|
"SYSTEM_ALARM_ACE_TYPE",
|
|
):
|
|
if getattr(ntsecuritycon, i) == ace[0][0]:
|
|
print(" ", i)
|
|
|
|
print(" -Flags", hex(ace[0][1]))
|
|
for i in (
|
|
"OBJECT_INHERIT_ACE",
|
|
"CONTAINER_INHERIT_ACE",
|
|
"NO_PROPAGATE_INHERIT_ACE",
|
|
"INHERIT_ONLY_ACE",
|
|
"SUCCESSFUL_ACCESS_ACE_FLAG",
|
|
"FAILED_ACCESS_ACE_FLAG",
|
|
):
|
|
if getattr(ntsecuritycon, i) & ace[0][1] == getattr(ntsecuritycon, i):
|
|
print(" ", i)
|
|
|
|
print(" -mask", hex(ace[1]))
|
|
|
|
# files and directories do permissions differently
|
|
permissions_file = (
|
|
"DELETE",
|
|
"READ_CONTROL",
|
|
"WRITE_DAC",
|
|
"WRITE_OWNER",
|
|
"SYNCHRONIZE",
|
|
"FILE_GENERIC_READ",
|
|
"FILE_GENERIC_WRITE",
|
|
"FILE_GENERIC_EXECUTE",
|
|
"FILE_DELETE_CHILD",
|
|
)
|
|
permissions_dir = (
|
|
"DELETE",
|
|
"READ_CONTROL",
|
|
"WRITE_DAC",
|
|
"WRITE_OWNER",
|
|
"SYNCHRONIZE",
|
|
"FILE_ADD_SUBDIRECTORY",
|
|
"FILE_ADD_FILE",
|
|
"FILE_DELETE_CHILD",
|
|
"FILE_LIST_DIRECTORY",
|
|
"FILE_TRAVERSE",
|
|
"FILE_READ_ATTRIBUTES",
|
|
"FILE_WRITE_ATTRIBUTES",
|
|
"FILE_READ_EA",
|
|
"FILE_WRITE_EA",
|
|
)
|
|
permissions_dir_inherit = (
|
|
"DELETE",
|
|
"READ_CONTROL",
|
|
"WRITE_DAC",
|
|
"WRITE_OWNER",
|
|
"SYNCHRONIZE",
|
|
"GENERIC_READ",
|
|
"GENERIC_WRITE",
|
|
"GENERIC_EXECUTE",
|
|
"GENERIC_ALL",
|
|
)
|
|
if os.path.isfile(name):
|
|
permissions = permissions_file
|
|
else:
|
|
permissions = permissions_dir
|
|
# directories also contain an ACE that is inherited by children (files) within them
|
|
if (
|
|
ace[0][1] & ntsecuritycon.OBJECT_INHERIT_ACE
|
|
== ntsecuritycon.OBJECT_INHERIT_ACE
|
|
and ace[0][1] & ntsecuritycon.INHERIT_ONLY_ACE
|
|
== ntsecuritycon.INHERIT_ONLY_ACE
|
|
):
|
|
permissions = permissions_dir_inherit
|
|
|
|
calc_mask = 0 # calculate the mask so we can see if we are printing all of the permissions
|
|
for i in permissions:
|
|
if getattr(ntsecuritycon, i) & ace[1] == getattr(ntsecuritycon, i):
|
|
calc_mask = calc_mask | getattr(ntsecuritycon, i)
|
|
print(" ", i)
|
|
print(" ", "Calculated Check Mask=", hex(calc_mask))
|
|
print(" -SID\n ", win32security.LookupAccountSid(None, ace[2]))
|