Todo: 集成多平台 解决因SaiNiu线程抢占资源问题 本地提交测试环境打包 和 正式打包脚本与正式环境打包bat 提交Python32环境包 改进多日志文件生成情况修改打包日志细节

This commit is contained in:
2025-09-18 15:52:03 +08:00
parent 8b9fc925fa
commit 7cfc0c22b7
7608 changed files with 2424791 additions and 25 deletions

View File

@@ -0,0 +1,110 @@
"""Lists various types of information about current user's access token,
including UAC status on Vista
"""
import pywintypes
import win32api
import win32con
import win32security
import winerror
from security_enums import (
SECURITY_IMPERSONATION_LEVEL,
TOKEN_ELEVATION_TYPE,
TOKEN_GROUP_ATTRIBUTES,
TOKEN_PRIVILEGE_ATTRIBUTES,
TOKEN_TYPE,
)
def dump_token(th):
token_type = win32security.GetTokenInformation(th, win32security.TokenType)
print("TokenType:", token_type, TOKEN_TYPE.lookup_name(token_type))
if token_type == win32security.TokenImpersonation:
imp_lvl = win32security.GetTokenInformation(
th, win32security.TokenImpersonationLevel
)
print(
"TokenImpersonationLevel:",
imp_lvl,
SECURITY_IMPERSONATION_LEVEL.lookup_name(imp_lvl),
)
print(
"TokenSessionId:",
win32security.GetTokenInformation(th, win32security.TokenSessionId),
)
privs = win32security.GetTokenInformation(th, win32security.TokenPrivileges)
print("TokenPrivileges:")
for priv_luid, priv_flags in privs:
flag_names, unk = TOKEN_PRIVILEGE_ATTRIBUTES.lookup_flags(priv_flags)
flag_desc = " ".join(flag_names)
if unk:
flag_desc += f"({unk})"
priv_name = win32security.LookupPrivilegeName("", priv_luid)
priv_desc = win32security.LookupPrivilegeDisplayName("", priv_name)
print("\t", priv_name, priv_desc, priv_flags, flag_desc)
print("TokenGroups:")
groups = win32security.GetTokenInformation(th, win32security.TokenGroups)
for group_sid, group_attr in groups:
flag_names, unk = TOKEN_GROUP_ATTRIBUTES.lookup_flags(group_attr)
flag_desc = " ".join(flag_names)
if unk:
flag_desc += f"({unk})"
if group_attr & TOKEN_GROUP_ATTRIBUTES.SE_GROUP_LOGON_ID:
sid_desc = "Logon sid"
else:
sid_desc = win32security.LookupAccountSid("", group_sid)
print("\t", group_sid, sid_desc, group_attr, flag_desc)
## Vista token information types, will throw (87, 'GetTokenInformation', 'The parameter is incorrect.') on earier OS
try:
is_elevated = win32security.GetTokenInformation(
th, win32security.TokenElevation
)
print("TokenElevation:", is_elevated)
except pywintypes.error as details:
if details.winerror != winerror.ERROR_INVALID_PARAMETER:
raise
return None
print(
"TokenHasRestrictions:",
win32security.GetTokenInformation(th, win32security.TokenHasRestrictions),
)
print(
"TokenMandatoryPolicy",
win32security.GetTokenInformation(th, win32security.TokenMandatoryPolicy),
)
print(
"TokenVirtualizationAllowed:",
win32security.GetTokenInformation(th, win32security.TokenVirtualizationAllowed),
)
print(
"TokenVirtualizationEnabled:",
win32security.GetTokenInformation(th, win32security.TokenVirtualizationEnabled),
)
elevation_type = win32security.GetTokenInformation(
th, win32security.TokenElevationType
)
print(
"TokenElevationType:",
elevation_type,
TOKEN_ELEVATION_TYPE.lookup_name(elevation_type),
)
if elevation_type != win32security.TokenElevationTypeDefault:
lt = win32security.GetTokenInformation(th, win32security.TokenLinkedToken)
print("TokenLinkedToken:", lt)
else:
lt = None
return lt
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(ph, win32con.MAXIMUM_ALLOWED)
lt = dump_token(th)
if lt:
print("\n\nlinked token info:")
dump_token(lt)

View File

@@ -0,0 +1,49 @@
import ntsecuritycon
import win32api
import win32con
import win32security
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", "SeEnableDelegationPrivilege"),
win32con.SE_PRIVILEGE_ENABLED,
), ##doesn't seem to be in ntsecuritycon.py ?
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
policy_handle = win32security.GetPolicyHandle("", win32security.POLICY_ALL_ACCESS)
tmp_sid = win32security.LookupAccountName("", "tmp")[0]
privs = [
ntsecuritycon.SE_DEBUG_NAME,
ntsecuritycon.SE_TCB_NAME,
ntsecuritycon.SE_RESTORE_NAME,
ntsecuritycon.SE_REMOTE_SHUTDOWN_NAME,
]
win32security.LsaAddAccountRights(policy_handle, tmp_sid, privs)
privlist = win32security.LsaEnumerateAccountRights(policy_handle, tmp_sid)
for priv in privlist:
print(priv)
privs = [ntsecuritycon.SE_DEBUG_NAME, ntsecuritycon.SE_TCB_NAME]
win32security.LsaRemoveAccountRights(policy_handle, tmp_sid, 0, privs)
privlist = win32security.LsaEnumerateAccountRights(policy_handle, tmp_sid)
for priv in privlist:
print(priv)
win32security.LsaClose(policy_handle)

View File

