RunAsTIplus

Pomocí programu RunAsTIplus se spustí jakýkoliv program s právy TrustedInstaller. Vhodné na mazání a úpravu složek, souborů a registru v případě, že na takovou operaci nejsou dostatečná práva a kdy nestačí ani práva správce.

Příklady použití

Bez parametru spustí cmd s právy TrustedInstaller. S jedním parametrem spustí program (například regedit.exe) v první parametru s právy TrustedInstaller. Se třemi parametry pracuje jako RunFromToken, kdy první parametr je název procesu, druhý je session id a třetí příkaz, který se má vykonat.

RunAsTIplus.exe
RunAsTIplus.exe regedit.exe
RunAsTIplus.exe trustedinstaller.exe 1 regedit

Binárky

Zdrojový kód

#RequireAdmin
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_Comment=Start program with same privileges as TrustedInstaller
#AutoIt3Wrapper_Res_Description=Start program with same privileges as TrustedInstaller
#AutoIt3Wrapper_Res_Fileversion=1.0.0.0
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Global Const $tagOBJECTATTRIBUTES = "ulong Length;hwnd RootDirectory;ptr ObjectName;ulong Attributes;ptr SecurityDescriptor;ptr SecurityQualityOfService"
Global Const $tagUNICODESTRING = "ushort Length;ushort MaximumLength;ptr Buffer"
Global Const $tagSTARTUPINFO1 = "dword cb;ptr lpReserved;ptr lpDesktop;ptr lpTitle;dword dwX;dword dwY;dword dwXSize;dword dwYSize;" & _
						"dword dwXCountChars;dword dwYCountChars;dword dwFillAttribute;dword dwFlags;ushort wShowWindow;" & _
						"ushort cbReserved2;ptr lpReserved2;ptr hStdInput;ptr hStdOutput;ptr hStdError"
Global Const $tagPROCESSINFO1 = "ptr hProcess;ptr hThread;dword dwProcessId;dword dwThreadId"
Global $ghADVAPI32 = DllOpen("advapi32.dll")


