mirror of
https://github.com/login-securite/DonPAPI
synced 2025-01-23 15:23:40 +00:00
221 lines
6.3 KiB
Python
221 lines
6.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Original code from https://github.com/joren485/PyWinPrivEsc/blob/master/RunAsSystem.py
|
|
|
|
import sys
|
|
import traceback
|
|
|
|
from lazagne.config.write_output import print_debug
|
|
from lazagne.config.winstructure import *
|
|
|
|
import os
|
|
|
|
|
|
def get_token_info(hToken):
|
|
"""
|
|
Retrieve SID and user owner from Token
|
|
"""
|
|
dwSize = DWORD(0)
|
|
pStringSid = LPWSTR()
|
|
TokenUser = 1
|
|
|
|
if GetTokenInformation(hToken, TokenUser, byref(TOKEN_USER()), 0, byref(dwSize)) == 0:
|
|
address = LocalAlloc(0x0040, dwSize)
|
|
if address:
|
|
GetTokenInformation(hToken, TokenUser, address, dwSize, byref(dwSize))
|
|
pToken_User = cast(address, POINTER(TOKEN_USER))
|
|
if pToken_User.contents.User.Sid:
|
|
ConvertSidToStringSid(pToken_User.contents.User.Sid, byref(pStringSid))
|
|
owner, domaine, _ = LookupAccountSidW(None, pToken_User.contents.User.Sid)
|
|
if pStringSid:
|
|
sid = pStringSid.value
|
|
LocalFree(address)
|
|
return sid, owner
|
|
return None, None
|
|
|
|
|
|
def enable_privilege(privilegeStr, hToken=None):
|
|
"""
|
|
Enable Privilege on token, if no token is given the function gets the token of the current process.
|
|
"""
|
|
if hToken == None:
|
|
hToken = HANDLE(INVALID_HANDLE_VALUE)
|
|
if not hToken:
|
|
return False
|
|
|
|
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, os.getpid())
|
|
if not hProcess:
|
|
return False
|
|
|
|
OpenProcessToken(hProcess, (TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY), byref(hToken))
|
|
e = GetLastError()
|
|
if e != 0:
|
|
return False
|
|
CloseHandle(hProcess)
|
|
|
|
privilege_id = LUID()
|
|
LookupPrivilegeValueA(None, privilegeStr, byref(privilege_id))
|
|
e = GetLastError()
|
|
if e != 0:
|
|
return False
|
|
|
|
SE_PRIVILEGE_ENABLED = 0x00000002
|
|
laa = LUID_AND_ATTRIBUTES(privilege_id, SE_PRIVILEGE_ENABLED)
|
|
tp = TOKEN_PRIVILEGES(1, laa)
|
|
|
|
AdjustTokenPrivileges(hToken, False, byref(tp), sizeof(tp), None, None)
|
|
e = GetLastError()
|
|
if e != 0:
|
|
return False
|
|
return True
|
|
|
|
|
|
def get_debug_privilege():
|
|
"""
|
|
Enable SE Debug privilege on token
|
|
"""
|
|
return RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE)
|
|
|
|
|
|
def list_sids():
|
|
"""
|
|
List all SID by process
|
|
"""
|
|
sids = []
|
|
for pid in EnumProcesses():
|
|
if pid <= 4:
|
|
continue
|
|
|
|
try:
|
|
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, pid)
|
|
if not hProcess:
|
|
continue
|
|
|
|
hToken = HANDLE(INVALID_HANDLE_VALUE)
|
|
if OpenProcessToken(hProcess, tokenprivs, byref(hToken)):
|
|
if hToken:
|
|
token_sid, owner = get_token_info(hToken)
|
|
if token_sid and owner:
|
|
pname = ''
|
|
sids.append((pid, pname, token_sid, owner))
|
|
CloseHandle(hToken)
|
|
|
|
CloseHandle(hProcess)
|
|
|
|
except Exception as e:
|
|
print_debug('DEBUG', traceback.format_exc())
|
|
continue
|
|
|
|
return list(sids)
|
|
|
|
|
|
def get_sid_token(token_sid):
|
|
if token_sid == "S-1-5-18":
|
|
sids = list_sids()
|
|
for sid in sids:
|
|
if "winlogon" in sid[1].lower():
|
|
try:
|
|
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, sid[0])
|
|
if hProcess:
|
|
hToken = HANDLE(INVALID_HANDLE_VALUE)
|
|
if hToken:
|
|
OpenProcessToken(hProcess, tokenprivs, byref(hToken))
|
|
if hToken:
|
|
print_debug('INFO', u'Using PID: ' + str(sid[0]))
|
|
CloseHandle(hProcess)
|
|
return hToken
|
|
|
|
# CloseHandle(hToken)
|
|
CloseHandle(hProcess)
|
|
except Exception as e:
|
|
print_debug('ERROR', u'{error}'.format(error=e))
|
|
break
|
|
return False
|
|
|
|
for pid in EnumProcesses():
|
|
if pid <= 4:
|
|
continue
|
|
|
|
try:
|
|
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, int(pid))
|
|
if hProcess:
|
|
hToken = HANDLE(INVALID_HANDLE_VALUE)
|
|
if hToken:
|
|
OpenProcessToken(hProcess, tokenprivs, byref(hToken))
|
|
if hToken:
|
|
sid, owner = get_token_info(hToken)
|
|
if sid == token_sid:
|
|
print_debug('INFO', u'Impersonate token from pid: ' + str(pid))
|
|
CloseHandle(hProcess)
|
|
return hToken
|
|
CloseHandle(hToken)
|
|
CloseHandle(hProcess)
|
|
except Exception as e:
|
|
print_debug('ERROR', u'{error}'.format(error=e))
|
|
|
|
return False
|
|
|
|
|
|
def impersonate_sid(sid, close=True):
|
|
"""
|
|
Try to impersonate an SID
|
|
"""
|
|
hToken = get_sid_token(sid)
|
|
if hToken:
|
|
hTokendupe = impersonate_token(hToken)
|
|
if hTokendupe:
|
|
if close:
|
|
CloseHandle(hTokendupe)
|
|
return hTokendupe
|
|
return False
|
|
|
|
|
|
global_ref = None
|
|
|
|
|
|
def impersonate_sid_long_handle(*args, **kwargs):
|
|
"""
|
|
Try to impersonate an SID
|
|
"""
|
|
global global_ref
|
|
hTokendupe = impersonate_sid(*args, **kwargs)
|
|
if not hTokendupe:
|
|
return False
|
|
|
|
if global_ref:
|
|
CloseHandle(global_ref)
|
|
|
|
global_ref = hTokendupe
|
|
return addressof(hTokendupe)
|
|
|
|
|
|
def impersonate_token(hToken):
|
|
"""
|
|
Impersonate token - Need admin privilege
|
|
"""
|
|
if get_debug_privilege():
|
|
hTokendupe = HANDLE(INVALID_HANDLE_VALUE)
|
|
if hTokendupe:
|
|
SecurityImpersonation = 2
|
|
TokenPrimary = 1
|
|
if DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, None, SecurityImpersonation, TokenPrimary, byref(hTokendupe)):
|
|
CloseHandle(hToken)
|
|
if ImpersonateLoggedOnUser(hTokendupe):
|
|
return hTokendupe
|
|
else:
|
|
print_debug('DEBUG', 'Get debug privilege failed')
|
|
return False
|
|
|
|
|
|
def rev2self():
|
|
"""
|
|
Back to previous token priv
|
|
"""
|
|
global global_ref
|
|
RevertToSelf()
|
|
try:
|
|
if global_ref:
|
|
CloseHandle(global_ref)
|
|
except Exception:
|
|
pass
|
|
global_ref = None
|