@@ -0,0 +1,170 @@
import os
import ntsecuritycon
import win32api
import win32con
import win32security
from security_enums import ACCESS_MODE, ACE_FLAGS, TRUSTEE_FORM, TRUSTEE_TYPE
fname = os.path.join(win32api.GetTempPath(), "win32security_test.txt")
f = open(fname, "w")
f.write("Hello from Python\n")
f.close()
print("Testing on file", fname)
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", "SeEnableDelegationPrivilege"),
win32con.SE_PRIVILEGE_ENABLED,
), ##doesn't seem to be in ntsecuritycon.py ?
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
all_security_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
sd = win32security.GetFileSecurity(fname, all_security_info)
old_sacl = sd.GetSecurityDescriptorSacl()
if old_sacl is None:
old_sacl = win32security.ACL()
old_dacl = sd.GetSecurityDescriptorDacl()
if old_dacl is None:
old_dacl = win32security.ACL()
my_sid = win32security.GetTokenInformation(th, ntsecuritycon.TokenUser)[0]
tmp_sid = win32security.LookupAccountName("", "tmp")[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
## MultipleTrustee,MultipleTrusteeOperation,TrusteeForm,TrusteeType,Identifier
## first two are ignored
my_trustee = {}
my_trustee["MultipleTrustee"] = None
my_trustee["MultipleTrusteeOperation"] = 0
my_trustee["TrusteeForm"] = TRUSTEE_FORM.TRUSTEE_IS_SID
my_trustee["TrusteeType"] = TRUSTEE_TYPE.TRUSTEE_IS_USER
my_trustee["Identifier"] = my_sid
tmp_trustee = {}
tmp_trustee["MultipleTrustee"] = None
tmp_trustee["MultipleTrusteeOperation"] = 0
tmp_trustee["TrusteeForm"] = TRUSTEE_FORM.TRUSTEE_IS_NAME
tmp_trustee["TrusteeType"] = TRUSTEE_TYPE.TRUSTEE_IS_USER
tmp_trustee["Identifier"] = "rupole\\tmp"
pwr_trustee = {}
pwr_trustee["MultipleTrustee"] = None
pwr_trustee["MultipleTrusteeOperation"] = 0
pwr_trustee["TrusteeForm"] = TRUSTEE_FORM.TRUSTEE_IS_SID
pwr_trustee["TrusteeType"] = TRUSTEE_TYPE.TRUSTEE_IS_USER
pwr_trustee["Identifier"] = pwr_sid
expl_list = []
expl_list.append(
{
"Trustee": my_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.SET_AUDIT_SUCCESS, ##|ACCESS_MODE.SET_AUDIT_FAILURE,
"AccessPermissions": win32con.GENERIC_ALL,
}
)
expl_list.append(
{
"Trustee": my_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.SET_AUDIT_FAILURE,
"AccessPermissions": win32con.GENERIC_ALL,
}
)
expl_list.append(
{
"Trustee": tmp_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.SET_AUDIT_SUCCESS,
"AccessPermissions": win32con.GENERIC_ALL,
}
)
expl_list.append(
{
"Trustee": tmp_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.SET_AUDIT_FAILURE,
"AccessPermissions": win32con.GENERIC_ALL,
}
)
old_sacl.SetEntriesInAcl(expl_list)
expl_list = []
expl_list.append(
{
"Trustee": tmp_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.DENY_ACCESS,
"AccessPermissions": win32con.DELETE,
}
)
expl_list.append(
{
"Trustee": tmp_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.GRANT_ACCESS,
"AccessPermissions": win32con.WRITE_OWNER,
}
)
expl_list.append(
{
"Trustee": pwr_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.GRANT_ACCESS,
"AccessPermissions": win32con.GENERIC_READ,
}
)
expl_list.append(
{
"Trustee": my_trustee,
"Inheritance": ACE_FLAGS.NO_INHERITANCE,
"AccessMode": ACCESS_MODE.GRANT_ACCESS,
"AccessPermissions": win32con.GENERIC_ALL,
}
)
old_dacl.SetEntriesInAcl(expl_list)
sd.SetSecurityDescriptorSacl(1, old_sacl, 1)
sd.SetSecurityDescriptorDacl(1, old_dacl, 1)
sd.SetSecurityDescriptorOwner(pwr_sid, 1)
win32security.SetFileSecurity(fname, all_security_info, sd)

View File

@@ -0,0 +1,39 @@
import win32security
policy_handle = win32security.GetPolicyHandle("rupole", win32security.POLICY_ALL_ACCESS)
# mod_nbr, mod_time = win32security.LsaQueryInformationPolicy(policy_handle,win32security.PolicyModificationInformation)
# print(mod_nbr, mod_time)
(
domain_name,
dns_domain_name,
dns_forest_name,
domain_guid,
domain_sid,
) = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyDnsDomainInformation
)
print(domain_name, dns_domain_name, dns_forest_name, domain_guid, domain_sid)
event_audit_info = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyAuditEventsInformation
)
print(event_audit_info)
domain_name, sid = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyPrimaryDomainInformation
)
print(domain_name, sid)
domain_name, sid = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyAccountDomainInformation
)
print(domain_name, sid)
server_role = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyLsaServerRoleInformation
)
print("server role: ", server_role)
win32security.LsaClose(policy_handle)

View File

@@ -0,0 +1,35 @@
import ntsecuritycon
import win32api
import win32con
import win32security
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", "SeEnableDelegationPrivilege"),
win32con.SE_PRIVILEGE_ENABLED,
), ##doesn't seem to be in ntsecuritycon.py ?
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
policy_handle = win32security.GetPolicyHandle("", win32security.POLICY_ALL_ACCESS)
sidlist = win32security.LsaEnumerateAccountsWithUserRight(
policy_handle, ntsecuritycon.SE_RESTORE_NAME
)
for sid in sidlist:
print(win32security.LookupAccountSid("", sid))
win32security.LsaClose(policy_handle)

View File

@@ -0,0 +1,70 @@
# A Python port of the MS knowledge base article Q157234
# "How to deal with localized and renamed user and group names"
# https://www.betaarchive.com/wiki/index.php?title=Microsoft_KB_Archive/157234
import sys
import pywintypes
from ntsecuritycon import (
DOMAIN_ALIAS_RID_ADMINS,
DOMAIN_USER_RID_ADMIN,
SECURITY_BUILTIN_DOMAIN_RID,
SECURITY_NT_AUTHORITY,
)
from win32net import NetUserModalsGet
from win32security import LookupAccountSid
def LookupAliasFromRid(TargetComputer, Rid):
# Sid is the same regardless of machine, since the well-known
# BUILTIN domain is referenced.
sid = pywintypes.SID()
sid.Initialize(SECURITY_NT_AUTHORITY, 2)
for i, r in enumerate((SECURITY_BUILTIN_DOMAIN_RID, Rid)):
sid.SetSubAuthority(i, r)
name, domain, typ = LookupAccountSid(TargetComputer, sid)
return name
def LookupUserGroupFromRid(TargetComputer, Rid):
# get the account domain Sid on the target machine
# note: if you were looking up multiple sids based on the same
# account domain, only need to call this once.
umi2 = NetUserModalsGet(TargetComputer, 2)
domain_sid = umi2["domain_id"]
SubAuthorityCount = domain_sid.GetSubAuthorityCount()
# create and init new sid with acct domain Sid + acct Rid
sid = pywintypes.SID()
sid.Initialize(domain_sid.GetSidIdentifierAuthority(), SubAuthorityCount + 1)
# copy existing subauthorities from account domain Sid into
# new Sid
for i in range(SubAuthorityCount):
sid.SetSubAuthority(i, domain_sid.GetSubAuthority(i))
# append Rid to new Sid
sid.SetSubAuthority(SubAuthorityCount, Rid)
name, domain, typ = LookupAccountSid(TargetComputer, sid)
return name
def main():
if len(sys.argv) == 2:
targetComputer = sys.argv[1]
else:
targetComputer = None
name = LookupUserGroupFromRid(targetComputer, DOMAIN_USER_RID_ADMIN)
print(f"'Administrator' user name = {name}")
name = LookupAliasFromRid(targetComputer, DOMAIN_ALIAS_RID_ADMINS)
print(f"'Administrators' local group/alias name = {name}")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,14 @@
import win32event
import win32security
evt = win32event.CreateEvent(None, 0, 0, None)
win32security.LsaRegisterPolicyChangeNotification(
win32security.PolicyNotifyAuditEventsInformation, evt
)
print("Waiting for you change Audit policy in Management console ...")
ret_code = win32event.WaitForSingleObject(evt, 1000000000)
## should come back when you change Audit policy in Management console ...
print(ret_code)
win32security.LsaUnregisterPolicyChangeNotification(
win32security.PolicyNotifyAuditEventsInformation, evt
)

View File

@@ -0,0 +1,12 @@
import win32security
policy_handle = win32security.GetPolicyHandle("", win32security.POLICY_ALL_ACCESS)
privatedata = "some sensitive data"
keyname = "tmp"
win32security.LsaStorePrivateData(policy_handle, keyname, privatedata)
retrieveddata = win32security.LsaRetrievePrivateData(policy_handle, keyname)
assert retrieveddata == privatedata
## passing None deletes key
win32security.LsaStorePrivateData(policy_handle, keyname, None)
win32security.LsaClose(policy_handle)

View File

@@ -0,0 +1,25 @@
import win32api
import win32security
import winerror
from ntsecuritycon import TOKEN_QUERY, TokenUser
# This is a Python implementation of win32api.GetDomainName()
def GetDomainName():
try:
tok = win32security.OpenThreadToken(win32api.GetCurrentThread(), TOKEN_QUERY, 1)
except win32api.error as details:
if details[0] != winerror.ERROR_NO_TOKEN:
raise
# attempt to open the process token, since no thread token
# exists
tok = win32security.OpenProcessToken(win32api.GetCurrentProcess(), TOKEN_QUERY)
sid, attr = win32security.GetTokenInformation(tok, TokenUser)
win32api.CloseHandle(tok)
name, dom, typ = win32security.LookupAccountSid(None, sid)
return dom
if __name__ == "__main__":
print("Domain name is", GetDomainName())

View File