If $cmdline[0] < 2 Then
	$Privs = "SeDebugPrivilege,SeAssignPrimaryTokenPrivilege,SeIncreaseQuotaPrivilege,SeImpersonateName"
	$PrivsArray = StringSplit($Privs,",")
	For $i = 1 To $PrivsArray[0]
		_SetPrivilege($PrivsArray[$i])
	Next
	If $cmdline[0] = 0 Then
		$sCmdLine = "cmd.exe"
	Else
		$sCmdLine = $cmdline[1]
	EndIf
	$dwSessionId = DllCall("kernel32.dll", "dword", "WTSGetActiveConsoleSessionId")
	If @error Or $dwSessionId[0] = 0xFFFFFFFF Then Exit
	$dwSessionId = $dwSessionId[0]
	Dim $aProcs = ProcessList("winlogon.exe"), $processPID = -1, $ret
	For $i = 1 To $aProcs[0][0]
		$ret = DllCall("kernel32.dll", "int", "ProcessIdToSessionId", "dword", $aProcs[$i][1], "dword*", 0)
		If Not @error And $ret[0] And ($ret[2] = $dwSessionId) Then
			$processPID = $aProcs[$i][1]
			ExitLoop
		EndIf
	Next
	If $processPID = -1 Then Exit
	Local $hProc = DllCall("kernel32.dll", "ptr", "OpenProcess", "dword", 0x001F0FFF, "int", 0, "dword", $processPID)
	If @error Or Not $hProc[0] Then Exit
	$hProc = $hProc[0]
	$hToken = DllCall($ghADVAPI32, "int", "OpenProcessToken", "ptr", $hProc, "dword", 0x2, "ptr*", 0)
	If @error Or Not $hToken[0] Then
		DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc)
		Exit
	EndIf
	$hToken = $hToken[3]
	$hDupToken = DllCall($ghADVAPI32, "int", "DuplicateTokenEx", "ptr", $hToken, "dword", 0x1F0FFF, "ptr", 0, "int", 1, "int", 1, "ptr*", 0)
	If @error Or Not $hDupToken[0] Then
		DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hToken)
		DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc)
		Exit
	EndIf
	$sCmdLine = """" & @ScriptFullPath & """" & " trustedinstaller.exe " & $dwSessionId & " " & $sCmdLine
	run("cmd.exe /c sc start trustedinstaller", "", @SW_HIDE, 0x10000)
	$hDupToken = $hDupToken[6]
	$pEnvBlock = _GetEnvironmentBlock("winlogon.exe", $dwSessionId)
	$dwCreationFlags = BitOR(0x00000020, 0x00000010)
	If $pEnvBlock Then $dwCreationFlags = BitOR($dwCreationFlags, 0x00000400)
	$SI = DllStructCreate($tagSTARTUPINFO1)
	DllStructSetData($SI, "cb", DllStructGetSize($SI))
	$PI = DllStructCreate($tagPROCESSINFO1)
	$sDesktop = "winsta0\default"
	$lpDesktop = DllStructCreate("wchar[" & StringLen($sDesktop) + 1 & "]")
	DllStructSetData($lpDesktop, 1, $sDesktop)
	DllStructSetData($SI, "lpDesktop", DllStructGetPtr($lpDesktop))
	$ret = DllCall($ghADVAPI32, "bool", "CreateProcessWithTokenW", "handle", $hDupToken, "dword", 1, "ptr", 0, "wstr", $sCmdLine, _
					"dword", $dwCreationFlags, "ptr", $pEnvBlock, "wstr", @WindowsDir, "ptr", DllStructGetPtr($SI), "ptr", DllStructGetPtr($PI))
	If @error or Not $ret[0] Then
		$ret = DllCall($ghADVAPI32, "int", "CreateProcessAsUserW", "handle", $hDupToken, "ptr", 0, "wstr", $sCmdLine, "ptr", 0, "ptr", 0, "int", 0, _
						"dword", $dwCreationFlags, "ptr", $pEnvBlock, "ptr", 0, "ptr", DllStructGetPtr($SI), "ptr", DllStructGetPtr($PI))
		If Not @error And $ret[0] Then
			DllCall("kernel32.dll", "int", "CloseHandle", "ptr", DllStructGetData($PI, "hThread"))
			DllCall("kernel32.dll", "int", "CloseHandle", "ptr", DllStructGetData($PI, "hProcess"))
		EndIf
	EndIf
