mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
update Doc + test + sample for token.py
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
(cmd) python debug\debugger_on_setup.py
|
||||
== With on_setup ==
|
||||
Setup called: <WinProcess "whoami.exe" pid 29796 at 0x4ccb790>
|
||||
<whoami output>
|
||||
Process exit: <WinProcess "whoami.exe" pid 29796 (DEAD) at 0x4ccb790>
|
||||
|
||||
== Without on_setup ==
|
||||
Exception: EXCEPTION_BREAKPOINT(0x80000003L)
|
||||
<whoami output>
|
||||
Process exit: <WinProcess "whoami.exe" pid 33328 (DEAD) at 0x4ccbdb0>
|
||||
@@ -0,0 +1,21 @@
|
||||
(cmd) python token\token_demo.py
|
||||
Our process token is <Token TokenId=0x3f1f98fd Type=TokenPrimary(0x1L)>
|
||||
Retrieving some infos
|
||||
Username: <hakril>
|
||||
User: <PSID "S-1-5-21-184905214-2723199098-2761450773-1001">
|
||||
- lookup : ('WILLIE', 'hakril')
|
||||
Primary group: <PSID "S-1-5-21-184905214-2723199098-2761450773-513">
|
||||
- lookup : ('WILLIE', 'Aucun')
|
||||
|
||||
Token Groups is <TokenGroups count=15>
|
||||
First group SID is <PSID "S-1-5-21-184905214-2723199098-2761450773-513">
|
||||
Some sid and attributes:
|
||||
- S-1-5-21-184905214-2723199098-2761450773-513: 7
|
||||
- S-1-1-0: 7
|
||||
- S-1-5-114: 16
|
||||
|
||||
Duplicate token is <Token TokenId=0x3f1fac85 Type=TokenImpersonation(0x2L) ImpersonationLevel=SecurityImpersonation(0x2L)>
|
||||
Enabling <SeShutDownPrivilege>
|
||||
Current thread token is <None>
|
||||
Setting impersonation token !
|
||||
Current thread token is <Token TokenId=0x3f1fac85 Type=TokenImpersonation(0x2L) ImpersonationLevel=SecurityImpersonation(0x2L)>
|
||||
@@ -0,0 +1,61 @@
|
||||
Token
|
||||
"""""
|
||||
|
||||
.. module:: windows.winobject.token
|
||||
|
||||
This module expose the :class:`Token` object that can be primarily retrieved through:
|
||||
|
||||
* :data:`windows.winobject.process.WinProcess.token`
|
||||
* :data:`windows.winobject.process.WinThread.token`
|
||||
* :data:`windows.current_process.token <windows.winobject.process.CurrentProcess.token>`
|
||||
* :data:`windows.current_thread.token <windows.winobject.process.CurrentThread.token>`
|
||||
|
||||
.. note::
|
||||
|
||||
See sample :ref:`token_sample`
|
||||
|
||||
|
||||
Token
|
||||
'''''
|
||||
|
||||
.. autoclass:: Token
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
TokenGroups
|
||||
'''''''''''
|
||||
|
||||
.. autoclass:: TokenGroups
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
|
||||
TokenPrivileges
|
||||
'''''''''''''''
|
||||
|
||||
.. autoclass:: TokenPrivileges
|
||||
:show-inheritance:
|
||||
:special-members: __getitem__, __setitem__
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
TokenSecurityAttributesInformation
|
||||
''''''''''''''''''''''''''''''''''
|
||||
|
||||
.. autoclass:: TokenSecurityAttributesInformation
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
TokenSecurityAttributeV1
|
||||
''''''''''''''''''''''''
|
||||
|
||||
.. autoclass:: TokenSecurityAttributeV1
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:inherited-members:
|
||||
+101
-21
@@ -1,28 +1,108 @@
|
||||
import pytest
|
||||
import os
|
||||
|
||||
import windows
|
||||
import windows.security
|
||||
import windows.generated_def as gdef
|
||||
|
||||
@pytest.fixture
|
||||
def curtok():
|
||||
return windows.current_process.token
|
||||
|
||||
@pytest.fixture
|
||||
def newtok():
|
||||
return windows.current_process.token.duplicate()
|
||||
|
||||
def test_token_info(curtok):
|
||||
assert isinstance(curtok.computername, basestring)
|
||||
assert isinstance(curtok.username, basestring)
|
||||
assert isinstance(curtok.integrity, (int, long))
|
||||
assert isinstance(curtok.is_elevated, (bool))
|
||||
|
||||
def test_lower_integrity(newtok):
|
||||
assert newtok.integrity != 123
|
||||
# Change token integrity
|
||||
newtok.integrity = 123
|
||||
# newtok.integrity retrieve the integrity at each call so this in enough
|
||||
assert newtok.integrity == 123
|
||||
|
||||
def test_token_user(curtok):
|
||||
user_sid = curtok.user
|
||||
assert user_sid
|
||||
computername, username = windows.security.lookup_sid(user_sid)
|
||||
assert computername == windows.system.computer_name
|
||||
assert username == os.environ["USERNAME"]
|
||||
|
||||
def test_token_id(curtok):
|
||||
ntok = curtok.duplicate()
|
||||
assert ntok.id != curtok.id
|
||||
mid = ntok.modified_id
|
||||
aid = ntok.authentication_id
|
||||
ntok.enable_privilege("SeShutDownPrivilege")
|
||||
mid2 = ntok.modified_id
|
||||
aid2 = ntok.authentication_id
|
||||
ntok.integrity -= 1
|
||||
assert ntok.modified_id != mid2 != mid
|
||||
assert ntok.authentication_id == aid2 == aid
|
||||
|
||||
|
||||
def test_token_info():
|
||||
token = windows.current_process.token
|
||||
assert isinstance(token.computername, basestring)
|
||||
assert isinstance(token.username, basestring)
|
||||
assert isinstance(token.integrity, (int, long))
|
||||
assert isinstance(token.is_elevated, (bool))
|
||||
|
||||
def test_lower_integrity(proc32):
|
||||
# Lowering the integrity in remote process
|
||||
# Because we don't want to mess with the token of our testing process
|
||||
|
||||
proc32.execute_python("import windows")
|
||||
# We stock the handle becase lowering the integrity
|
||||
# will mess with token retrieval
|
||||
proc32.execute_python("token = windows.current_process.token")
|
||||
proc32.execute_python("token.integrity = 123")
|
||||
# execute_python will raise this in our own process :)
|
||||
proc32.execute_python("assert token.integrity == 123")
|
||||
def test_enable_privilege(newtok):
|
||||
PRIVILEGE_NAME = "SeShutdownPrivilege"
|
||||
assert not newtok.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
|
||||
newtok.enable_privilege(PRIVILEGE_NAME)
|
||||
assert newtok.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
|
||||
|
||||
|
||||
def test_token_elevation():
|
||||
tok = windows.current_process.token
|
||||
assert tok.TokenElevation
|
||||
def test_adjust_privilege(newtok):
|
||||
PRIVILEGE_NAME = "SeShutdownPrivilege"
|
||||
PRIVILEGE2_NAME = "SeTimeZonePrivilege"
|
||||
tok_dup = newtok.duplicate()
|
||||
assert not tok_dup.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
|
||||
assert not tok_dup.privileges[PRIVILEGE2_NAME] & gdef.SE_PRIVILEGE_ENABLED
|
||||
# Enable privilege in another token.
|
||||
privs = newtok.privileges
|
||||
assert not privs[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
|
||||
assert not privs[PRIVILEGE2_NAME] & gdef.SE_PRIVILEGE_ENABLED
|
||||
|
||||
privs[PRIVILEGE_NAME] = gdef.SE_PRIVILEGE_ENABLED
|
||||
privs[PRIVILEGE2_NAME] = gdef.SE_PRIVILEGE_ENABLED
|
||||
tok_dup.adjust_privileges(privs)
|
||||
|
||||
assert tok_dup.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
|
||||
assert tok_dup.privileges[PRIVILEGE2_NAME] & gdef.SE_PRIVILEGE_ENABLED
|
||||
|
||||
assert not newtok.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
|
||||
newtok.enable_privilege(PRIVILEGE_NAME)
|
||||
assert newtok.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
|
||||
|
||||
|
||||
def test_token_groups(curtok):
|
||||
groups = curtok.groups
|
||||
groups_size = groups.GroupCount
|
||||
assert groups_size > 0
|
||||
assert len(groups.sids) == groups_size
|
||||
assert len(groups.sids_and_attributes) == groups_size
|
||||
|
||||
def test_token_duplicate(newtok):
|
||||
x = newtok.duplicate()
|
||||
assert x.type == newtok.type
|
||||
|
||||
primtok = newtok.duplicate(type=gdef.TokenPrimary)
|
||||
assert primtok.type == gdef.TokenPrimary
|
||||
with pytest.raises(WindowsError):
|
||||
assert x.impersonation_level
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# duplicate TokenPrimary -> TokenImpersonation require explicit impersonation_level
|
||||
primtok.duplicate(type=gdef.TokenImpersonation)
|
||||
|
||||
for i in range(gdef.SecurityAnonymous, gdef.SecurityDelegation + 1):
|
||||
x = newtok.duplicate(type=gdef.TokenImpersonation, impersonation_level=i)
|
||||
assert x.type == gdef.TokenImpersonation
|
||||
assert x.impersonation_level == i
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# def test_token_groups
|
||||
|
||||
+407
-189
@@ -1,38 +1,23 @@
|
||||
import ctypes
|
||||
import functools
|
||||
from __builtin__ import type as bltn_type
|
||||
|
||||
import windows
|
||||
from windows import utils
|
||||
from windows import winproxy
|
||||
import windows.generated_def as gdef
|
||||
import windows.security
|
||||
|
||||
import functools
|
||||
|
||||
# Move to windows.security ?
|
||||
def lookup_privilege(luid, system_name=None):
|
||||
pass
|
||||
|
||||
# stolen from windows.utils :D (refactor !)
|
||||
def lookup_privilege_name(privilege_value):
|
||||
if isinstance(privilege_value, tuple):
|
||||
luid = LUID(privilege_value[1], privilege_value[0])
|
||||
privilege_value = luid
|
||||
size = DWORD(0x100)
|
||||
buff = ctypes.c_buffer(size.value)
|
||||
winproxy.LookupPrivilegeNameA(None, privilege_value, buff, size)
|
||||
return buff[:size.value]
|
||||
|
||||
KNOW_INTEGRITY_LEVEL = [
|
||||
gdef.SECURITY_MANDATORY_UNTRUSTED_RID,
|
||||
gdef.SECURITY_MANDATORY_LOW_RID,
|
||||
gdef.SECURITY_MANDATORY_MEDIUM_RID,
|
||||
gdef.SECURITY_MANDATORY_MEDIUM_PLUS_RID,
|
||||
gdef.SECURITY_MANDATORY_HIGH_RID,
|
||||
gdef.SECURITY_MANDATORY_SYSTEM_RID,
|
||||
gdef.SECURITY_MANDATORY_PROTECTED_PROCESS_RID
|
||||
]
|
||||
|
||||
know_integrity_level_mapper = gdef.FlagMapper(*KNOW_INTEGRITY_LEVEL)
|
||||
|
||||
KNOW_INTEGRITY_LEVEL = gdef.FlagMapper(
|
||||
gdef.SECURITY_MANDATORY_UNTRUSTED_RID,
|
||||
gdef.SECURITY_MANDATORY_LOW_RID,
|
||||
gdef.SECURITY_MANDATORY_MEDIUM_RID,
|
||||
gdef.SECURITY_MANDATORY_MEDIUM_PLUS_RID,
|
||||
gdef.SECURITY_MANDATORY_HIGH_RID,
|
||||
gdef.SECURITY_MANDATORY_SYSTEM_RID,
|
||||
gdef.SECURITY_MANDATORY_PROTECTED_PROCESS_RID
|
||||
)
|
||||
|
||||
# Voodoo to fix lookup-strangeness in class declaration
|
||||
def meta_craft(x):
|
||||
@@ -48,10 +33,18 @@ class TokenGroups(gdef.TOKEN_GROUPS):
|
||||
|
||||
@property
|
||||
def sids_and_attributes(self):
|
||||
"""The sids and attributes of each group
|
||||
|
||||
:type: [:class:`~windows.generated_def.winstructs.SID_AND_ATTRIBUTES`] - A list of :class:`~windows.generated_def.winstructs.SID_AND_ATTRIBUTES`
|
||||
"""
|
||||
return self._groups # Something else ?
|
||||
|
||||
@property
|
||||
def sids(self):
|
||||
"""The sids of each group
|
||||
|
||||
:type: [:class:`~windows.generated_def.winstructs.PSID`] - A list of :class:`~windows.generated_def.winstructs.PSID`
|
||||
"""
|
||||
return [g.Sid for g in self._groups]
|
||||
|
||||
def __repr__(self):
|
||||
@@ -60,19 +53,87 @@ class TokenGroups(gdef.TOKEN_GROUPS):
|
||||
TokenGroupsType = TokenGroups # Prevent confusion with token.TokenGroups
|
||||
|
||||
class TokenPrivileges(gdef.TOKEN_PRIVILEGES):
|
||||
"""Improved ``TOKEN_PRIVILEGES`` usable like a mapping"""
|
||||
@property
|
||||
def _privileges(self):
|
||||
return windows.utils.resized_array(self.Privileges, self.PrivilegeCount)
|
||||
|
||||
@property
|
||||
def all(self):
|
||||
"""The list of all privileges
|
||||
|
||||
:returns: [:class:`~windows.generated_def.winstructs.LUID_AND_ATTRIBUTES`] - A list of :class:`~windows.generated_def.winstructs.LUID_AND_ATTRIBUTES`
|
||||
"""
|
||||
return list(self._privileges)
|
||||
|
||||
def keys(self):
|
||||
"""The name of all privileges in the TokenPrivileges
|
||||
|
||||
:returns: [:class:`str`] - A list of name
|
||||
"""
|
||||
return [self._lookup_name(p.Luid) for p in self._privileges]
|
||||
|
||||
__iter__ = keys
|
||||
|
||||
def items(self):
|
||||
"""The (name, Attribute) of all privileges in the TokenPrivileges
|
||||
|
||||
:returns: [(:class:`str`, :class:`int`)] - A list of (name, Attribute) tuple
|
||||
"""
|
||||
return [(self._lookup_name(p.Luid), p.Attributes) for p in self._privileges]
|
||||
|
||||
def _get_priv_by_name(self, name):
|
||||
luid = self._lookup_value(name)
|
||||
x = [p for p in self._privileges if p.Luid == luid]
|
||||
if not x:
|
||||
return None
|
||||
assert len(x) == 1
|
||||
return x[0]
|
||||
|
||||
def __getitem__(self, name):
|
||||
"""Retrieve the attribute value for privilege ``name``
|
||||
|
||||
:raises: KeyError if privilege ``name`` not in the TokenPrivileges
|
||||
:returns: :class:`int`
|
||||
"""
|
||||
priv = self._get_priv_by_name(name)
|
||||
if not priv:
|
||||
raise KeyError(name)
|
||||
return priv.Attributes
|
||||
|
||||
def __setitem__(self, name, value):
|
||||
"""Set the attribute value for privilege ``name``
|
||||
|
||||
:raises: KeyError if privilege ``name`` not in the TokenPrivileges
|
||||
"""
|
||||
priv = self._get_priv_by_name(name)
|
||||
if not priv:
|
||||
raise KeyError(name)
|
||||
priv.Attributes = value
|
||||
|
||||
# __delitem__ that set SE_PRIVILEGE_REMOVED ?
|
||||
|
||||
def _lookup_name(self, luid):
|
||||
size = gdef.DWORD(0x100)
|
||||
buff = ctypes.c_buffer(size.value)
|
||||
winproxy.LookupPrivilegeNameA(None, luid, buff, size)
|
||||
return buff[:size.value]
|
||||
|
||||
def _lookup_value(self, name):
|
||||
luid = gdef.LUID()
|
||||
winproxy.LookupPrivilegeValueA(None, name, ctypes.byref(luid))
|
||||
return luid
|
||||
|
||||
|
||||
|
||||
TokenPrivilegesType = TokenPrivileges
|
||||
|
||||
class TokenSecurityAttributesInformation(gdef.TOKEN_SECURITY_ATTRIBUTES_INFORMATION):
|
||||
@property
|
||||
def attributes(self):
|
||||
"""Return all the attributes as :class:`TokenSecurityAttributeV1`
|
||||
|
||||
:type: [:class:`TokenSecurityAttributeV1`] - A list of token security attributes
|
||||
"""
|
||||
tptr = ctypes.cast(self.Attribute.pAttributeV1, ctypes.POINTER(TokenSecurityAttributeV1))
|
||||
# Well look like this cast does NOT keep a ref to self.
|
||||
# Setup the base object ref ourself
|
||||
@@ -93,10 +154,12 @@ class TokenSecurityAttributeV1(gdef.TOKEN_SECURITY_ATTRIBUTE_V1):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""The name of the security attribute"""
|
||||
return self.Name.str
|
||||
|
||||
@property
|
||||
def values(self):
|
||||
"""The values of the security attribute"""
|
||||
array_name = self.VALUE_ARRAY_PTR_BY_TYPE[self.ValueType]
|
||||
return getattr(self.Values, array_name)[:self.ValueCount]
|
||||
|
||||
@@ -104,9 +167,16 @@ class TokenSecurityAttributeV1(gdef.TOKEN_SECURITY_ATTRIBUTE_V1):
|
||||
return """<{0} name="{1}">""".format(type(self).__name__, self.name)
|
||||
|
||||
|
||||
|
||||
# https://docs.microsoft.com/en-us/windows/desktop/SecAuthZ/access-tokens
|
||||
class Token(utils.AutoHandle):
|
||||
"""The token of a process"""
|
||||
"""Represent a Windows Token.
|
||||
The attributes only documented by a type are from the :class:`~windows.generated_def.winstructs.TOKEN_INFORMATION_CLASS`, such return values may be improved version of the structure.
|
||||
|
||||
.. note::
|
||||
|
||||
see `[MSDN] TOKEN_INFORMATION_CLASS <https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ne-winnt-_token_information_class>`_
|
||||
"""
|
||||
def __init__(self, handle):
|
||||
self._handle = handle
|
||||
|
||||
@@ -119,7 +189,7 @@ class Token(utils.AutoHandle):
|
||||
raise
|
||||
return cbsize.value
|
||||
|
||||
def _get_token_infomations(self, infos_class, rtype):
|
||||
def get_token_infomations(self, infos_class, rtype):
|
||||
required_size = self._get_required_token_information_size(infos_class)
|
||||
requested_size = max(required_size, ctypes.sizeof(rtype))
|
||||
buffer = utils.BUFFER(rtype, 1)(size=requested_size)
|
||||
@@ -128,136 +198,285 @@ class Token(utils.AutoHandle):
|
||||
return buffer[0]
|
||||
|
||||
|
||||
craft = meta_craft(_get_token_infomations)
|
||||
def set_informations(self, info_type, infos):
|
||||
return winproxy.SetTokenInformation(self.handle, info_type, ctypes.byref(infos), ctypes.sizeof(infos))
|
||||
|
||||
|
||||
craft = meta_craft(get_token_infomations)
|
||||
# https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ne-winnt-_token_information_class
|
||||
TokenUser = craft(gdef.TokenUser, gdef.TOKEN_USER)
|
||||
TokenGroups = craft(gdef.TokenGroups , TokenGroupsType)
|
||||
TokenPrivileges = craft(gdef.TokenPrivileges , TokenPrivilegesType)
|
||||
TokenOwner = craft(gdef.TokenOwner, gdef.TOKEN_OWNER )
|
||||
TokenPrimaryGroup = craft(gdef.TokenPrimaryGroup, gdef.TOKEN_PRIMARY_GROUP)
|
||||
TokenDefaultDacl = craft(gdef.TokenDefaultDacl, gdef.TOKEN_DEFAULT_DACL )
|
||||
TokenSource = craft(gdef.TokenSource, gdef.TOKEN_SOURCE)
|
||||
TokenType = craft(gdef.TokenType, gdef.TOKEN_TYPE)
|
||||
TokenImpersonationLevel = craft(gdef.TokenImpersonationLevel, gdef.SECURITY_IMPERSONATION_LEVEL)
|
||||
TokenStatistics = craft(gdef.TokenStatistics, gdef.TOKEN_STATISTICS)
|
||||
TokenRestrictedSids = craft(gdef.TokenRestrictedSids, TokenGroupsType)
|
||||
TokenSessionId = craft(gdef.TokenSessionId, gdef.DWORD)
|
||||
TokenGroupsAndPrivileges = craft(gdef.TokenGroupsAndPrivileges, gdef.TOKEN_GROUPS_AND_PRIVILEGES)
|
||||
TokenUser = craft(gdef.TokenUser, gdef.TOKEN_USER) #: :class:`~windows.generated_def.winstructs.TOKEN_USER`
|
||||
TokenGroups = craft(gdef.TokenGroups , TokenGroupsType) #: :class:`TokenGroups`
|
||||
TokenPrivileges = craft(gdef.TokenPrivileges , TokenPrivilegesType) #: :class:`TokenPrivileges`
|
||||
TokenOwner = craft(gdef.TokenOwner, gdef.TOKEN_OWNER) #: :class:`~windows.generated_def.winstructs.TOKEN_OWNER`
|
||||
TokenPrimaryGroup = craft(gdef.TokenPrimaryGroup, gdef.TOKEN_PRIMARY_GROUP) #: :class:`~windows.generated_def.winstructs.TOKEN_PRIMARY_GROUP`
|
||||
TokenDefaultDacl = craft(gdef.TokenDefaultDacl, gdef.TOKEN_DEFAULT_DACL) #: :class:`~windows.generated_def.winstructs.TOKEN_DEFAULT_DACL`
|
||||
TokenSource = craft(gdef.TokenSource, gdef.TOKEN_SOURCE) #: :class:`~windows.generated_def.winstructs.TOKEN_SOURCE`
|
||||
TokenType = craft(gdef.TokenType, gdef.TOKEN_TYPE) #: :class:`~windows.generated_def.winstructs.TOKEN_TYPE`
|
||||
TokenImpersonationLevel = craft(gdef.TokenImpersonationLevel, gdef.SECURITY_IMPERSONATION_LEVEL) #: :class:`~windows.generated_def.winstructs.SECURITY_IMPERSONATION_LEVEL`
|
||||
TokenStatistics = craft(gdef.TokenStatistics, gdef.TOKEN_STATISTICS) #: :class:`~windows.generated_def.winstructs.TOKEN_STATISTICS`
|
||||
TokenRestrictedSids = craft(gdef.TokenRestrictedSids, TokenGroupsType) #: :class:`~windows.generated_def.winstructs.TokenGroups`
|
||||
TokenSessionId = craft(gdef.TokenSessionId, gdef.DWORD) #: :class:`~windows.generated_def.winstructs.DWORD`
|
||||
TokenGroupsAndPrivileges = craft(gdef.TokenGroupsAndPrivileges, gdef.TOKEN_GROUPS_AND_PRIVILEGES) #: :class:`~windows.generated_def.winstructs.TOKEN_GROUPS_AND_PRIVILEGES`
|
||||
# TokenSessionReference = craft(gdef.TokenSessionReference, ???) # Reserved.
|
||||
TokenSandBoxInert = craft(gdef.TokenSandBoxInert, gdef.DWORD)
|
||||
TokenSandBoxInert = craft(gdef.TokenSandBoxInert, gdef.DWORD) #: :class:`~windows.generated_def.winstructs.DWORD`
|
||||
# TokenAuditPolicy = craft(gdef.TokenAuditPolicy, ???) # Reserved.
|
||||
TokenOrigin = craft(gdef.TokenOrigin, gdef.TOKEN_ORIGIN)
|
||||
TokenElevationType = craft(gdef.TokenElevationType, gdef.TOKEN_ELEVATION_TYPE)
|
||||
TokenLinkedToken = craft(gdef.TokenLinkedToken, gdef.TOKEN_LINKED_TOKEN)
|
||||
TokenElevation = craft(gdef.TokenElevation, gdef.TOKEN_ELEVATION)
|
||||
TokenHasRestrictions = craft(gdef.TokenHasRestrictions, gdef.DWORD)
|
||||
TokenAccessInformation = craft(gdef.TokenAccessInformation, gdef.TOKEN_ACCESS_INFORMATION )
|
||||
TokenVirtualizationAllowed = craft(gdef.TokenVirtualizationAllowed, gdef.DWORD)
|
||||
TokenVirtualizationEnabled = craft(gdef.TokenVirtualizationEnabled, gdef.DWORD)
|
||||
TokenIntegrityLevel = craft(gdef.TokenIntegrityLevel, gdef.TOKEN_MANDATORY_LABEL )
|
||||
TokenUIAccess = craft(gdef.TokenUIAccess, gdef.DWORD)
|
||||
TokenMandatoryPolicy = craft(gdef.TokenMandatoryPolicy, gdef.TOKEN_MANDATORY_POLICY)
|
||||
TokenLogonSid = craft(gdef.TokenLogonSid, TokenGroupsType)
|
||||
TokenIsAppContainer = craft(gdef.TokenIsAppContainer, gdef.DWORD)
|
||||
TokenCapabilities = craft(gdef.TokenCapabilities, TokenGroupsType)
|
||||
TokenAppContainerSid = craft(gdef.TokenAppContainerSid, gdef.TOKEN_APPCONTAINER_INFORMATION)
|
||||
TokenAppContainerNumber = craft(gdef.TokenAppContainerNumber, gdef.DWORD)
|
||||
TokenUserClaimAttributes = craft(gdef.TokenUserClaimAttributes, gdef.CLAIM_SECURITY_ATTRIBUTES_INFORMATION)
|
||||
TokenDeviceClaimAttributes = craft(gdef.TokenDeviceClaimAttributes, gdef.CLAIM_SECURITY_ATTRIBUTES_INFORMATION)
|
||||
TokenOrigin = craft(gdef.TokenOrigin, gdef.TOKEN_ORIGIN) #: :class:`~windows.generated_def.winstructs.TOKEN_ORIGIN`
|
||||
TokenElevationType = craft(gdef.TokenElevationType, gdef.TOKEN_ELEVATION_TYPE) #: :class:`~windows.generated_def.winstructs.TOKEN_ELEVATION_TYPE`
|
||||
TokenLinkedToken = craft(gdef.TokenLinkedToken, gdef.TOKEN_LINKED_TOKEN) #: :class:`~windows.generated_def.winstructs.TOKEN_LINKED_TOKEN`
|
||||
TokenElevation = craft(gdef.TokenElevation, gdef.TOKEN_ELEVATION) #: :class:`~windows.generated_def.winstructs.TOKEN_ELEVATION`
|
||||
TokenHasRestrictions = craft(gdef.TokenHasRestrictions, gdef.DWORD) #: :class:`~windows.generated_def.winstructs.DWORD`
|
||||
TokenAccessInformation = craft(gdef.TokenAccessInformation, gdef.TOKEN_ACCESS_INFORMATION) #: :class:`~windows.generated_def.winstructs.TOKEN_ACCESS_INFORMATION`
|
||||
TokenVirtualizationAllowed = craft(gdef.TokenVirtualizationAllowed, gdef.DWORD) #: :class:`~windows.generated_def.winstructs.DWORD`
|
||||
TokenVirtualizationEnabled = craft(gdef.TokenVirtualizationEnabled, gdef.DWORD) #: :class:`~windows.generated_def.winstructs.DWORD`
|
||||
TokenIntegrityLevel = craft(gdef.TokenIntegrityLevel, gdef.TOKEN_MANDATORY_LABEL) #: :class:`~windows.generated_def.winstructs.TOKEN_MANDATORY_LABEL`
|
||||
TokenUIAccess = craft(gdef.TokenUIAccess, gdef.DWORD) #: :class:`~windows.generated_def.winstructs.DWORD`
|
||||
TokenMandatoryPolicy = craft(gdef.TokenMandatoryPolicy, gdef.TOKEN_MANDATORY_POLICY) #: :class:`~windows.generated_def.winstructs.TOKEN_MANDATORY_POLICY`
|
||||
TokenLogonSid = craft(gdef.TokenLogonSid, TokenGroupsType) #: :class:`TokenGroups`
|
||||
TokenIsAppContainer = craft(gdef.TokenIsAppContainer, gdef.DWORD) #: :class:`~windows.generated_def.winstructs.DWORD`
|
||||
TokenCapabilities = craft(gdef.TokenCapabilities, TokenGroupsType) #: :class:`TokenGroups`
|
||||
TokenAppContainerSid = craft(gdef.TokenAppContainerSid, gdef.TOKEN_APPCONTAINER_INFORMATION) #: :class:`~windows.generated_def.winstructs.TOKEN_APPCONTAINER_INFORMATION`
|
||||
TokenAppContainerNumber = craft(gdef.TokenAppContainerNumber, gdef.DWORD) #: :class:`~windows.generated_def.winstructs.DWORD`
|
||||
TokenUserClaimAttributes = craft(gdef.TokenUserClaimAttributes, gdef.CLAIM_SECURITY_ATTRIBUTES_INFORMATION) #: :class:`~windows.generated_def.winstructs.CLAIM_SECURITY_ATTRIBUTES_INFORMATION`
|
||||
TokenDeviceClaimAttributes = craft(gdef.TokenDeviceClaimAttributes, gdef.CLAIM_SECURITY_ATTRIBUTES_INFORMATION) #: :class:`~windows.generated_def.winstructs.CLAIM_SECURITY_ATTRIBUTES_INFORMATION`
|
||||
# TokenRestrictedUserClaimAttributes = craft(gdef.TokenRestrictedUserClaimAttributes, ???) # Reserved.
|
||||
# TokenRestrictedDeviceClaimAttributes = craft(gdef.TokenRestrictedDeviceClaimAttributes, ???) # Reserved.
|
||||
TokenDeviceGroups = craft(gdef.TokenDeviceGroups, TokenGroups)
|
||||
TokenRestrictedDeviceGroups = craft(gdef.TokenRestrictedDeviceGroups, gdef.TOKEN_GROUPS)
|
||||
TokenDeviceGroups = craft(gdef.TokenDeviceGroups, TokenGroupsType) #: :class:`TokenGroups`
|
||||
TokenRestrictedDeviceGroups = craft(gdef.TokenRestrictedDeviceGroups, gdef.TOKEN_GROUPS) #: :class:`~windows.generated_def.winstructs.TOKEN_GROUPS`
|
||||
# Reserved.
|
||||
# Structure found in ntseapi.h (thx internet)
|
||||
TokenSecurityAttributes = craft(gdef.TokenSecurityAttributes, TokenSecurityAttributesInformation)
|
||||
TokenSecurityAttributes = craft(gdef.TokenSecurityAttributes, TokenSecurityAttributesInformation) #: :class:`TokenSecurityAttributesInformation`
|
||||
# Help would be appreciated for the structures of the following query type
|
||||
|
||||
# TokenIsRestricted = craft(gdef.TokenIsRestricted, ???) # Reserved.
|
||||
# TokenProcessTrustLevel = craft(gdef.TokenProcessTrustLevel, ???) # Reserved.
|
||||
# TokenPrivateNameSpace = craft(gdef.TokenPrivateNameSpace, ???) # Reserved.
|
||||
TokenProcessTrustLevel = craft(gdef.TokenProcessTrustLevel, gdef.PSID) #: :class:`~windows.generated_def.winstructs.PSID`
|
||||
# TokenPrivateNameSpace = craft(gdef.TokenPrivateNameSpace, gdef.ULONG) # Reserved.
|
||||
# TokenSingletonAttributes = craft(gdef.TokenSingletonAttributes, ???) # Reserved.
|
||||
# TokenBnoIsolation = craft(gdef.TokenBnoIsolation, ???) # Reserved.
|
||||
# TokenChildProcessFlags = craft(gdef.TokenChildProcessFlags, ???) # Reserved.
|
||||
# TokenIsLessPrivilegedAppContainer = craft(gdef.TokenIsLessPrivilegedAppContainer, ???) # Reserved.
|
||||
|
||||
# property arround raw 'GetTokenInformation'
|
||||
# High level properties
|
||||
|
||||
@property
|
||||
def user(self):
|
||||
"""The user sid of the token
|
||||
|
||||
:type: :class:`~windows.generated_def.winstructs.PSID`
|
||||
"""
|
||||
return self.TokenUser.User.Sid
|
||||
|
||||
groups = TokenGroups # The property not the ctypes Struct
|
||||
@property
|
||||
def username(self):
|
||||
"""The username of the token
|
||||
|
||||
:type: :class:`str`
|
||||
"""
|
||||
return self._user_and_computer_name()[1]
|
||||
|
||||
@property
|
||||
def computername(self):
|
||||
"""The computername of the token
|
||||
|
||||
:type: :class:`str`
|
||||
"""
|
||||
return self._user_and_computer_name()[0]
|
||||
|
||||
def _user_and_computer_name(self):
|
||||
return windows.security.lookup_sid(self.user)
|
||||
|
||||
|
||||
groups = TokenGroups #: Alias for TokenGroups (type may change in the future for improved struct)
|
||||
|
||||
@property
|
||||
def owner(self):
|
||||
"""The owner sid of the token
|
||||
|
||||
:type: :class:`~windows.generated_def.winstructs.PSID`
|
||||
"""
|
||||
return self.TokenOwner.Owner
|
||||
|
||||
@property
|
||||
def primary_group(self):
|
||||
"""The sid of the primary group of the token
|
||||
|
||||
:type: :class:`~windows.generated_def.winstructs.PSID`
|
||||
"""
|
||||
return self.TokenPrimaryGroup.PrimaryGroup
|
||||
|
||||
@property
|
||||
def default_dacl(self):
|
||||
return self._get_token_infomations(gdef.TokenDefaultDacl, windows.security.PAcl)[0]
|
||||
"""The defaul DACL of the token
|
||||
|
||||
:type: :class:`windows.security.Acl`
|
||||
"""
|
||||
return self.get_token_infomations(gdef.TokenDefaultDacl, windows.security.PAcl)[0]
|
||||
|
||||
# def source(self): (tok.TokenSource) ??
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""The type (Primary / Impersonation) of the token
|
||||
|
||||
|
||||
"""
|
||||
return self.TokenType.value
|
||||
|
||||
@property
|
||||
def impersonation_level(self):
|
||||
return self.TokenImpersonationLevel.value
|
||||
"""The impersonation level of a ``TokenImpersonation`` token.
|
||||
|
||||
statistics = TokenStatistics
|
||||
restricted_sids = TokenRestrictedSids
|
||||
session_id = TokenSessionId
|
||||
:raises: :class:`WindowsError` if token is not a ``TokenImpersonation``
|
||||
:type: :class:`int` -- Enum value from :class:`~windows.generated_def.winstructs.SECURITY_IMPERSONATION_LEVEL`
|
||||
"""
|
||||
try:
|
||||
return self.TokenImpersonationLevel.value
|
||||
except WindowsError as e:
|
||||
if (e.winerror == gdef.ERROR_INVALID_PARAMETER and
|
||||
self.type != gdef.TokenImpersonation):
|
||||
# raise ValueError ?
|
||||
e.strerror += " This Token is not an Impersonation token"
|
||||
raise
|
||||
|
||||
statistics = TokenStatistics #: Alias for TokenStatistics (type may change in the future for improved struct)
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""The TokenId Specifies an unique identifier that identifies this instance of the token object.
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
return int(self.TokenStatistics.TokenId)
|
||||
|
||||
@property
|
||||
def authentication_id(self):
|
||||
"""The AuthenticationId Specifies an unique identifier assigned to the session this token represents.
|
||||
There can be many tokens representing a single logon session.
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
return int(self.TokenStatistics.AuthenticationId)
|
||||
|
||||
@property
|
||||
def modified_id(self):
|
||||
"""The ModifiedId Specifies an unique identifier that changes each time the token is modified.
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
return int(self.TokenStatistics.ModifiedId)
|
||||
|
||||
restricted_sids = TokenRestrictedSids #: Alias for TokenRestrictedSids (type may change in the future for improved struct)
|
||||
session_id = TokenSessionId #: Alias for TokenSessionId (type may change in the future for improved struct)
|
||||
|
||||
@property
|
||||
def groups_and_privileges(self):
|
||||
"""Alias for TokenGroupsAndPrivileges (type may change in the future for improved struct)"""
|
||||
# Return enhanced 'TOKEN_GROUPS_AND_PRIVILEGES' ?
|
||||
raise NotImplementedError("Token.groups_and_privileges")
|
||||
return self.TokenGroupsAndPrivileges
|
||||
|
||||
sandbox_inert = TokenSandBoxInert
|
||||
@property
|
||||
def privileges(self):
|
||||
"""Alias for ``TokenPrivileges``
|
||||
|
||||
# audit_policy
|
||||
:type: :class:`TokenPrivileges`
|
||||
"""
|
||||
return self.TokenPrivileges
|
||||
|
||||
sandbox_inert = TokenSandBoxInert #: Alias for TokenSandBoxInert (type may change in the future for improved struct)
|
||||
|
||||
# def audit_policy(self):
|
||||
# raise NotImplementedError("Need to find the type of TokenAuditPolicy")
|
||||
|
||||
@property
|
||||
def origin(self):
|
||||
# Make a enhanced LUID ?
|
||||
"""The originating logon session of the token.
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
origin_logon_session = self.TokenOrigin.OriginatingLogonSession
|
||||
return gdef.ULONG64.from_buffer(origin_logon_session).value
|
||||
return int(origin_logon_session) # improved LUID implem __int__ :)
|
||||
|
||||
@property
|
||||
def elevation_type(self):
|
||||
"""The elevation type of the token.
|
||||
|
||||
:type: :class:`int` -- Enum value from :class:`~windows.generated_def.winstructs.TOKEN_ELEVATION_TYPE`
|
||||
"""
|
||||
return self.TokenElevationType.value
|
||||
|
||||
@property
|
||||
def linked_token(self):
|
||||
"""The token linked to our token if present (may raise else)
|
||||
|
||||
:type: :class:`Token`
|
||||
"""
|
||||
# TODO: return None if not present ?
|
||||
return Token(self.TokenLinkedToken.LinkedToken)
|
||||
|
||||
@property
|
||||
def elevation(self):
|
||||
def elevated(self):
|
||||
"""``True`` if token is an elevated token"""
|
||||
return bool(self.TokenElevation.TokenIsElevated)
|
||||
|
||||
is_elevated = elevation # Keep this old name ?
|
||||
has_restriction = TokenHasRestrictions
|
||||
is_elevated = elevated #: Alias for ``elevated`` deprecated and may disapear
|
||||
has_restriction = TokenHasRestrictions #: Alias for TokenHasRestrictions (type may change in the future for improved struct)
|
||||
|
||||
@property
|
||||
def access_information(self):
|
||||
"""Alias for TokenAccessInformation (type may change in the future for improved struct)"""
|
||||
# Return enhanced subclass ?
|
||||
raise NotImplementedError("Token.access_information")
|
||||
# return self.TokenAccessInformation
|
||||
return self.TokenAccessInformation
|
||||
|
||||
virtualization_allowed = TokenVirtualizationAllowed
|
||||
virtualization_enabled = TokenVirtualizationEnabled
|
||||
@property
|
||||
def trust_level(self):
|
||||
"""The trust level of the process if present else ``None``.
|
||||
|
||||
:type: :class:`~windows.generated_def.winstructs.PSID`
|
||||
"""
|
||||
tl = self.TokenProcessTrustLevel
|
||||
if not tl: # NULL:
|
||||
return None
|
||||
return tl
|
||||
|
||||
virtualization_allowed = TokenVirtualizationAllowed #: Alias for TokenVirtualizationAllowed (type may change in the future for improved struct)
|
||||
virtualization_enabled = TokenVirtualizationEnabled #: Alias for TokenVirtualizationEnabled (type may change in the future for improved struct)
|
||||
|
||||
@property
|
||||
def integrity_level(self):
|
||||
# Return SID_AND_ATTRIBUTES ? Only SID ?
|
||||
"""The integrity level and attributes of the token
|
||||
|
||||
:type: :class:`windows.generated_def.winstructs.SID_AND_ATTRIBUTES`
|
||||
"""
|
||||
return self.TokenIntegrityLevel.Label # SID_AND_ATTRIBUTES
|
||||
|
||||
ui_access = TokenUIAccess
|
||||
def get_integrity(self):
|
||||
"""Return the integrity level of the token
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
sid = self.integrity_level.Sid
|
||||
count = winproxy.GetSidSubAuthorityCount(sid)
|
||||
integrity = winproxy.GetSidSubAuthority(sid, count[0] - 1)[0]
|
||||
return KNOW_INTEGRITY_LEVEL[integrity]
|
||||
|
||||
def set_integrity(self, integrity):
|
||||
"""Set the integrity level of a token
|
||||
|
||||
:param type: :class:`int`
|
||||
"""
|
||||
mandatory_label = gdef.TOKEN_MANDATORY_LABEL()
|
||||
mandatory_label.Label.Attributes = 0x60
|
||||
mandatory_label.Label.Sid = gdef.PSID.from_string("S-1-16-{0}".format(integrity))
|
||||
return self.set_informations(gdef.TokenIntegrityLevel, mandatory_label)
|
||||
|
||||
_INTEGRITY_PROPERTY_DOC = """The integrity of the token as an int (extracted from integrity PSID)
|
||||
|
||||
:getter: :func:`get_integrity`
|
||||
:setter: :func:`set_integrity`
|
||||
"""
|
||||
|
||||
integrity = property(get_integrity, set_integrity, doc=_INTEGRITY_PROPERTY_DOC)
|
||||
|
||||
ui_access = TokenUIAccess #: Alias for TokenUIAccess (type may change in the future for improved struct)
|
||||
|
||||
VALID_TOKEN_POLICIES = gdef.FlagMapper(
|
||||
gdef.TOKEN_MANDATORY_POLICY_OFF,
|
||||
@@ -268,129 +487,128 @@ class Token(utils.AutoHandle):
|
||||
|
||||
@property
|
||||
def mandatory_policy(self):
|
||||
"""mandatory integrity access policy for the associated token
|
||||
|
||||
:type: :class:`int` -- see `[MSDN] mandatory policy <https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_token_mandatory_policy>`_
|
||||
"""
|
||||
return self.VALID_TOKEN_POLICIES[self.TokenMandatoryPolicy.Policy]
|
||||
|
||||
@property
|
||||
def logon_sid(self):
|
||||
"""The logon sid of the token. (Case of multiple logon sid not handled and will raise AssertionError)
|
||||
|
||||
:type: :class:`windows.generated_def.winstructs.SID_AND_ATTRIBUTES`
|
||||
"""
|
||||
rgroups = self.TokenLogonSid
|
||||
assert rgroups.GroupCount == 1, "More than 1 TokenLogonSid"
|
||||
return rgroups.Groups[0]
|
||||
|
||||
is_appcontainer = TokenIsAppContainer
|
||||
capabilities = TokenCapabilities
|
||||
is_appcontainer = TokenIsAppContainer #: Alias for TokenIsAppContainer (type may change in the future for improved struct)
|
||||
capabilities = TokenCapabilities #: Alias for TokenCapabilities (type may change in the future for improved struct)
|
||||
|
||||
@property
|
||||
def appcontainer_sid(self):
|
||||
return self.TokenAppContainerSid.TokenAppContainer
|
||||
"""The sid of the TokenAppContainerSid if present else ``None``
|
||||
|
||||
appcontainer_number = TokenAppContainerNumber
|
||||
:type: :class:`~windows.generated_def.winstructs.PSID`
|
||||
"""
|
||||
sid = self.TokenAppContainerSid.TokenAppContainer
|
||||
if not sid: # NULL
|
||||
return None
|
||||
return sid
|
||||
|
||||
# def security_attribute:
|
||||
# see PTOKEN_SECURITY_ATTRIBUTES_INFORMATION
|
||||
# https://github.com/wj32/Backup/blob/59aa77379f9f7ca57f27265e796dd2fe4dae9fab/include/phnt/ntseapi.h
|
||||
# blablabla :)
|
||||
appcontainer_number = TokenAppContainerNumber #: Alias for TokenAppContainerNumber (type may change in the future for improved struct)
|
||||
|
||||
@property
|
||||
def security_attributes(self):
|
||||
"""The security attributes of the token
|
||||
|
||||
:type: [:class:`TokenSecurityAttributeV1`] - A list of token security attributes
|
||||
"""
|
||||
return self.TokenSecurityAttributes.attributes
|
||||
|
||||
|
||||
def duplicate(self, access_rigth=0, attributes=None, impersonation_level=gdef.SecurityImpersonation, toktype=gdef.TokenPrimary):
|
||||
## Token Methods
|
||||
def duplicate(self, access_rigth=gdef.MAXIMUM_ALLOWED, attributes=None, type=None, impersonation_level=None):
|
||||
"""Duplicate the token into a new :class:`Token`.
|
||||
|
||||
:param type: The type of token: ``TokenPrimary(0x1L)`` or ``TokenImpersonation(0x2L)``
|
||||
:param impersonation_level: The :class:`~windows.generated_def.winstructs.SECURITY_IMPERSONATION_LEVEL` for a ``TokenImpersonation(0x2L)``:
|
||||
|
||||
- If ``type`` is ``TokenPrimary(0x1L)`` this parameter is ignored if ``None`` or used as-is.
|
||||
- If ``type`` is ``TokenImpersonation(0x2L)`` and this parameter is None, ``self.impersonation_level`` is used.
|
||||
- If ``type`` is ``TokenImpersonation(0x2L)`` and our Token is a ``TokenPrimary(0x1L)`` this parameter MUST be provided
|
||||
|
||||
:returns: :class:`Token` - The duplicate token
|
||||
|
||||
Example:
|
||||
|
||||
>>> tok
|
||||
<Token TokenId=0x39d6dde5 Type=TokenPrimary(0x1L)>
|
||||
>>> tok.duplicate()
|
||||
<Token TokenId=0x39d7b206 Type=TokenPrimary(0x1L)>
|
||||
>>> tok.duplicate(type=gdef.TokenImpersonation)
|
||||
...
|
||||
ValueError: Duplicating a PrimaryToken as a TokenImpersonation require explicit <impersonation_level> parameter
|
||||
>>> tok.duplicate(type=gdef.TokenImpersonation, impersonation_level=gdef.SecurityImpersonation)
|
||||
<Token TokenId=0x39dadbf8 Type=TokenImpersonation(0x2L) ImpersonationLevel=SecurityImpersonation(0x2L)>
|
||||
"""
|
||||
newtoken = gdef.HANDLE()
|
||||
winproxy.DuplicateTokenEx(self.handle, access_rigth, attributes, impersonation_level, toktype, newtoken)
|
||||
return type(self)(newtoken.value)
|
||||
if type is None:
|
||||
type = self.type
|
||||
if impersonation_level is None:
|
||||
if self.type == gdef.TokenImpersonation:
|
||||
impersonation_level = self.impersonation_level
|
||||
elif type != gdef.TokenImpersonation:
|
||||
impersonation_level = 0 #: ignored
|
||||
else:
|
||||
raise ValueError("Duplicating a PrimaryToken as a TokenImpersonation require explicit <impersonation_level> parameter")
|
||||
winproxy.DuplicateTokenEx(self.handle, access_rigth, attributes, impersonation_level, type, newtoken)
|
||||
return bltn_type(self)(newtoken.value)
|
||||
|
||||
def adjust_privileges(self, privileges):
|
||||
"""Adjust the token privileges according to ``privileges``.
|
||||
This API is the `complex one` to adjust multiple privileges at once.
|
||||
|
||||
To simply enable one privilege see :func:`enable_privilege`.
|
||||
|
||||
### OLD CODE
|
||||
:param privileges: :class:`~windows.generated_def.winstructs.TOKEN_PRIVILEGES` (or subclass as :class:`TokenPrivileges`). To easily update your token privileges use the result of :data:`privileges`.
|
||||
|
||||
def get_integrity(self):
|
||||
"""Return the integrity level of a token
|
||||
Example:
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
buffer_size = self.get_required_information_size(gdef.TokenIntegrityLevel)
|
||||
buffer = ctypes.c_buffer(buffer_size)
|
||||
self.get_informations(gdef.TokenIntegrityLevel, buffer)
|
||||
sid = ctypes.cast(buffer, ctypes.POINTER(gdef.TOKEN_MANDATORY_LABEL))[0].Label.Sid
|
||||
count = winproxy.GetSidSubAuthorityCount(sid)
|
||||
integrity = winproxy.GetSidSubAuthority(sid, count[0] - 1)[0]
|
||||
return know_integrity_level_mapper[integrity]
|
||||
>>> tok = windows.current_process.token
|
||||
>>> privs = tok.privileges
|
||||
>>> privs["SeShutdownPrivilege"] = gdef.SE_PRIVILEGE_ENABLED
|
||||
>>> privs["SeUndockPrivilege"] = gdef.SE_PRIVILEGE_ENABLED
|
||||
>>> tok.adjust_privileges(privs)
|
||||
|
||||
def set_integrity(self, integrity):
|
||||
"""Set the integrity level of a token
|
||||
"""
|
||||
buffsize = None
|
||||
if isinstance(privileges, TokenPrivilegesType):
|
||||
# The TokenPrivilegesType should come from a PTR via Improved buffer
|
||||
try:
|
||||
buffsize = privileges._b_base_.real_size
|
||||
except AttributeError as e:
|
||||
pass
|
||||
if buffsize is None:
|
||||
buffsize = ctypes.sizeof(privileges)
|
||||
winproxy.AdjustTokenPrivileges(self.handle, False, privileges, buffsize, None, None)
|
||||
if winproxy.GetLastError() == gdef.ERROR_NOT_ALL_ASSIGNED:
|
||||
raise ValueError("Failed to adjust all privileges")
|
||||
|
||||
:param type: :class:`int`
|
||||
"""
|
||||
mandatory_label = gdef.TOKEN_MANDATORY_LABEL()
|
||||
mandatory_label.Label.Attributes = 0x60
|
||||
mandatory_label.Label.Sid = gdef.PSID.from_string("S-1-16-{0}".format(integrity))
|
||||
self.set_informations(gdef.TokenIntegrityLevel, mandatory_label)
|
||||
|
||||
integrity = property(get_integrity, set_integrity)
|
||||
|
||||
@property
|
||||
def is_elevated(self):
|
||||
"""``True`` if process is Admin"""
|
||||
elevation = gdef.TOKEN_ELEVATION()
|
||||
self.get_informations(gdef.TokenElevation, elevation)
|
||||
return bool(elevation.TokenIsElevated)
|
||||
|
||||
@property
|
||||
def token_user(self):
|
||||
buffer_size = self.get_required_information_size(gdef.TokenUser)
|
||||
buffer = ctypes.c_buffer(buffer_size)
|
||||
self.get_informations(gdef.TokenUser, buffer)
|
||||
return ctypes.cast(buffer, ctypes.POINTER(gdef.TOKEN_USER))[0]
|
||||
|
||||
@property
|
||||
def computername(self):
|
||||
"""The computername of the token"""
|
||||
return self._user_and_computer_name()[1]
|
||||
|
||||
@property
|
||||
def username(self):
|
||||
"""The username of the token"""
|
||||
return self._user_and_computer_name()[0]
|
||||
|
||||
|
||||
|
||||
def _user_and_computer_name(self):
|
||||
tok_usr = self.token_user
|
||||
sid = tok_usr.User.Sid
|
||||
usernamesize = gdef.DWORD(0x1000)
|
||||
computernamesize = gdef.DWORD(0x1000)
|
||||
username = ctypes.c_buffer(usernamesize.value)
|
||||
computername = ctypes.c_buffer(computernamesize.value)
|
||||
peUse = gdef.SID_NAME_USE()
|
||||
winproxy.LookupAccountSidA(None, sid, username, usernamesize, computername, computernamesize, peUse)
|
||||
return username[:usernamesize.value], computername[:computernamesize.value]
|
||||
|
||||
def get_informations(self, info_type, data):
|
||||
cbsize = gdef.DWORD()
|
||||
winproxy.GetTokenInformation(self.handle, info_type, ctypes.byref(data), ctypes.sizeof(data), ctypes.byref(cbsize))
|
||||
return cbsize.value
|
||||
|
||||
def get_required_information_size(self, info_type):
|
||||
cbsize = gdef.DWORD()
|
||||
def enable_privilege(self, name):
|
||||
"""Enable privilege ``name`` in the token"""
|
||||
privs = self.privileges
|
||||
try:
|
||||
winproxy.GetTokenInformation(self.handle, info_type, None, 0, ctypes.byref(cbsize))
|
||||
except WindowsError as e:
|
||||
if not e.winerror == gdef.ERROR_INSUFFICIENT_BUFFER:
|
||||
raise
|
||||
return cbsize.value
|
||||
|
||||
#TODO: TEST + DOC
|
||||
def set_informations(self, info_type, infos):
|
||||
return winproxy.SetTokenInformation(self.handle, info_type, ctypes.byref(infos), ctypes.sizeof(infos))
|
||||
|
||||
# TEST
|
||||
def dacl(self):
|
||||
"""TEST CODE"""
|
||||
buffer_size = self.get_required_information_size(TokenDefaultDacl)
|
||||
buffer = ctypes.c_buffer(buffer_size)
|
||||
self.get_informations(gdef.TokenDefaultDacl, buffer)
|
||||
# TODO: use windows.security.Acl
|
||||
return ctypes.cast(buffer, POINTER(TOKEN_DEFAULT_DACL))[0]
|
||||
|
||||
|
||||
privs[name] = gdef.SE_PRIVILEGE_ENABLED
|
||||
except KeyError as e:
|
||||
raise ValueError("{0} as no privilege <{1}>".format(self, name))
|
||||
return self.adjust_privileges(privs)
|
||||
|
||||
def __repr__(self):
|
||||
tid_int = gdef.ULONG64.from_buffer(self.TokenStatistics.TokenId).value
|
||||
return "<{0} TokenId={1:#x}>".format(type(self).__name__, tid_int)
|
||||
flag_repr = gdef.Flag.__repr__
|
||||
tid_int = int(self.TokenStatistics.TokenId)
|
||||
toktype = self.type
|
||||
if toktype == gdef.TokenPrimary:
|
||||
return "<{0} TokenId={1:#x} Type={2}>".format(type(self).__name__, tid_int, flag_repr(toktype))
|
||||
return "<{0} TokenId={1:#x} Type={2} ImpersonationLevel={3}>".format(type(self).__name__, tid_int, flag_repr(toktype), flag_repr(self.impersonation_level))
|
||||
|
||||
Reference in New Issue
Block a user