@@ -0,0 +1,61 @@
fname = "h:\\tmp.reg"
import os
import ntsecuritycon
import pywintypes
import win32api
import win32con
import win32security
## regsave will not overwrite a file
if os.path.isfile(fname):
os.remove(fname)
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_BACKUP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS | win32con.TOKEN_ADJUST_PRIVILEGES
)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
my_sid = win32security.GetTokenInformation(th, ntsecuritycon.TokenUser)[0]
hklm = win32api.RegOpenKey(
win32con.HKEY_LOCAL_MACHINE, None, 0, win32con.KEY_ALL_ACCESS
)
skey = win32api.RegOpenKey(hklm, "SYSTEM", 0, win32con.KEY_ALL_ACCESS)
sa = pywintypes.SECURITY_ATTRIBUTES()
sd = pywintypes.SECURITY_DESCRIPTOR()
sa.SECURITY_DESCRIPTOR = sd
acl = pywintypes.ACL()
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
acl.AddAccessAllowedAce(
win32con.ACL_REVISION,
win32con.GENERIC_READ | win32con.ACCESS_SYSTEM_SECURITY,
my_sid,
)
sd.SetSecurityDescriptorDacl(1, acl, 0)
sd.SetSecurityDescriptorOwner(pwr_sid, 0)
sa.bInheritHandle = 1
assert sa.SECURITY_DESCRIPTOR is sd
win32api.RegSaveKey(skey, fname, sa)

View File

@@ -0,0 +1,36 @@
import ntsecuritycon
import win32api
import win32con
import win32security
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS | win32con.TOKEN_ADJUST_PRIVILEGES
)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
hkey = win32api.RegOpenKey(
win32con.HKEY_LOCAL_MACHINE, None, 0, win32con.KEY_ALL_ACCESS
)
win32api.RegCreateKey(hkey, "SYSTEM\\NOTMP")
notmpkey = win32api.RegOpenKey(
hkey, "SYSTEM\\notmp", 0, win32con.ACCESS_SYSTEM_SECURITY
)
tmp_sid = win32security.LookupAccountName("", "tmp")[0]
sacl = win32security.ACL()
sacl.AddAuditAccessAce(win32security.ACL_REVISION, win32con.GENERIC_ALL, tmp_sid, 1, 1)
sd = win32security.SECURITY_DESCRIPTOR()
sd.SetSecurityDescriptorSacl(1, sacl, 1)
win32api.RegSetKeySecurity(notmpkey, win32con.SACL_SECURITY_INFORMATION, sd)

View File

@@ -0,0 +1,8 @@
import pywintypes
import win32security
sa = pywintypes.SECURITY_ATTRIBUTES()
tmp_sid = win32security.LookupAccountName("", "tmp")[0]
sa.SetSecurityDescriptorOwner(tmp_sid, 0)
sid = sa.SECURITY_DESCRIPTOR.GetSecurityDescriptorOwner()
print(win32security.LookupAccountSid("", sid))

View File