ElseIf $cmdline[0] = 3 Then
	$Privs = "SeDebugPrivilege,SeAssignPrimaryTokenPrivilege,SeIncreaseQuotaPrivilege"
	$PrivsArray = StringSplit($Privs,",")
	For $i = 1 To $PrivsArray[0]
		_SetPrivilege($PrivsArray[$i])
	Next
	Global $sProcessAsUser = $cmdline[1]
	Global $TargetSessionId = $cmdline[2]
	Global $sCmdLine = $cmdline[3]
	$TargetSessionId = Dec($TargetSessionId)
	Local $aProcs = ProcessList($sProcessAsUser), $processPID = -1, $ret
	For $i = 1 To $aProcs[0][0]
		$ret = DllCall("kernel32.dll", "int", "ProcessIdToSessionId", "dword", $aProcs[$i][1], "dword*", 0)
		If Not @error And $ret[0]  Then
			$processPID = $aProcs[$i][1]
			ExitLoop
		EndIf
	Next
	If $processPID = -1 Then Exit
	Local $hProc = _NtOpenProcess($processPID)
	If @error Then
		Exit
	Else
		$hProc = $hProc
	EndIf
	$hToken = DllCall($ghADVAPI32, "int", "OpenProcessToken", "ptr", $hProc, "dword", 0x000F01FF, "ptr*", 0)
	If @error Or Not $hToken[0] Then
		DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc)
		Exit
	EndIf
	$hToken = $hToken[3]
	Local $hDupToken = DllCall($ghADVAPI32, "int", "DuplicateTokenEx", "ptr", $hToken, "dword", 0x1F0FFF, "ptr", 0, "int", 1, "int", 1, "ptr*", 0)
	If @error Or Not $hDupToken[0] Then
		DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hToken)
		DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc)
		Exit
	EndIf
	$hDupToken = $hDupToken[6]
	$myStruct = DllStructCreate("byte[4]")
	DllStructSetData($myStruct,1,$TargetSessionId)
	_SetTokenInformation($hDupToken, 12, DllStructGetPtr($myStruct), DllStructGetSize($myStruct))
	If @error then Exit
	Local $pEnvBlock
	$pEnvBlock = _GetEnvironmentBlock($sProcessAsUser, $TargetSessionId)
	Local $dwCreationFlags = BitOR(0x00000020, 0x00000010)
	If $pEnvBlock Then $dwCreationFlags = BitOR($dwCreationFlags, 0x00000400)
	Local $SI = DllStructCreate($tagSTARTUPINFO1)
	DllStructSetData($SI, "cb", DllStructGetSize($SI))
	Local $PI = DllStructCreate($tagPROCESSINFO1)
	Local $sDesktop = "winsta0\default"
	Local $lpDesktop = DllStructCreate("wchar[" & StringLen($sDesktop) + 1 & "]")
	DllStructSetData($lpDesktop, 1, $sDesktop)
	DllStructSetData($SI, "lpDesktop", DllStructGetPtr($lpDesktop))
	$ret = DllCall($ghADVAPI32, "int", "CreateProcessAsUserW", "ptr", $hDupToken, "ptr", 0, "wstr", $sCmdLine, "ptr", 0, "ptr", 0, "int", 0, _
					"dword", $dwCreationFlags, "ptr", $pEnvBlock, "ptr", 0, "ptr", DllStructGetPtr($SI), "ptr", DllStructGetPtr($PI))
	If Not @error And $ret[0] Then
		DllCall("kernel32.dll", "int", "CloseHandle", "ptr", DllStructGetData($PI, "hThread"))
		DllCall("kernel32.dll", "int", "CloseHandle", "ptr", DllStructGetData($PI, "hProcess"))
	EndIf
Else
	Exit
EndIf

If $pEnvBlock Then DllCall("userenv.dll", "int", "DestroyEnvironmentBlock", "ptr", $pEnvBlock)
DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hDupToken)
DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hToken)
DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc)

Func _GetEnvironmentBlock($sProcess, $dwSession)
	Local $aProcs = ProcessList($sProcess), $processPID = -1, $ret = 0
	For $i = 1 To $aProcs[0][0]
		$ret = DllCall("kernel32.dll", "int", "ProcessIdToSessionId", "dword", $aProcs[$i][1], "dword*", 0)
		If Not @error And $ret[0] And ($ret[2] = $dwSession) Then
			$processPID = $aProcs[$i][1]
			ExitLoop
		EndIf
	Next
	If $processPID = -1 Then Return 0
	Local $hProc = DllCall("kernel32.dll", "ptr", "OpenProcess", "dword", 0x02000000, "int", 0, "dword", $processPID)
	If @error Or Not $hProc[0] Then Return 0
	$hProc = $hProc[0]
	$hToken = DllCall($ghADVAPI32, "int", "OpenProcessToken", "ptr", $hProc, "dword", BitOR(0x2, 0x8), "ptr*", 0)
	If @error Or Not $hToken[0] Then
		DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc)
		Return 0
	EndIf
	$hToken = $hToken[3]
	Local $pEnvBlock = DllCall("userenv.dll", "int", "CreateEnvironmentBlock", "ptr*", 0, "ptr", $hToken, "int", 1)
	If Not @error And $pEnvBlock[0] Then $ret = $pEnvBlock[1]
	DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hToken)
	DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hProc)
	Return $ret
