E1M1 Posted August 30, 2012 Share Posted August 30, 2012 (edited) Hello My intention is to restart my service in logged in user's session but have it run as SYSTEM. Logic tells me that if environment's token is from user and other token that is passed to CreateProcessAsUser() is from system then it should run it in user's environment but it doesnt. I have even Local $sDesktop = "winsta0\default" but still no result. If I get hToken from user then it runs in user session but it's username isn't SYSTEM anymore. expandcollapse popup;~ CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo)) #include <winapi.au3> #include <array.au3> #include <security.au3> GUICreate("...") GUISetState(@SW_SHOW) $force_gui = true ;~ $force_gui = False ;~ $list = ProcessList("ra2.exe") ;~ If $list[0][0] > 1 Then ;~ Sleep(1000) ;~ MsgBox(0,"test","abc",10) ;~ Exit ;~ EndIf $NULL = 0 $FALE = 0 $TRUE = 1 $WTS_CURRENT_SERVER_HANDLE = $NULL $WTSActive = 0 $WTSShadow = 1 $WTSConnectQuery = 2 $CREATE_UNICODE_ENVIRONMENT = 0x00000400 $DETACHED_PROCESS = 0x00000008 $MAX_PATH = 260 $PROCESS_ALL_ACCESS = 0x001F0FFF ;~ $TOKEN_ALL_ACCESS = 0xf01ff $ERROR_SUCCESS = 0 Global Const $tagWTS_SESSION_INFO = 'dword SessionId;ptr WinStationName;uint State' ;testing ;~ $s = "" ;~ GetModuleFileName(0,$s,260) ;~ MsgBox(0,0,$s) #cs typedef struct _STARTUPINFO { DWORD cb; 1 LPTSTR lpReserved; 2 LPTSTR lpDesktop; 3 LPTSTR lpTitle; 4 DWORD dwX; 5 DWORD dwY; 6 DWORD dwXSize; 7 DWORD dwYSize; 8 DWORD dwXCountChars; 9 DWORD dwYCountChars; 10 DWORD dwFillAttribute; 11 DWORD dwFlags; 12 WORD wShowWindow; 13 WORD cbReserved2; 14 LPBYTE lpReserved2; 15 HANDLE hStdInput; 16 HANDLE hStdOutput; 17 HANDLE hStdError; 18 } STARTUPINFO, *LPSTARTUPINFO; typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION, *LPPROCESS_INFORMATION; #ce LaunchProcessWin() Func LaunchProcessWin() $bReturn = False $hToken = 0 $env = 0 $StartUPInfo = DllstructCreate($tagSTARTUPINFO) $ProcessInfo = DllStructCreate("HANDLE;HANDLE;DWORD;DWORD") MemSet(DllStructGetPtr($StartUPInfo),Chr(0),DllStructGetSize($StartUPInfo)) MemSet(DllStructGetPtr($ProcessInfo),Chr(0),DllStructGetSize($ProcessInfo)) DllStructSetData($StartUPInfo, 13, @SW_SHOW) Local $sDesktop = "winsta0\default" Local $lpDesktop = DllStructCreate("char[" & StringLen($sDesktop) + 1 & "]") DllStructSetData($lpDesktop, 1, $sDesktop) DllStructSetData($StartUPInfo, 3, DllStructGetPtr($lpDesktop)) DllStructSetData($StartUPInfo, 1, DllStructGetSize($StartUPInfo)) $app_path = "" SetTBCPrivileges() $id = WTSGetActiveConsoleSessionId() _MsgBox(0, DllStructGetData($StartUPInfo, 3), $id ) $hTokenuser = WTSQueryUserToken($id) $hToken = _Security__OpenProcessToken(-1, $TOKEN_ALL_ACCESS) _MsgBox(0, 2, "abc") $hToken = _Security__DuplicateTokenEx($hToken, $TOKEN_ALL_ACCESS, $SECURITYIMPERSONATION, $TOKENPRIMARY) CreateEnvironmentBlock($env, $hTokenuser, 0) _MsgBox(0,$hToken, $env) GetModuleFileName(0,$app_path,$MAX_PATH) _MsgBox(0, 3, DllStructGetPtr($StartUPInfo)) $file = DllStructCreate("char[260]") $lpProcessAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES) $lpThreadAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES) DLLStructSetData($lpThreadAttributes,"Descriptor",0) $ta_size=dllstructgetsize($lpThreadAttributes) DLLStructSetData($lpThreadAttributes,"Length",$ta_size) DLLStructSetData($lpProcessAttributes,"Descriptor",0) $pa_size=dllstructgetsize($lpProcessAttributes) DLLStructSetData($lpProcessAttributes,"Length",$pa_size) $ret = CreateProcessAsUser($hToken, "", $app_path, DllStructGetPtr($lpProcessAttributes), DllStructGetPtr($lpThreadAttributes), 0, $CREATE_UNICODE_ENVIRONMENT + $DETACHED_PROCESS, $env,"", $StartUPInfo, $ProcessInfo) _MsgBox(0, "4 "&$ret[0], DllStructGetData($ProcessInfo,3)) ;CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo)// C++ EndFunc ;==>LaunchProcessWin Func MemSet($pDest, $nChar, $nCount) DllCall("msvcrt.dll", "ptr:cdecl", "memset", "ptr", $pDest, "int", $nChar, "int", $nCount) If @error Then Return SetError(1,0,False) Return True EndFunc Func CreateEnvironmentBlock(ByRef $lpEnvironment, $hToken, $bInherit) $struct = DllStructCreate("ptr") $Ret = DllCall('Userenv.dll', 'bool', 'CreateEnvironmentBlock', _ 'ptr', DllStructGetPtr($struct), _ 'HANDLE', $hToken, _ 'bool', $bInherit) $lpEnvironment = DllStructGetData($struct, 1) Return $Ret[0] EndFunc ;==>CreateEnvironmentBlock Func WTSQueryUserToken($SessionId) $struct = DllStructCreate("HANDLE") $Ret = DllCall('wtsapi32.dll', 'bool', 'WTSQueryUserToken', _ 'ULONG', $SessionId, _ 'ptr*', DllStructGetPtr($struct)) If $Ret[0] <> 0 Then Return $Ret[2] Else _MsgBox(16, "Error (you must run me as system service)", _WinAPI_GetLastErrorMessage(), 10) Exit EndIf EndFunc ;==>WTSQueryUserToken Func WTSGetActiveConsoleSessionId() $Ret = DllCall('Kernel32.dll', 'dword', 'WTSGetActiveConsoleSessionId') Return $Ret[0] EndFunc ;==>WTSGetActiveConsoleSessionId Func GetModuleFileName($hModule,byref $lpFilename, $nSize) $Ret = DllCall('Kernel32.dll', 'int', 'GetModuleFileNameW', _ 'handle', $hModule, _ 'wstr', 0, _ 'int', $nSize) $lpFilename = $Ret[2] Return $Ret[0] EndFunc Func CreateProcessAsUser($hToken, $lpApplicationName, $lpCommandline, $lpProcessAttributes, $lpThreadAttributes, $bInheritHandles, $dwCreationFlags, $lpEnvironment, $lpCurrentDirectory, byref $lpStartupInfo,byref $lpProcessInformation) $ret = DllCall("advapi32.dll", "bool", "CreateProcessAsUser", _ ; W is better "handle", $hToken, _ "ptr", 0, _ "str", $lpCommandline, _ ; wstr for CreateProcessAsUserW "int", $lpProcessAttributes, _ "int", $lpThreadAttributes, _ "bool", $bInheritHandles, _ "dword", $dwCreationFlags, _ "ptr", $lpEnvironment, _ "ptr", 0, _ "struct*", $lpStartupInfo, _ "struct*", $lpProcessInformation) If $ret[0] = 0 Then _MsgBox(16, "proc e "&@error&" "&$hToken, _WinAPI_GetLastErrorMessage()) ;~ $lpProcessInformation = $ret[11] Return $ret EndFunc ;==>CreateProcessAsUser Func SetTBCPrivileges() $dwPID = @AutoItPID $hToken = 0 $hProcess = 0 $tpDebug = DllStructCreate($tagTOKEN_PRIVILEGES) $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS,False,$dwPID) If not $hProcess Then return False If not _WinAPI_OpenProcessToken($hProcess,$TOKEN_ALL_ACCESS,$hToken) Then return False $LUID = _Security__LookupPrivilegeValue("", $SE_DEBUG_NAME) if $LUID == 0 Then Return False DllStructSetData($tpDebug,"Count",1) DllStructSetData($tpDebug,"LUID",$LUID,1) DllStructSetData($tpDebug,"Attributes",$SE_PRIVILEGE_ENABLED,1) if _Security__AdjustTokenPrivileges($hToken,False,DllStructGetPtr($tpDebug),DllStructGetSize($tpDebug),$NULL,$NULL) = False Then Return false if _WinAPI_GetLastError() <> $ERROR_SUCCESS Then Return False _WinAPI_CloseHandle($hToken); _WinAPI_CloseHandle($hProcess); Return true EndFunc Func _WinAPI_OpenProcessToken($pHandle, $iAccess, byref $hToken) Local $aResult = DllCall("advapi32.dll", "int", "OpenProcessToken", "hwnd", $pHandle, "int", $iAccess, "int*", 0) If @error Or $aResult[0] = 0 Then Return SetError(1, 0, 0) $hToken = $aResult[3] Return $aResult[0] EndFunc ;Debugging Func _MsgBox($a, $b, $c, $d = 0) If @UserName <> "SYSTEM" Or $force_gui Then MsgBox($a, $b, $c, $d) Else FileWrite(@ScriptDir & "\mb.txt", '"' & $b & '"' & ", " & '"' & $c & '"' & @CRLF) EndIf EndFunc ;==>_MsgBox Func __ArrayDisplay($a, $b = "array") If @UserName <> "SYSTEM" Or $force_gui Then _ArrayDisplay($a, $b) Else $dat = $b & @CRLF For $i = 0 To UBound($a) - 1 $dat &= @TAB & $a[$i] & @CRLF Next FileWrite(@ScriptDir & "\arr.txt", $dat) EndIf EndFunc ;==>__ArrayDisplay edit: had to set token information. Here's working code for everyone who are interested expandcollapse popup;~ CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo)) #include <winapi.au3> #include <array.au3> #include <security.au3> #include <SecurityConstants.au3> GUICreate("...") GUISetState(@SW_SHOW) $force_gui = true ;~ $force_gui = False ;~ $list = ProcessList("ra2.exe") ;~ If $list[0][0] > 1 Then ;~ Sleep(1000) ;~ MsgBox(0,"test","abc",10) ;~ Exit ;~ EndIf $NULL = 0 $FALE = 0 $TRUE = 1 $WTS_CURRENT_SERVER_HANDLE = $NULL $WTSActive = 0 $WTSShadow = 1 $WTSConnectQuery = 2 $CREATE_UNICODE_ENVIRONMENT = 0x00000400 $DETACHED_PROCESS = 0x00000008 $MAX_PATH = 260 $PROCESS_ALL_ACCESS = 0x001F0FFF ;~ $TOKEN_ALL_ACCESS = 0xf01ff $ERROR_SUCCESS = 0 Global Const $tagWTS_SESSION_INFO = 'dword SessionId;ptr WinStationName;uint State' wlist() func wlist() $wl = WinList() $swin = "---------"&@AutoItPID For $i = 1 to $wl[0][0] $swin &= $wl[$i][0]&@CRLF Next FileWrite(@ScriptDir&"\winl.txt",$swin) EndFunc ;testing ;~ $s = "" ;~ GetModuleFileName(0,$s,260) ;~ MsgBox(0,0,$s) #cs typedef struct _STARTUPINFO { DWORD cb; 1 LPTSTR lpReserved; 2 LPTSTR lpDesktop; 3 LPTSTR lpTitle; 4 DWORD dwX; 5 DWORD dwY; 6 DWORD dwXSize; 7 DWORD dwYSize; 8 DWORD dwXCountChars; 9 DWORD dwYCountChars; 10 DWORD dwFillAttribute; 11 DWORD dwFlags; 12 WORD wShowWindow; 13 WORD cbReserved2; 14 LPBYTE lpReserved2; 15 HANDLE hStdInput; 16 HANDLE hStdOutput; 17 HANDLE hStdError; 18 } STARTUPINFO, *LPSTARTUPINFO; typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION, *LPPROCESS_INFORMATION; #ce LaunchProcessWin() Func LaunchProcessWin() $bReturn = False $hToken = 0 $env = 0 $StartUPInfo = DllstructCreate($tagSTARTUPINFO) $ProcessInfo = DllStructCreate("HANDLE;HANDLE;DWORD;DWORD") MemSet(DllStructGetPtr($StartUPInfo),Chr(0),DllStructGetSize($StartUPInfo)) MemSet(DllStructGetPtr($ProcessInfo),Chr(0),DllStructGetSize($ProcessInfo)) DllStructSetData($StartUPInfo, 13, @SW_SHOW) Local $sDesktop = "winsta0\default" Local $lpDesktop = DllStructCreate("wchar[" & StringLen($sDesktop) + 1 & "]") DllStructSetData($lpDesktop, 1, $sDesktop) DllStructSetData($StartUPInfo, 3, DllStructGetPtr($lpDesktop)) DllStructSetData($StartUPInfo, 1, DllStructGetSize($StartUPInfo)) $app_path = "" SetTBCPrivileges() $id = WTSGetActiveConsoleSessionId() _MsgBox(0, DllStructGetData($StartUPInfo, 3), $id ) $hTokenuser = WTSQueryUserToken($id) $hToken = _Security__OpenProcessToken(-1, $TOKEN_ALL_ACCESS) _MsgBox(0, 2, "abc") $hToken = _Security__DuplicateTokenEx($hToken, $TOKEN_ALL_ACCESS, $SECURITYIMPERSONATION, $TOKENPRIMARY) $sid = DllStructCreate("DWORD") DllStructSetData($sid,1,$id) _Security__SetTokenInformation($hToken, $TOKENSESSIONID, DllStructGetPtr($sid), DllStructGetSize($sid)) CreateEnvironmentBlock($env, $hToken, 0) _MsgBox(0,$hToken, $env) GetModuleFileName(0,$app_path,$MAX_PATH) _MsgBox(0, 3, DllStructGetPtr($StartUPInfo)) $file = DllStructCreate("char[260]") $lpProcessAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES) $lpThreadAttributes=dllstructcreate($tagSECURITY_ATTRIBUTES) DLLStructSetData($lpThreadAttributes,"Descriptor",0) $ta_size=dllstructgetsize($lpThreadAttributes) DLLStructSetData($lpThreadAttributes,"Length",$ta_size) DLLStructSetData($lpProcessAttributes,"Descriptor",0) $pa_size=dllstructgetsize($lpProcessAttributes) DLLStructSetData($lpProcessAttributes,"Length",$pa_size) Run("taskmgr") $ret = CreateProcessAsUser($hToken, "", $app_path, DllStructGetPtr($lpProcessAttributes), DllStructGetPtr($lpThreadAttributes), 0, $CREATE_UNICODE_ENVIRONMENT + $DETACHED_PROCESS, $env,"", $StartUPInfo, $ProcessInfo) _MsgBox(0, "4 "&$ret[0], DllStructGetData($ProcessInfo,3)) ;CreateProcessAsUser(hToken,NULL,app_path,NULL,NULL,FALSE,CREATE_UNICODE_ENVIRONMENT |DETACHED_PROCESS,lpEnvironment,NULL,&StartUPInfo,&ProcessInfo)// C++ EndFunc ;==>LaunchProcessWin Func MemSet($pDest, $nChar, $nCount) DllCall("msvcrt.dll", "ptr:cdecl", "memset", "ptr", $pDest, "int", $nChar, "int", $nCount) If @error Then Return SetError(1,0,False) Return True EndFunc Func CreateEnvironmentBlock(ByRef $lpEnvironment, $hToken, $bInherit) $struct = DllStructCreate("ptr") $Ret = DllCall('Userenv.dll', 'bool', 'CreateEnvironmentBlock', _ 'ptr', DllStructGetPtr($struct), _ 'HANDLE', $hToken, _ 'bool', $bInherit) $lpEnvironment = DllStructGetData($struct, 1) Return $Ret[0] EndFunc ;==>CreateEnvironmentBlock Func WTSQueryUserToken($SessionId) $struct = DllStructCreate("HANDLE") $Ret = DllCall('wtsapi32.dll', 'bool', 'WTSQueryUserToken', _ 'ULONG', $SessionId, _ 'ptr*', DllStructGetPtr($struct)) If $Ret[0] <> 0 Then Return $Ret[2] Else _MsgBox(16, "Error (you must run me as system service)", _WinAPI_GetLastErrorMessage(), 10) Exit EndIf EndFunc ;==>WTSQueryUserToken Func WTSGetActiveConsoleSessionId() $Ret = DllCall('Kernel32.dll', 'dword', 'WTSGetActiveConsoleSessionId') Return $Ret[0] EndFunc ;==>WTSGetActiveConsoleSessionId Func GetModuleFileName($hModule,byref $lpFilename, $nSize) $Ret = DllCall('Kernel32.dll', 'int', 'GetModuleFileNameW', _ 'handle', $hModule, _ 'wstr', 0, _ 'int', $nSize) $lpFilename = $Ret[2] Return $Ret[0] EndFunc Func CreateProcessAsUser($hToken, $lpApplicationName, $lpCommandline, $lpProcessAttributes, $lpThreadAttributes, $bInheritHandles, $dwCreationFlags, $lpEnvironment, $lpCurrentDirectory, byref $lpStartupInfo,byref $lpProcessInformation) $ret = DllCall("advapi32.dll", "bool", "CreateProcessAsUserW", _ ; W is better "handle", $hToken, _ "ptr", 0, _ "wstr", $lpCommandline, _ ; wstr for CreateProcessAsUserW "int", $lpProcessAttributes, _ "int", $lpThreadAttributes, _ "bool", $bInheritHandles, _ "dword", $dwCreationFlags, _ "ptr", $lpEnvironment, _ "ptr", 0, _ "struct*", $lpStartupInfo, _ "struct*", $lpProcessInformation) If $ret[0] = 0 Then _MsgBox(16, "proc e "&@error&" "&$hToken, _WinAPI_GetLastErrorMessage()) ;~ $lpProcessInformation = $ret[11] Return $ret EndFunc ;==>CreateProcessAsUser Func SetTBCPrivileges() $dwPID = @AutoItPID $hToken = 0 $hProcess = 0 $tpDebug = DllStructCreate($tagTOKEN_PRIVILEGES) $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS,False,$dwPID) If not $hProcess Then return False If not _WinAPI_OpenProcessToken($hProcess,$TOKEN_ALL_ACCESS,$hToken) Then return False $LUID = _Security__LookupPrivilegeValue("", $SE_DEBUG_NAME) if $LUID == 0 Then Return False DllStructSetData($tpDebug,"Count",1) DllStructSetData($tpDebug,"LUID",$LUID,1) DllStructSetData($tpDebug,"Attributes",$SE_PRIVILEGE_ENABLED,1) if _Security__AdjustTokenPrivileges($hToken,False,DllStructGetPtr($tpDebug),DllStructGetSize($tpDebug),$NULL,$NULL) = False Then Return false if _WinAPI_GetLastError() <> $ERROR_SUCCESS Then Return False _WinAPI_CloseHandle($hToken); _WinAPI_CloseHandle($hProcess); Return true EndFunc Func _WinAPI_OpenProcessToken($pHandle, $iAccess, byref $hToken) Local $aResult = DllCall("advapi32.dll", "int", "OpenProcessToken", "hwnd", $pHandle, "int", $iAccess, "int*", 0) If @error Or $aResult[0] = 0 Then Return SetError(1, 0, 0) $hToken = $aResult[3] Return $aResult[0] EndFunc ;Debugging Func _MsgBox($a, $b, $c, $d = 0) If @UserName <> "SYSTEM" Or $force_gui Then MsgBox($a, $b, $c, $d) Else FileWrite(@ScriptDir & "\mb.txt", '"' & $b & '"' & ", " & '"' & $c & '"' & @CRLF) EndIf EndFunc ;==>_MsgBox Func __ArrayDisplay($a, $b = "array") If @UserName <> "SYSTEM" Or $force_gui Then _ArrayDisplay($a, $b) Else $dat = $b & @CRLF For $i = 0 To UBound($a) - 1 $dat &= @TAB & $a[$i] & @CRLF Next FileWrite(@ScriptDir & "\arr.txt", $dat) EndIf EndFunc ;==>__ArrayDisplay Edited August 30, 2012 by E1M1 edited Link to comment Share on other sites More sharing options...
woldofoldo Posted July 4, 2013 Share Posted July 4, 2013 hi E1M1, i have a problem if i use your second script. I write in the line of app patch: $app_path = "C:\Windows\System32\cmd.exe" and run this script as service with "srvany.exe". The good message is, that the cmd.exe open with the SYSTEM-Account in the User Session ID (1), but the bad message is, that this script open the cmd.exe not one time. It open the programm infinitely until the memory is full . can you help me by my problem? sorry for my bad english Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now