@@ -0,0 +1,336 @@
import ntsecuritycon
import win32security
import winnt
class Enum:
def __init__(self, *const_names):
"""Accepts variable number of constant names that can be found in either
win32security, ntsecuritycon, or winnt."""
for const_name in const_names:
try:
const_val = getattr(win32security, const_name)
except AttributeError:
try:
const_val = getattr(ntsecuritycon, const_name)
except AttributeError:
try:
const_val = getattr(winnt, const_name)
except AttributeError:
raise AttributeError(
'Constant "%s" not found in win32security, ntsecuritycon, or winnt.'
% const_name
)
setattr(self, const_name, const_val)
def lookup_name(self, const_val):
"""Looks up the name of a particular value."""
for k, v in self.__dict__.items():
if v == const_val:
return k
raise AttributeError("Value %s not found in enum" % const_val)
def lookup_flags(self, flags):
"""Returns the names of all recognized flags in input, and any flags not found in the enum."""
flag_names = []
unknown_flags = flags
for k, v in self.__dict__.items():
if flags & v == v:
flag_names.append(k)
unknown_flags &= ~v
return flag_names, unknown_flags
TOKEN_INFORMATION_CLASS = Enum(
"TokenUser",
"TokenGroups",
"TokenPrivileges",
"TokenOwner",
"TokenPrimaryGroup",
"TokenDefaultDacl",
"TokenSource",
"TokenType",
"TokenImpersonationLevel",
"TokenStatistics",
"TokenRestrictedSids",
"TokenSessionId",
"TokenGroupsAndPrivileges",
"TokenSessionReference",
"TokenSandBoxInert",
"TokenAuditPolicy",
"TokenOrigin",
"TokenElevationType",
"TokenLinkedToken",
"TokenElevation",
"TokenHasRestrictions",
"TokenAccessInformation",
"TokenVirtualizationAllowed",
"TokenVirtualizationEnabled",
"TokenIntegrityLevel",
"TokenUIAccess",
"TokenMandatoryPolicy",
"TokenLogonSid",
)
TOKEN_TYPE = Enum("TokenPrimary", "TokenImpersonation")
TOKEN_ELEVATION_TYPE = Enum(
"TokenElevationTypeDefault", "TokenElevationTypeFull", "TokenElevationTypeLimited"
)
POLICY_AUDIT_EVENT_TYPE = Enum(
"AuditCategorySystem",
"AuditCategoryLogon",
"AuditCategoryObjectAccess",
"AuditCategoryPrivilegeUse",
"AuditCategoryDetailedTracking",
"AuditCategoryPolicyChange",
"AuditCategoryAccountManagement",
"AuditCategoryDirectoryServiceAccess",
"AuditCategoryAccountLogon",
)
POLICY_INFORMATION_CLASS = Enum(
"PolicyAuditLogInformation",
"PolicyAuditEventsInformation",
"PolicyPrimaryDomainInformation",
"PolicyPdAccountInformation",
"PolicyAccountDomainInformation",
"PolicyLsaServerRoleInformation",
"PolicyReplicaSourceInformation",
"PolicyDefaultQuotaInformation",
"PolicyModificationInformation",
"PolicyAuditFullSetInformation",
"PolicyAuditFullQueryInformation",
"PolicyDnsDomainInformation",
)
POLICY_LSA_SERVER_ROLE = Enum("PolicyServerRoleBackup", "PolicyServerRolePrimary")
## access modes for opening a policy handle - this is not a real enum
POLICY_ACCESS_MODES = Enum(
"POLICY_VIEW_LOCAL_INFORMATION",
"POLICY_VIEW_AUDIT_INFORMATION",
"POLICY_GET_PRIVATE_INFORMATION",
"POLICY_TRUST_ADMIN",
"POLICY_CREATE_ACCOUNT",
"POLICY_CREATE_SECRET",
"POLICY_CREATE_PRIVILEGE",
"POLICY_SET_DEFAULT_QUOTA_LIMITS",
"POLICY_SET_AUDIT_REQUIREMENTS",
"POLICY_AUDIT_LOG_ADMIN",
"POLICY_SERVER_ADMIN",
"POLICY_LOOKUP_NAMES",
"POLICY_NOTIFICATION",
"POLICY_ALL_ACCESS",
"POLICY_READ",
"POLICY_WRITE",
"POLICY_EXECUTE",
)
## EventAuditingOptions flags - not a real enum
POLICY_AUDIT_EVENT_OPTIONS_FLAGS = Enum(
"POLICY_AUDIT_EVENT_UNCHANGED",
"POLICY_AUDIT_EVENT_SUCCESS",
"POLICY_AUDIT_EVENT_FAILURE",
"POLICY_AUDIT_EVENT_NONE",
)
# AceType in ACE_HEADER - not a real enum
ACE_TYPE = Enum(
"ACCESS_MIN_MS_ACE_TYPE",
"ACCESS_ALLOWED_ACE_TYPE",
"ACCESS_DENIED_ACE_TYPE",
"SYSTEM_AUDIT_ACE_TYPE",
"SYSTEM_ALARM_ACE_TYPE",
"ACCESS_MAX_MS_V2_ACE_TYPE",
"ACCESS_ALLOWED_COMPOUND_ACE_TYPE",
"ACCESS_MAX_MS_V3_ACE_TYPE",
"ACCESS_MIN_MS_OBJECT_ACE_TYPE",
"ACCESS_ALLOWED_OBJECT_ACE_TYPE",
"ACCESS_DENIED_OBJECT_ACE_TYPE",
"SYSTEM_AUDIT_OBJECT_ACE_TYPE",
"SYSTEM_ALARM_OBJECT_ACE_TYPE",
"ACCESS_MAX_MS_OBJECT_ACE_TYPE",
"ACCESS_MAX_MS_V4_ACE_TYPE",
"ACCESS_MAX_MS_ACE_TYPE",
"ACCESS_ALLOWED_CALLBACK_ACE_TYPE",
"ACCESS_DENIED_CALLBACK_ACE_TYPE",
"ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE",
"ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE",
"SYSTEM_AUDIT_CALLBACK_ACE_TYPE",
"SYSTEM_ALARM_CALLBACK_ACE_TYPE",
"SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE",
"SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE",
"SYSTEM_MANDATORY_LABEL_ACE_TYPE",
"ACCESS_MAX_MS_V5_ACE_TYPE",
)
# bit flags for AceFlags - not a real enum
ACE_FLAGS = Enum(
"CONTAINER_INHERIT_ACE",
"FAILED_ACCESS_ACE_FLAG",
"INHERIT_ONLY_ACE",
"INHERITED_ACE",
"NO_PROPAGATE_INHERIT_ACE",
"OBJECT_INHERIT_ACE",
"SUCCESSFUL_ACCESS_ACE_FLAG",
"NO_INHERITANCE",
"SUB_CONTAINERS_AND_OBJECTS_INHERIT",
"SUB_CONTAINERS_ONLY_INHERIT",
"SUB_OBJECTS_ONLY_INHERIT",
)
# used in SetEntriesInAcl - very similar to ACE_TYPE
ACCESS_MODE = Enum(
"NOT_USED_ACCESS",
"GRANT_ACCESS",
"SET_ACCESS",
"DENY_ACCESS",
"REVOKE_ACCESS",
"SET_AUDIT_SUCCESS",
"SET_AUDIT_FAILURE",
)
# Bit flags in PSECURITY_DESCRIPTOR->Control - not a real enum
SECURITY_DESCRIPTOR_CONTROL_FLAGS = Enum(
"SE_DACL_AUTO_INHERITED", ## win2k and up
"SE_SACL_AUTO_INHERITED", ## win2k and up
"SE_DACL_PROTECTED", ## win2k and up
"SE_SACL_PROTECTED", ## win2k and up
"SE_DACL_DEFAULTED",
"SE_DACL_PRESENT",
"SE_GROUP_DEFAULTED",
"SE_OWNER_DEFAULTED",
"SE_SACL_PRESENT",
"SE_SELF_RELATIVE",
"SE_SACL_DEFAULTED",
)
# types of SID
SID_NAME_USE = Enum(
"SidTypeUser",
"SidTypeGroup",
"SidTypeDomain",
"SidTypeAlias",
"SidTypeWellKnownGroup",
"SidTypeDeletedAccount",
"SidTypeInvalid",
"SidTypeUnknown",
"SidTypeComputer",
"SidTypeLabel",
)
## bit flags, not a real enum
TOKEN_ACCESS_PRIVILEGES = Enum(
"TOKEN_ADJUST_DEFAULT",
"TOKEN_ADJUST_GROUPS",
"TOKEN_ADJUST_PRIVILEGES",
"TOKEN_ALL_ACCESS",
"TOKEN_ASSIGN_PRIMARY",
"TOKEN_DUPLICATE",
"TOKEN_EXECUTE",
"TOKEN_IMPERSONATE",
"TOKEN_QUERY",
"TOKEN_QUERY_SOURCE",
"TOKEN_READ",
"TOKEN_WRITE",
)
SECURITY_IMPERSONATION_LEVEL = Enum(
"SecurityAnonymous",
"SecurityIdentification",
"SecurityImpersonation",
"SecurityDelegation",
)
POLICY_SERVER_ENABLE_STATE = Enum("PolicyServerEnabled", "PolicyServerDisabled")
POLICY_NOTIFICATION_INFORMATION_CLASS = Enum(
"PolicyNotifyAuditEventsInformation",
"PolicyNotifyAccountDomainInformation",
"PolicyNotifyServerRoleInformation",
"PolicyNotifyDnsDomainInformation",
"PolicyNotifyDomainEfsInformation",
"PolicyNotifyDomainKerberosTicketInformation",
"PolicyNotifyMachineAccountPasswordInformation",
)
TRUSTED_INFORMATION_CLASS = Enum(
"TrustedDomainNameInformation",
"TrustedControllersInformation",
"TrustedPosixOffsetInformation",
"TrustedPasswordInformation",
"TrustedDomainInformationBasic",
"TrustedDomainInformationEx",
"TrustedDomainAuthInformation",
"TrustedDomainFullInformation",
"TrustedDomainAuthInformationInternal",
"TrustedDomainFullInformationInternal",
"TrustedDomainInformationEx2Internal",
"TrustedDomainFullInformation2Internal",
)
TRUSTEE_FORM = Enum(
"TRUSTEE_IS_SID",
"TRUSTEE_IS_NAME",
"TRUSTEE_BAD_FORM",
"TRUSTEE_IS_OBJECTS_AND_SID",
"TRUSTEE_IS_OBJECTS_AND_NAME",
)
TRUSTEE_TYPE = Enum(
"TRUSTEE_IS_UNKNOWN",
"TRUSTEE_IS_USER",
"TRUSTEE_IS_GROUP",
"TRUSTEE_IS_DOMAIN",
"TRUSTEE_IS_ALIAS",
"TRUSTEE_IS_WELL_KNOWN_GROUP",
"TRUSTEE_IS_DELETED",
"TRUSTEE_IS_INVALID",
"TRUSTEE_IS_COMPUTER",
)
## SE_OBJECT_TYPE - securable objects
SE_OBJECT_TYPE = Enum(
"SE_UNKNOWN_OBJECT_TYPE",
"SE_FILE_OBJECT",
"SE_SERVICE",
"SE_PRINTER",
"SE_REGISTRY_KEY",
"SE_LMSHARE",
"SE_KERNEL_OBJECT",
"SE_WINDOW_OBJECT",
"SE_DS_OBJECT",
"SE_DS_OBJECT_ALL",
"SE_PROVIDER_DEFINED_OBJECT",
"SE_WMIGUID_OBJECT",
"SE_REGISTRY_WOW64_32KEY",
)
PRIVILEGE_FLAGS = Enum(
"SE_PRIVILEGE_ENABLED_BY_DEFAULT",
"SE_PRIVILEGE_ENABLED",
"SE_PRIVILEGE_USED_FOR_ACCESS",
)
# Group flags used with TokenGroups
TOKEN_GROUP_ATTRIBUTES = Enum(
"SE_GROUP_MANDATORY",
"SE_GROUP_ENABLED_BY_DEFAULT",
"SE_GROUP_ENABLED",
"SE_GROUP_OWNER",
"SE_GROUP_USE_FOR_DENY_ONLY",
"SE_GROUP_INTEGRITY",
"SE_GROUP_INTEGRITY_ENABLED",
"SE_GROUP_LOGON_ID",
"SE_GROUP_RESOURCE",
)
# Privilege flags returned by TokenPrivileges
TOKEN_PRIVILEGE_ATTRIBUTES = Enum(
"SE_PRIVILEGE_ENABLED_BY_DEFAULT",
"SE_PRIVILEGE_ENABLED",
"SE_PRIVILEGE_REMOVED",
"SE_PRIVILEGE_USED_FOR_ACCESS",
)