EndFunc

Func _SetPrivilege($Privilege)
	Local $tagTOKENPRIVILEGES = "dword PrivilegeCount;byte LUIDandATTRIB[" & 12 & "]"
	Local $curProc = DllCall("kernel32.dll", "ptr", "GetCurrentProcess")
	Local $call = DllCall("advapi32.dll", "int", "OpenProcessToken", "ptr", $curProc[0], "dword", 0x000F01FF, "ptr*", "")
	If Not $call[0] Then Return False
	Local $hToken = $call[3]
	$call = DllCall("advapi32.dll", "int", "LookupPrivilegeValue", "str", "", "str", $Privilege, "int64*", "")
	Local $iLuid = $call[3]
	Local $TP = DllStructCreate($tagTOKENPRIVILEGES)
	Local $TPout = DllStructCreate($tagTOKENPRIVILEGES)
	Local $LUID = DllStructCreate("int64 Luid;dword Attributes", DllStructGetPtr($TP, "LUIDandATTRIB"))
	DllStructSetData($TP, "PrivilegeCount", 1)
	DllStructSetData($LUID, "Luid", $iLuid)
	DllStructSetData($LUID, "Attributes", 0x2)
	$call = DllCall("advapi32.dll", "int", "AdjustTokenPrivileges", "ptr", $hToken, "int", 0, "ptr", DllStructGetPtr($TP), "dword", DllStructGetSize($TPout), "ptr", DllStructGetPtr($TPout), "dword*", 0)
	Local $aResult = DllCall("kernel32.dll", "dword", "GetLastError")
	$lasterror = SetError(@error, @extended, $aResult[0])
	If $lasterror <> 0 Then
		If $lasterror = 1300 Then
			$RightsAdder = _LsaAddAccountRights(@UserName, $Privilege)
			If @error then Return SetError(1,0,0)
		EndIf
	EndIf
	DllCall("kernel32.dll", "int", "CloseHandle", "ptr", $hToken)
	Return ($call[0] <> 0)
EndFunc

Func _SetTokenInformation($hToken, $iTokenInformation, $vTokenInformation, $iTokenInformationLength)
	Local $aCall = DllCall("advapi32.dll", "bool", "SetTokenInformation", "handle", $hToken, "int", $iTokenInformation, "struct*", $vTokenInformation, "dword", $iTokenInformationLength)
	If @error Or Not $aCall[0] Then
		Return SetError(1, @extended, False)
	EndIf
	Return True
EndFunc

Func _NtOpenProcess($PID)
	Local $sOA = DllStructCreate($tagOBJECTATTRIBUTES)
	DllStructSetData($sOA, "Length", DllStructGetSize($sOA))
	DllStructSetData($sOA, "RootDirectory", 0)
	DllStructSetData($sOA, "ObjectName", 0)
	DllStructSetData($sOA, "Attributes", 0x00000040)
	DllStructSetData($sOA, "SecurityDescriptor", 0)
	DllStructSetData($sOA, "SecurityQualityOfService", 0)
	Local $ClientID = DllStructCreate("dword_ptr UniqueProcessId;dword_ptr UniqueThreadId")
	DllStructSetData($ClientID, "UniqueProcessId", $PID)
	DllStructSetData($ClientID, "UniqueThreadId", 0)
	Local $aCall = DllCall("ntdll.dll", "hwnd", "NtOpenProcess", "handle*", 0, "dword", 0x001F0FFF, "struct*", $sOA, "struct*", $ClientID)
	If Not NT_SUCCESS($aCall[0]) Then
		Return SetError(1, 0, $aCall[0])
	Else
		Return $aCall[1]
	EndIf
EndFunc

