Skip to content

Commit 986664d

Browse files
committed
update Doc + test + sample for token.py
1 parent 8dc2d44 commit 986664d

5 files changed

Lines changed: 598 additions & 208 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(cmd) python debug\debugger_on_setup.py
2+
== With on_setup ==
3+
Setup called: <WinProcess "whoami.exe" pid 29796 at 0x4ccb790>
4+
<whoami output>
5+
Process exit: <WinProcess "whoami.exe" pid 29796 (DEAD) at 0x4ccb790>
6+
7+
== Without on_setup ==
8+
Exception: EXCEPTION_BREAKPOINT(0x80000003L)
9+
<whoami output>
10+
Process exit: <WinProcess "whoami.exe" pid 33328 (DEAD) at 0x4ccbdb0>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
(cmd) python token\token_demo.py
2+
Our process token is <Token TokenId=0x3f1f98fd Type=TokenPrimary(0x1L)>
3+
Retrieving some infos
4+
Username: <hakril>
5+
User: <PSID "S-1-5-21-184905214-2723199098-2761450773-1001">
6+
- lookup : ('WILLIE', 'hakril')
7+
Primary group: <PSID "S-1-5-21-184905214-2723199098-2761450773-513">
8+
- lookup : ('WILLIE', 'Aucun')
9+
10+
Token Groups is <TokenGroups count=15>
11+
First group SID is <PSID "S-1-5-21-184905214-2723199098-2761450773-513">
12+
Some sid and attributes:
13+
- S-1-5-21-184905214-2723199098-2761450773-513: 7
14+
- S-1-1-0: 7
15+
- S-1-5-114: 16
16+
17+
Duplicate token is <Token TokenId=0x3f1fac85 Type=TokenImpersonation(0x2L) ImpersonationLevel=SecurityImpersonation(0x2L)>
18+
Enabling <SeShutDownPrivilege>
19+
Current thread token is <None>
20+
Setting impersonation token !
21+
Current thread token is <Token TokenId=0x3f1fac85 Type=TokenImpersonation(0x2L) ImpersonationLevel=SecurityImpersonation(0x2L)>