View File

@@ -0,0 +1,106 @@
import os
import ntsecuritycon
import win32api
import win32con
import win32security
from win32security import (
ACL_REVISION_DS,
CONTAINER_INHERIT_ACE,
DACL_SECURITY_INFORMATION,
GROUP_SECURITY_INFORMATION,
OBJECT_INHERIT_ACE,
OWNER_SECURITY_INFORMATION,
PROTECTED_DACL_SECURITY_INFORMATION,
SACL_SECURITY_INFORMATION,
SE_FILE_OBJECT,
)
## SE_SECURITY_NAME needed to access SACL, SE_RESTORE_NAME needed to change owner to someone other than yourself
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS | win32con.TOKEN_ADJUST_PRIVILEGES
)
modified_privs = win32security.AdjustTokenPrivileges(th, 0, new_privs)
## look up a few sids that should be available on most systems
my_sid = win32security.GetTokenInformation(th, ntsecuritycon.TokenUser)[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
admin_sid = win32security.LookupAccountName("", "Administrators")[0]
everyone_sid = win32security.LookupAccountName("", "EveryOne")[0]
## create a dir and set security so Everyone has read permissions, and all files and subdirs inherit its ACLs
temp_dir = win32api.GetTempPath()
dir_name = win32api.GetTempFileName(temp_dir, "sfa")[0]
os.remove(dir_name)
os.mkdir(dir_name)
dir_dacl = win32security.ACL()
dir_dacl.AddAccessAllowedAceEx(
ACL_REVISION_DS,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
win32con.GENERIC_READ,
everyone_sid,
)
## make sure current user has permissions on dir
dir_dacl.AddAccessAllowedAceEx(
ACL_REVISION_DS,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
win32con.GENERIC_ALL,
my_sid,
)
## keep dir from inheriting any permissions so it only has ACEs explicitly set here
win32security.SetNamedSecurityInfo(
dir_name,
SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
| PROTECTED_DACL_SECURITY_INFORMATION,
pwr_sid,
pwr_sid,
dir_dacl,
None,
)
## Create a file in the dir and add some specific permissions to it
fname = win32api.GetTempFileName(dir_name, "sfa")[0]
print(fname)
file_sd = win32security.GetNamedSecurityInfo(
fname, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION
)
file_dacl = file_sd.GetSecurityDescriptorDacl()
file_sacl = file_sd.GetSecurityDescriptorSacl()
if file_dacl is None:
file_dacl = win32security.ACL()
if file_sacl is None:
file_sacl = win32security.ACL()
file_dacl.AddAccessDeniedAce(file_dacl.GetAclRevision(), win32con.DELETE, admin_sid)
file_dacl.AddAccessDeniedAce(file_dacl.GetAclRevision(), win32con.DELETE, my_sid)
file_dacl.AddAccessAllowedAce(file_dacl.GetAclRevision(), win32con.GENERIC_ALL, pwr_sid)
file_sacl.AddAuditAccessAce(
file_dacl.GetAclRevision(), win32con.GENERIC_ALL, my_sid, True, True
)
win32security.SetNamedSecurityInfo(
fname,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
None,
None,
file_dacl,
file_sacl,
)
win32security.AdjustTokenPrivileges(th, 0, modified_privs)

View File

@@ -0,0 +1,73 @@
fname = r"h:\tmp.txt"
import ntsecuritycon
import win32api
import win32con
import win32security
new_privs = (
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", ntsecuritycon.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", "SeEnableDelegationPrivilege"),
win32con.SE_PRIVILEGE_ENABLED,
), ##doesn't seem to be in ntsecuritycon.py ?
)
ph = win32api.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS | win32con.TOKEN_ADJUST_PRIVILEGES
)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
all_security_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
sd = win32security.GetFileSecurity(fname, all_security_info)
old_dacl = sd.GetSecurityDescriptorDacl()
old_sacl = sd.GetSecurityDescriptorSacl()
old_group = sd.GetSecurityDescriptorGroup()
new_sd = win32security.SECURITY_DESCRIPTOR()
print(
"relative, valid, size: ",
new_sd.IsSelfRelative(),
new_sd.IsValid(),
new_sd.GetLength(),
)
my_sid = win32security.GetTokenInformation(th, ntsecuritycon.TokenUser)[0]
tmp_sid = win32security.LookupAccountName("", "tmp")[0]
new_sd.SetSecurityDescriptorSacl(1, old_sacl, 1)
new_sd.SetSecurityDescriptorDacl(1, old_dacl, 1)
new_sd.SetSecurityDescriptorOwner(tmp_sid, 0)
new_sd.SetSecurityDescriptorGroup(old_group, 0)
win32security.SetFileSecurity(fname, all_security_info, new_sd)

View File

@@ -0,0 +1,25 @@
import win32security
policy_handle = win32security.GetPolicyHandle("rupole", win32security.POLICY_ALL_ACCESS)
event_audit_info = win32security.LsaQueryInformationPolicy(
policy_handle, win32security.PolicyAuditEventsInformation
)
print(event_audit_info)
new_audit_info = list(event_audit_info[1])
new_audit_info[win32security.AuditCategoryPolicyChange] = (
win32security.POLICY_AUDIT_EVENT_SUCCESS | win32security.POLICY_AUDIT_EVENT_FAILURE
)
new_audit_info[win32security.AuditCategoryAccountLogon] = (
win32security.POLICY_AUDIT_EVENT_SUCCESS | win32security.POLICY_AUDIT_EVENT_FAILURE
)
new_audit_info[win32security.AuditCategoryLogon] = (
win32security.POLICY_AUDIT_EVENT_SUCCESS | win32security.POLICY_AUDIT_EVENT_FAILURE
)
win32security.LsaSetInformationPolicy(
policy_handle, win32security.PolicyAuditEventsInformation, (1, new_audit_info)
)
win32security.LsaClose(policy_handle)

View File

@@ -0,0 +1,134 @@
import win32api
import win32con
import win32security
## You need SE_RESTORE_NAME to be able to set the owner of a security descriptor to anybody
## other than yourself or your primary group. Most admin logins don't have it by default, so
## enabling it may fail
new_privs = (
(
win32security.LookupPrivilegeValue("", win32security.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_ENABLE_DELEGATION_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CHANGE_NOTIFY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_DEBUG_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue(
"", win32security.SE_PROF_SINGLE_PROCESS_NAME
),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SYSTEM_PROFILE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_LOCK_MEMORY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
all_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
pid = win32api.GetCurrentProcessId()
ph = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, pid)
## PROCESS_ALL_ACCESS does not contain ACCESS_SYSTEM_SECURITY (neccessy to do SACLs)
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
old_privs = win32security.GetTokenInformation(th, win32security.TokenPrivileges)
desired_privs = tuple((e[0], win32con.SE_PRIVILEGE_ENABLED) for e in old_privs)
modified_privs = win32security.AdjustTokenPrivileges(
th, 0, desired_privs
) # Will (partially) fail for new_privs (unless they are a subset of current ones)
gle = win32api.GetLastError()
if gle != 0:
print("AdjustTokenPrivileges error:", gle)
# print(modified_privs)
my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
## reopen process with ACCESS_SYSTEM_SECURITY now that sufficent privs are enabled
ph = win32api.OpenProcess(
win32con.PROCESS_ALL_ACCESS | win32con.ACCESS_SYSTEM_SECURITY, 0, pid
)
sd = win32security.GetKernelObjectSecurity(ph, all_info)
dacl = sd.GetSecurityDescriptorDacl()
if dacl is None:
dacl = win32security.ACL()
sacl = sd.GetSecurityDescriptorSacl()
if sacl is None:
sacl = win32security.ACL()
dacl_ace_cnt = dacl.GetAceCount()
sacl_ace_cnt = sacl.GetAceCount()
dacl.AddAccessAllowedAce(
dacl.GetAclRevision(), win32con.ACCESS_SYSTEM_SECURITY | win32con.WRITE_DAC, my_sid
)
sacl.AddAuditAccessAce(sacl.GetAclRevision(), win32con.GENERIC_ALL, my_sid, 1, 1)
sd.SetSecurityDescriptorDacl(1, dacl, 0)
sd.SetSecurityDescriptorSacl(1, sacl, 0)
sd.SetSecurityDescriptorGroup(pwr_sid, 0)
sd.SetSecurityDescriptorOwner(pwr_sid, 0)
win32security.SetKernelObjectSecurity(ph, all_info, sd)
new_sd = win32security.GetKernelObjectSecurity(ph, all_info)
if new_sd.GetSecurityDescriptorDacl().GetAceCount() != dacl_ace_cnt + 1:
print("New dacl doesn't contain extra ace ????")
if new_sd.GetSecurityDescriptorSacl().GetAceCount() != sacl_ace_cnt + 1:
print("New Sacl doesn't contain extra ace ????")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorOwner())[0]
!= "Power Users"
):
print("Owner not successfully set to Power Users !!!!!")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorGroup())[0]
!= "Power Users"
):
print("Group not successfully set to Power Users !!!!!")
sd.SetSecurityDescriptorSacl(0, None, 0)
win32security.SetKernelObjectSecurity(ph, win32security.SACL_SECURITY_INFORMATION, sd)
new_sd_1 = win32security.GetKernelObjectSecurity(
ph, win32security.SACL_SECURITY_INFORMATION
)
if new_sd_1.GetSecurityDescriptorSacl() is not None:
print("Unable to set Sacl to NULL !!!!!!!!")