Func _LsaAddAccountRights($sName, $sRight)
	Local $hPolicy, $tSid, $pSid, $iLength, $iSysError
	Local $tUnicode, $pUnicode, $iResult, $tRight, $pRight
	$tSid = _LookupAccountName($sName)
	$pSid = DllStructGetPtr($tSid)
	If Not _IsValidSid($pSid) Then Return SetError(@error, 0, 0)
	$hPolicy = _LsaOpenPolicy(0x811)
	$iLength = StringLen($sRight) * 2
	$tRight = DllStructCreate("wchar[" & $iLength & "]")
	$pRight = DllStructGetPtr($tRight)
	DllStructSetData($tRight, 1, $sRight)
	$tUnicode = DllStructCreate("ushort Length;ushort MemSize;ptr wBuffer")
	$pUnicode = DllStructGetPtr($tUnicode)
	DllStructSetData($tUnicode, "Length", $iLength)
	DllStructSetData($tUnicode, "MemSize", $iLength + 2)
	DllStructSetData($tUnicode, "wBuffer", $pRight)
	$iResult = DllCall("advapi32.dll", "dword", "LsaAddAccountRights", _
					"hWnd", $hPolicy, "ptr", $pSid, _
					"ptr", $pUnicode, "ulong", 1)
	$tSid = 0
	_LsaClose($hPolicy)
	$iSysError = _LsaNtStatusToWinError($iResult[0])
	Return SetError($iSysError, 0, $iSysError = 0)
EndFunc

Func _LsaOpenPolicy($iAccess)
	Local $hPolicy, $tLsaAttr, $pLsaAttr
	$tLsaAttr = DllStructCreate("ulong;hWnd;ptr;ulong;ptr[2]")
	$pLsaAttr = DllStructGetPtr($tLsaAttr)
	$hPolicy = DllCall("advapi32.dll", "ulong", "LsaOpenPolicy", _
					"ptr", 0, "ptr", $pLsaAttr, "int", $iAccess, "hWnd*", 0)
	Return SetError(_LsaNtStatusToWinError($hPolicy[0]), 0, $hPolicy[4])
EndFunc

Func _LsaClose($hPolicy)
		Local $iResult
		$iResult = DllCall("advapi32.dll", "ulong", "LsaClose", "hWnd", $hPolicy)
		Return SetError(_LsaNtStatusToWinError($iResult[0]), 0, $iResult[0] = 0)
EndFunc

Func _LookupAccountName($sName, $sSystem = "")
	Local $iResult, $tSid, $pSid, $tDomain, $pDomain
	$iResult = DllCall("advapi32.dll", "int", "LookupAccountName", _
					"str", $sSystem, "str", $sName, _
					"ptr", 0, "int*", 0, "ptr", 0, "int*", 0, "int*", 0)
	If $iResult[4] = 0 Then Return SetError(1337, 0, 0)
	$tSid = DllStructCreate("ubyte[" & $iResult[4] & "]")
	$tDomain = DllStructCreate("ubyte[" & $iResult[6] & "]")
	$pSid = DllStructGetPtr($tSid)
	$pDomain = DllStructGetPtr($tDomain)
	$iResult = DllCall("advapi32.dll", "int", "LookupAccountName", _
						"str", $sSystem ,"str", $sName, _
						"ptr", $pSid, "int*", $iResult[4], _
						"ptr", $pDomain, "int*", $iResult[6], "int*", 0)
	Return SetError(Not $iResult[0], $iResult[7], $tSid)
EndFunc

Func _IsValidSid($pSid)
	Local $iResult
	$iResult = DllCall("advapi32.dll", "int", "IsValidSid", "ptr", $pSid)
	If $iResult[0] Then Return SetError(0, 0, True)
	Return SetError(1337, 0, 0)
EndFunc

Func _LsaNtStatusToWinError($iNtStatus)
	Local $iSysError
	$iSysError = DllCall("Advapi32.dll", "ulong", "LsaNtStatusToWinError", "dword", $iNtStatus)
	Return $iSysError[0]
EndFunc

Func NT_SUCCESS($status)
	If 0 <= $status And $status <= 0x7FFFFFFF Then
		Return True
	Else
		Return False
	EndIf
EndFunc

Zdroje informací