docs/source/token.rst

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
Token
2+
"""""
3+
4+
.. module:: windows.winobject.token
5+
6+
This module expose the :class:`Token` object that can be primarily retrieved through:
7+
8+
* :data:`windows.winobject.process.WinProcess.token`
9+
* :data:`windows.winobject.process.WinThread.token`
10+
* :data:`windows.current_process.token <windows.winobject.process.CurrentProcess.token>`
11+
* :data:`windows.current_thread.token <windows.winobject.process.CurrentThread.token>`
12+
13+
.. note::
14+
15+
See sample :ref:`token_sample`
16+
17+
18+
Token
19+
'''''
20+
21+
.. autoclass:: Token
22+
:members:
23+
:inherited-members:
24+
25+
26+
TokenGroups
27+
'''''''''''
28+
29+
.. autoclass:: TokenGroups
30+
:show-inheritance:
31+
:members:
32+
:inherited-members:
33+
34+
35+
36+
TokenPrivileges
37+
'''''''''''''''
38+
39+
.. autoclass:: TokenPrivileges
40+
:show-inheritance:
41+
:special-members: __getitem__, __setitem__
42+
:members:
43+
:inherited-members:
44+
45+
46+
TokenSecurityAttributesInformation
47+
''''''''''''''''''''''''''''''''''
48+
49+
.. autoclass:: TokenSecurityAttributesInformation
50+
:show-inheritance:
51+
:members:
52+
:inherited-members:
53+
54+
55+
TokenSecurityAttributeV1
56+
''''''''''''''''''''''''
57+
58+
.. autoclass:: TokenSecurityAttributeV1
59+
:show-inheritance:
60+
:members:
61+
:inherited-members:

tests/test_token.py

Lines changed: 99 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,108 @@
1+
import pytest
2+
import os
3+
14
import windows
5+
import windows.security
26
import windows.generated_def as gdef
37

8+
@pytest.fixture
9+
def curtok():
10+
return windows.current_process.token
11+
12+
@pytest.fixture
13+
def newtok():
14+
return windows.current_process.token.duplicate()
15+
16+
def test_token_info(curtok):
17+
assert isinstance(curtok.computername, basestring)
18+
assert isinstance(curtok.username, basestring)
19+
assert isinstance(curtok.integrity, (int, long))
20+
assert isinstance(curtok.is_elevated, (bool))
21+
22+
def test_lower_integrity(newtok):
23+
assert newtok.integrity != 123
24+
# Change token integrity
25+
newtok.integrity = 123
26+
# newtok.integrity retrieve the integrity at each call so this in enough
27+
assert newtok.integrity == 123
28+
29+
def test_token_user(curtok):
30+
user_sid = curtok.user
31+
assert user_sid
32+
computername, username = windows.security.lookup_sid(user_sid)
33+
assert computername == windows.system.computer_name
34+
assert username == os.environ["USERNAME"]
35+
36+
def test_token_id(curtok):
37+
ntok = curtok.duplicate()
38+
assert ntok.id != curtok.id
39+
mid = ntok.modified_id
40+
aid = ntok.authentication_id
41+
ntok.enable_privilege("SeShutDownPrivilege")
42+
mid2 = ntok.modified_id
43+
aid2 = ntok.authentication_id
44+
ntok.integrity -= 1
45+
assert ntok.modified_id != mid2 != mid
46+
assert ntok.authentication_id == aid2 == aid
47+
48+
49+
def test_enable_privilege(newtok):
50+
PRIVILEGE_NAME = "SeShutdownPrivilege"
51+
assert not newtok.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
52+
newtok.enable_privilege(PRIVILEGE_NAME)
53+
assert newtok.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
54+
55+
56+
def test_adjust_privilege(newtok):
57+
PRIVILEGE_NAME = "SeShutdownPrivilege"
58+
PRIVILEGE2_NAME = "SeTimeZonePrivilege"
59+
tok_dup = newtok.duplicate()
60+
assert not tok_dup.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
61+
assert not tok_dup.privileges[PRIVILEGE2_NAME] & gdef.SE_PRIVILEGE_ENABLED
62+
# Enable privilege in another token.
63+
privs = newtok.privileges
64+
assert not privs[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
65+
assert not privs[PRIVILEGE2_NAME] & gdef.SE_PRIVILEGE_ENABLED
66+
67+
privs[PRIVILEGE_NAME] = gdef.SE_PRIVILEGE_ENABLED
68+
privs[PRIVILEGE2_NAME] = gdef.SE_PRIVILEGE_ENABLED
69+
tok_dup.adjust_privileges(privs)
70+
71+
assert tok_dup.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
72+
assert tok_dup.privileges[PRIVILEGE2_NAME] & gdef.SE_PRIVILEGE_ENABLED
73+
74+
assert not newtok.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
75+
newtok.enable_privilege(PRIVILEGE_NAME)
76+
assert newtok.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED
77+
78+
79+
def test_token_groups(curtok):
80+
groups = curtok.groups
81+
groups_size = groups.GroupCount
82+
assert groups_size > 0
83+
assert len(groups.sids) == groups_size
84+
assert len(groups.sids_and_attributes) == groups_size
85+
86+
def test_token_duplicate(newtok):
87+
x = newtok.duplicate()
88+
assert x.type == newtok.type
89+
90+
primtok = newtok.duplicate(type=gdef.TokenPrimary)
91+
assert primtok.type == gdef.TokenPrimary
92+
with pytest.raises(WindowsError):
93+
assert x.impersonation_level
94+
95+
with pytest.raises(ValueError):
96+
# duplicate TokenPrimary -> TokenImpersonation require explicit impersonation_level
97+
primtok.duplicate(type=gdef.TokenImpersonation)
498

99+
for i in range(gdef.SecurityAnonymous, gdef.SecurityDelegation + 1):
100+
x = newtok.duplicate(type=gdef.TokenImpersonation, impersonation_level=i)
101+
assert x.type == gdef.TokenImpersonation
102+
assert x.impersonation_level == i
5103

6-
def test_token_info():
7-
token = windows.current_process.token
8-
assert isinstance(token.computername, basestring)
9-
assert isinstance(token.username, basestring)
10-
assert isinstance(token.integrity, (int, long))
11-
assert isinstance(token.is_elevated, (bool))
12104

13-
def test_lower_integrity(proc32):
14-
# Lowering the integrity in remote process
15-
# Because we don't want to mess with the token of our testing process
16105

17-
proc32.execute_python("import windows")
18-
# We stock the handle becase lowering the integrity
19-
# will mess with token retrieval
20-
proc32.execute_python("token = windows.current_process.token")
21-
proc32.execute_python("token.integrity = 123")
22-
# execute_python will raise this in our own process :)
23-
proc32.execute_python("assert token.integrity == 123")
24106

25107

26-
def test_token_elevation():
27-
tok = windows.current_process.token
28-
assert tok.TokenElevation
108+
# def test_token_groups

0 commit comments

Comments
 (0)