View File

@@ -0,0 +1,131 @@
import win32api
import win32con
import win32process
import win32security
fname, tmp = win32api.GetTempFileName(win32api.GetTempPath(), "tmp")
print(fname)
## You need SE_RESTORE_NAME to be able to set the owner of a security descriptor to anybody
## other than yourself or your primary group. Most admin logins don't have it by default, so
## enabling it may fail
new_privs = (
(
win32security.LookupPrivilegeValue("", win32security.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_ENABLE_DELEGATION_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CHANGE_NOTIFY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_DEBUG_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue(
"", win32security.SE_PROF_SINGLE_PROCESS_NAME
),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SYSTEM_PROFILE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_LOCK_MEMORY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
all_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
ph = win32process.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
sd = win32security.GetNamedSecurityInfo(fname, win32security.SE_FILE_OBJECT, all_info)
dacl = sd.GetSecurityDescriptorDacl()
if dacl is None:
dacl = win32security.ACL()
sacl = sd.GetSecurityDescriptorSacl()
if sacl is None:
sacl = win32security.ACL()
dacl_ace_cnt = dacl.GetAceCount()
sacl_ace_cnt = sacl.GetAceCount()
dacl.AddAccessAllowedAce(
dacl.GetAclRevision(), win32con.ACCESS_SYSTEM_SECURITY | win32con.WRITE_DAC, my_sid
)
sacl.AddAuditAccessAce(sacl.GetAclRevision(), win32con.GENERIC_ALL, my_sid, 1, 1)
win32security.SetNamedSecurityInfo(
fname, win32security.SE_FILE_OBJECT, all_info, pwr_sid, pwr_sid, dacl, sacl
)
new_sd = win32security.GetNamedSecurityInfo(
fname, win32security.SE_FILE_OBJECT, all_info
)
## could do additional checking to make sure added ACE contains expected info
if new_sd.GetSecurityDescriptorDacl().GetAceCount() != dacl_ace_cnt + 1:
print("New dacl doesn't contain extra ace ????")
if new_sd.GetSecurityDescriptorSacl().GetAceCount() != sacl_ace_cnt + 1:
print("New Sacl doesn't contain extra ace ????")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorOwner())[0]
!= "Power Users"
):
print("Owner not successfully set to Power Users !!!!!")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorGroup())[0]
!= "Power Users"
):
print("Group not successfully set to Power Users !!!!!")
win32security.SetNamedSecurityInfo(
fname,
win32security.SE_FILE_OBJECT,
win32security.SACL_SECURITY_INFORMATION,
None,
None,
None,
None,
)
new_sd_1 = win32security.GetNamedSecurityInfo(
fname, win32security.SE_FILE_OBJECT, win32security.SACL_SECURITY_INFORMATION
)
if new_sd_1.GetSecurityDescriptorSacl() is not None:
print("Unable to set Sacl to NULL !!!!!!!!")

View File

@@ -0,0 +1,131 @@
import win32api
import win32con
import win32security
## You need SE_RESTORE_NAME to be able to set the owner of a security descriptor to anybody
## other than yourself or your primary group. Most admin logins don't have it by default, so
## enabling it may fail
new_privs = (
(
win32security.LookupPrivilegeValue("", win32security.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_ENABLE_DELEGATION_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CHANGE_NOTIFY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_DEBUG_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue(
"", win32security.SE_PROF_SINGLE_PROCESS_NAME
),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SYSTEM_PROFILE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_LOCK_MEMORY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
all_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
pid = win32api.GetCurrentProcessId()
ph = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, pid)
## PROCESS_ALL_ACCESS does not contain ACCESS_SYSTEM_SECURITY (neccessy to do SACLs)
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
old_privs = win32security.AdjustTokenPrivileges(th, 0, new_privs)
my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
## reopen process with ACCESS_SYSTEM_SECURITY now that sufficent privs are enabled
ph = win32api.OpenProcess(
win32con.PROCESS_ALL_ACCESS | win32con.ACCESS_SYSTEM_SECURITY, 0, pid
)
sd = win32security.GetSecurityInfo(ph, win32security.SE_KERNEL_OBJECT, all_info)
dacl = sd.GetSecurityDescriptorDacl()
if dacl is None:
dacl = win32security.ACL()
sacl = sd.GetSecurityDescriptorSacl()
if sacl is None:
sacl = win32security.ACL()
dacl_ace_cnt = dacl.GetAceCount()
sacl_ace_cnt = sacl.GetAceCount()
dacl.AddAccessAllowedAce(
dacl.GetAclRevision(), win32con.ACCESS_SYSTEM_SECURITY | win32con.WRITE_DAC, my_sid
)
sacl.AddAuditAccessAce(sacl.GetAclRevision(), win32con.GENERIC_ALL, my_sid, 1, 1)
win32security.SetSecurityInfo(
ph, win32security.SE_KERNEL_OBJECT, all_info, pwr_sid, pwr_sid, dacl, sacl
)
new_sd = win32security.GetSecurityInfo(ph, win32security.SE_KERNEL_OBJECT, all_info)
if new_sd.GetSecurityDescriptorDacl().GetAceCount() != dacl_ace_cnt + 1:
print("New dacl doesn't contain extra ace ????")
if new_sd.GetSecurityDescriptorSacl().GetAceCount() != sacl_ace_cnt + 1:
print("New Sacl doesn't contain extra ace ????")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorOwner())[0]
!= "Power Users"
):
print("Owner not successfully set to Power Users !!!!!")
if (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorGroup())[0]
!= "Power Users"
):
print("Group not successfully set to Power Users !!!!!")
win32security.SetSecurityInfo(
ph,
win32security.SE_KERNEL_OBJECT,
win32security.SACL_SECURITY_INFORMATION,
None,
None,
None,
None,
)
new_sd_1 = win32security.GetSecurityInfo(
ph, win32security.SE_KERNEL_OBJECT, win32security.SACL_SECURITY_INFORMATION
)
if new_sd_1.GetSecurityDescriptorSacl() is not None:
print("Unable to set Sacl to NULL !!!!!!!!")

View File

@@ -0,0 +1,102 @@
import win32con
import win32process
import win32security
new_privs = (
(
win32security.LookupPrivilegeValue("", win32security.SE_SECURITY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TCB_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SHUTDOWN_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_RESTORE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_TAKE_OWNERSHIP_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CREATE_PERMANENT_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_ENABLE_DELEGATION_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_CHANGE_NOTIFY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_DEBUG_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue(
"", win32security.SE_PROF_SINGLE_PROCESS_NAME
),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_SYSTEM_PROFILE_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
(
win32security.LookupPrivilegeValue("", win32security.SE_LOCK_MEMORY_NAME),
win32con.SE_PRIVILEGE_ENABLED,
),
)
all_info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
| win32security.SACL_SECURITY_INFORMATION
)
info = (
win32security.OWNER_SECURITY_INFORMATION
| win32security.GROUP_SECURITY_INFORMATION
| win32security.DACL_SECURITY_INFORMATION
)
ph = win32process.GetCurrentProcess()
th = win32security.OpenProcessToken(
ph, win32security.TOKEN_ALL_ACCESS
) ##win32con.TOKEN_ADJUST_PRIVILEGES)
win32security.AdjustTokenPrivileges(th, 0, new_privs)
my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0]
pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
h = win32process.GetProcessWindowStation()
sd = win32security.GetUserObjectSecurity(h, info)
dacl = sd.GetSecurityDescriptorDacl()
ace_cnt = dacl.GetAceCount()
dacl.AddAccessAllowedAce(
dacl.GetAclRevision(), win32con.ACCESS_SYSTEM_SECURITY | win32con.WRITE_DAC, my_sid
)
sd.SetSecurityDescriptorDacl(1, dacl, 0)
sd.SetSecurityDescriptorGroup(pwr_sid, 0)
sd.SetSecurityDescriptorOwner(pwr_sid, 0)
win32security.SetUserObjectSecurity(h, info, sd)
new_sd = win32security.GetUserObjectSecurity(h, info)
assert (
new_sd.GetSecurityDescriptorDacl().GetAceCount() == ace_cnt + 1
), "Did not add an ace to the Dacl !!!!!!"
assert (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorOwner())[0]
== "Power Users"
), "Owner not successfully set to Power Users !!!!!"
assert (
win32security.LookupAccountSid("", new_sd.GetSecurityDescriptorGroup())[0]
== "Power Users"
), "Group not successfully set to Power Users !!!!!"

View File

@@ -0,0 +1,158 @@
"""
Fetches a URL from a web-server supporting NTLM authentication
eg, IIS.
If no arguments are specified, a default of http://localhost/localstart.asp
is used. This script does follow simple 302 redirections, so pointing at the
root of an IIS server is should work.
"""
import http.client # sorry, this demo needs 2.3+
import optparse
import urllib.error
import urllib.parse
import urllib.request
from base64 import decodestring, encodestring
from sspi import ClientAuth
options = None # set to optparse options object
def open_url(host, url):
h = http.client.HTTPConnection(host)
# h.set_debuglevel(9)
h.putrequest("GET", url)
h.endheaders()
resp = h.getresponse()
print("Initial response is", resp.status, resp.reason)
body = resp.read()
if resp.status == 302: # object moved
url = "/" + resp.msg["location"]
resp.close()
h.putrequest("GET", url)
h.endheaders()
resp = h.getresponse()
print("After redirect response is", resp.status, resp.reason)
if options.show_headers:
print("Initial response headers:")
for name, val in resp.msg.items():
print(f" {name}: {val}")
if options.show_body:
print(body)
if resp.status == 401:
# 401: Unauthorized - here is where the real work starts
auth_info = None
if options.user or options.domain or options.password:
auth_info = options.user, options.domain, options.password
ca = ClientAuth("NTLM", auth_info=auth_info)
auth_scheme = ca.pkg_info["Name"]
data = None
while 1:
err, out_buf = ca.authorize(data)
data = out_buf[0].Buffer
# Encode it as base64 as required by HTTP
auth = encodestring(data).replace("\012", "")
h.putrequest("GET", url)
h.putheader("Authorization", auth_scheme + " " + auth)
h.putheader("Content-Length", "0")
h.endheaders()
resp = h.getresponse()
if options.show_headers:
print("Token dance headers:")
for name, val in resp.msg.items():
print(f" {name}: {val}")
if err == 0:
break
else:
if resp.status != 401:
print("Eeek - got response", resp.status)
cl = resp.msg.get("content-length")
if cl:
print(repr(resp.read(int(cl))))
else:
print("no content!")
assert resp.status == 401, resp.status
assert not resp.will_close, "NTLM is per-connection - must not close"
schemes = [
s.strip() for s in resp.msg.get("WWW-Authenticate", "").split(",")
]
for scheme in schemes:
if scheme.startswith(auth_scheme):
data = decodestring(scheme[len(auth_scheme) + 1 :])
break
else:
print(f"Could not find scheme '{auth_scheme}' in schemes {schemes!r}")
break
resp.read()
print("Final response status is", resp.status, resp.reason)
if resp.status == 200:
# Worked!
# Check we can read it again without re-authenticating.
if resp.will_close:
print(
"EEEK - response will close, but NTLM is per connection - it must stay open"
)
body = resp.read()
if options.show_body:
print("Final response body:")
print(body)
h.putrequest("GET", url)
h.endheaders()
resp = h.getresponse()
print("Second fetch response is", resp.status, resp.reason)
if options.show_headers:
print("Second response headers:")
for name, val in resp.msg.items():
print(f" {name}: {val}")
resp.read(int(resp.msg.get("content-length", 0)))
elif resp.status == 500:
print("Error text")
print(resp.read())
else:
if options.show_body:
cl = resp.msg.get("content-length")
print(resp.read(int(cl)))
if __name__ == "__main__":
parser = optparse.OptionParser(description=__doc__)
parser.add_option(
"",
"--show-body",
action="store_true",
help="print the body of each response as it is received",
)
parser.add_option(
"",
"--show-headers",
action="store_true",
help="print the headers of each response as it is received",
)
parser.add_option("", "--user", action="store", help="The username to login with")
parser.add_option(
"", "--password", action="store", help="The password to login with"
)
parser.add_option("", "--domain", action="store", help="The domain to login to")
options, args = parser.parse_args()
if not args:
print("Run with --help for usage details")
args = ["http://localhost/localstart.asp"]
for url in args:
scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(url)
if (scheme != "http") or params or query or fragment:
parser.error("Scheme must be http, URL must be simple")
print(f"Opening '{path}' from '{netloc}'")
r = open_url(netloc, path)

View File

@@ -0,0 +1,72 @@
# A demo of basic SSPI authentication.
# There is a 'client' context and a 'server' context - typically these will
# be on different machines (here they are in the same process, but the same
# concepts apply)
import sspi
import sspicon
import win32api
import win32security
def lookup_ret_code(err):
for k, v in sspicon.__dict__.items():
if k[0:6] in ("SEC_I_", "SEC_E_") and v == err:
return k
"""
pkg_name='Kerberos'
sspiclient=SSPIClient(pkg_name, win32api.GetUserName(), ## target spn is ourself
None, None, ## use none for client name and authentication information for current context
## 'username', ('username','domain.com','passwd'),
sspicon.ISC_REQ_INTEGRITY|sspicon.ISC_REQ_SEQUENCE_DETECT|sspicon.ISC_REQ_REPLAY_DETECT| \
sspicon.ISC_REQ_DELEGATE|sspicon.ISC_REQ_CONFIDENTIALITY|sspicon.ISC_REQ_USE_SESSION_KEY)
sspiserver=SSPIServer(pkg_name, None,
sspicon.ASC_REQ_INTEGRITY|sspicon.ASC_REQ_SEQUENCE_DETECT|sspicon.ASC_REQ_REPLAY_DETECT| \
sspicon.ASC_REQ_DELEGATE|sspicon.ASC_REQ_CONFIDENTIALITY|sspicon.ASC_REQ_STREAM|sspicon.ASC_REQ_USE_SESSION_KEY)
"""
pkg_name = "NTLM"
# Setup the 2 contexts.
sspiclient = sspi.ClientAuth(pkg_name)
sspiserver = sspi.ServerAuth(pkg_name)
# Perform the authentication dance, each loop exchanging more information
# on the way to completing authentication.
sec_buffer = None
while 1:
err, sec_buffer = sspiclient.authorize(sec_buffer)
err, sec_buffer = sspiserver.authorize(sec_buffer)
if err == 0:
break
# The server can now impersonate the client. In this demo the 2 users will
# always be the same.
sspiserver.ctxt.ImpersonateSecurityContext()
print("Impersonated user: ", win32api.GetUserNameEx(win32api.NameSamCompatible))
sspiserver.ctxt.RevertSecurityContext()
print("Reverted to self: ", win32api.GetUserName())
pkg_size_info = sspiclient.ctxt.QueryContextAttributes(sspicon.SECPKG_ATTR_SIZES)
# Now sign some data
msg = "some data to be encrypted ......"
sigsize = pkg_size_info["MaxSignature"]
sigbuf = win32security.PySecBufferDescType()
sigbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
sigbuf.append(win32security.PySecBufferType(sigsize, sspicon.SECBUFFER_TOKEN))
sigbuf[0].Buffer = msg
sspiclient.ctxt.MakeSignature(0, sigbuf, 1)
sspiserver.ctxt.VerifySignature(sigbuf, 1)
# And finally encrypt some.
trailersize = pkg_size_info["SecurityTrailer"]
encbuf = win32security.PySecBufferDescType()
encbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
encbuf.append(win32security.PySecBufferType(trailersize, sspicon.SECBUFFER_TOKEN))
encbuf[0].Buffer = msg
sspiclient.ctxt.EncryptMessage(0, encbuf, 1)
print(f"Encrypted data: {encbuf[0].Buffer!r}")
sspiserver.ctxt.DecryptMessage(encbuf, 1)
print(f"Encrypted data: {encbuf[0].Buffer}")

View File

@@ -0,0 +1,199 @@
"""A sample socket server and client using SSPI authentication and encryption.
You must run with either 'client' or 'server' as arguments. A server must be
running before a client can connect.
To use with Kerberos you should include in the client options
--target-spn=username, where 'username' is the user under which the server is
being run.
Running either the client or server as a different user can be informative.
A command-line such as the following may be useful:
`runas /user:{user} {fqp}\\python.exe {fqp}\\socket_server.py --wait client|server`
{fqp} should specify the relevant fully-qualified path names.
To use 'runas' with Kerberos, the client program will need to
specify --target-spn with the username under which the *server* is running.
See the SSPI documentation for more details.
"""
import http.client # sorry, this demo needs 2.3+
import optparse
import socketserver
import struct
import traceback
import sspi
import win32api
options = None # set to optparse object.
def GetUserName():
try:
return win32api.GetUserName()
except win32api.error as details:
# Seeing 'access denied' errors here for non-local users (presumably
# without permission to login locally). Get the fully-qualified
# username, although a side-effect of these permission-denied errors
# is a lack of Python codecs - so printing the Unicode value fails.
# So just return the repr(), and avoid codecs completely.
return repr(win32api.GetUserNameEx(win32api.NameSamCompatible))
# Send a simple "message" over a socket - send the number of bytes first,
# then the string. Ditto for receive.
def _send_msg(s, m):
s.send(struct.pack("i", len(m)))
s.send(m)
def _get_msg(s):
size_data = s.recv(struct.calcsize("i"))
if not size_data:
return None
cb = struct.unpack("i", size_data)[0]
return s.recv(cb)
class SSPISocketServer(socketserver.TCPServer):
def __init__(self, *args, **kw):
socketserver.TCPServer.__init__(self, *args, **kw)
self.sa = sspi.ServerAuth(options.package)
def verify_request(self, sock, ca):
# Do the sspi auth dance
self.sa.reset()
while 1:
data = _get_msg(sock)
if data is None:
return False
try:
err, sec_buffer = self.sa.authorize(data)
except sspi.error as details:
print("FAILED to authorize client:", details)
return False
if err == 0:
break
_send_msg(sock, sec_buffer[0].Buffer)
return True
def process_request(self, request, client_address):
# An example using the connection once it is established.
print("The server is running as user", GetUserName())
self.sa.ctxt.ImpersonateSecurityContext()
try:
print("Having conversation with client as user", GetUserName())
while 1:
# we need to grab 2 bits of data - the encrypted data, and the
# 'key'
data = _get_msg(request)
key = _get_msg(request)
if data is None or key is None:
break
data = self.sa.decrypt(data, key)
print(f"Client sent: {data!r}")
finally:
self.sa.ctxt.RevertSecurityContext()
self.close_request(request)
print("The server is back to user", GetUserName())
def serve():
s = SSPISocketServer(("localhost", options.port), None)
print("Running test server...")
s.serve_forever()
def sspi_client():
c = http.client.HTTPConnection("localhost", options.port)
c.connect()
# Do the auth dance.
ca = sspi.ClientAuth(options.package, targetspn=options.target_spn)
data = None
while 1:
err, out_buf = ca.authorize(data)
_send_msg(c.sock, out_buf[0].Buffer)
if err == 0:
break
data = _get_msg(c.sock)
print("Auth dance complete - sending a few encryted messages")
# Assume out data is sensitive - encrypt the message.
for data in "Hello from the client".split():
blob, key = ca.encrypt(data)
_send_msg(c.sock, blob)
_send_msg(c.sock, key)
c.sock.close()
print("Client completed.")
if __name__ == "__main__":
parser = optparse.OptionParser("%prog [options] client|server", description=__doc__)
parser.add_option(
"",
"--package",
action="store",
default="NTLM",
help="The SSPI package to use (eg, Kerberos) - default is NTLM",
)
parser.add_option(
"",
"--target-spn",
action="store",
help="""The target security provider name to use. The
string contents are security-package specific. For
example, 'Kerberos' or 'Negotiate' require the server
principal name (SPN) (ie, the username) of the remote
process. For NTLM this must be blank.""",
)
parser.add_option(
"",
"--port",
action="store",
default="8181",
help="The port number to use (default=8181)",
)
parser.add_option(
"",
"--wait",
action="store_true",
help="""Cause the program to wait for input just before
terminating. Useful when using via runas to see
any error messages before termination.
""",
)
options, args = parser.parse_args()
try:
options.port = int(options.port)
except (ValueError, TypeError):
parser.error("--port must be an integer")
try:
try:
if not args:
args = [""]
if args[0] == "client":
sspi_client()
elif args[0] == "server":
serve()
else:
parser.error(
"You must supply 'client' or 'server' - use --help for details"
)
except KeyboardInterrupt:
pass
except SystemExit:
pass
except:
traceback.print_exc()
finally:
if options.wait:
input("Press enter to continue")

View File

@@ -0,0 +1,41 @@
# Demonstrates how to validate a password.
# See also MSKB article Q180548
#
# To use with Kerberos you need to jump through the 'targetspn' hoops.
import sys
import win32security
from sspi import ClientAuth, ServerAuth
def validate(username, password, domain=""):
auth_info = username, domain, password
ca = ClientAuth("NTLM", auth_info=auth_info)
sa = ServerAuth("NTLM")
data = err = None
while err != 0:
err, data = ca.authorize(data)
err, data = sa.authorize(data)
# If we get here without exception, we worked!
if __name__ == "__main__":
if len(sys.argv) not in [2, 3, 4]:
print(f"Usage: {__file__} username [password [domain]]")
sys.exit(1)
# password and domain are optional!
password = None
if len(sys.argv) >= 3:
password = sys.argv[2]
domain = ""
if len(sys.argv) >= 4:
domain = sys.argv[3]
try:
validate(sys.argv[1], password, domain)
print("Validated OK")
except win32security.error as details:
hr, func, msg = details
print("Validation failed: %s (%d)" % (msg, hr))