Icon Ressource

[Windows] ElevateMe - Ausführung mit erhöhten Rechten ohne UAC Prompt 1.2

ElevateMe - Execution using elevated privileges without UAC prompt
For an English description refer to file "ReadMe.txt" included in the download.


ElevateMe bietet eine Möglichkeit, Prozesse mit den höchsten verfügbaren Privilegien des aktuellen Benutzers ohne UAC-Bestätigung auszuführen.
Dadurch können Automatisierungsskripts unbeaufsichtigt ausgeführt werden.

Das Skript richtet sich an Endnutzer auf ihren privaten Computern, wo sie der lokalen Administratorgruppe angehören.
Benutzung auf eigenes Risiko.



Installation:
Führe "Install_ElevateMe.ps1" aus. (im Download enthalten)
  • Der Benutzer wird einmalig zur UAC-Bestätigung aufgefordert.
  • Datei "%LOCALAPPDATA%\ElevateMe.vbs" wird erstellt (wobei %LOCALAPPDATA% üblicherweise "C:\Users\<Dein Benutzername>\AppData\Local" ist).
  • Der Geplante Task "ElevateMe" wird erstellt.



Benutzung
Code:
%LOCALAPPDATA%\ElevateMe.vbs  envVarName  [wndStyle]  [sync]

  envVarName  Name einer Umgebungsvariable, die die mit höchsten verfügbaren
               Privilegien auszuführende Kommandozeile beinhaltet.
              ACHTUNG: Übergib NICHT die Kommandozeile selbst. Weise sie erst
               einer Umgebungsvariable zu und übergib nur den Name der Variable
               ohne sie zu ihrem Wert zu expandieren.

  wndStyle    (optional) Ganzzahliger Wert der das Erscheinungsbild des Fensters
               für den Prozess mit erhöhten Rechten spezifiziert.
              Im Zweifel, wähle 1, 3 oder 7. Standardwert ist 1.
              Mögliche Werte sind:
               0 Das Fenster ist unsichtbar und ein anderes Fenster ist aktiv.
               1 Aktiviere und blende das Fenster ein.
               2 Aktiviere und minimiere.
               3 Aktiviere und maximiere.
               4 Wiederherstellen. Das aktive Fenster bleibt aktiv.
               5 Aktiviere und stelle wieder her.
               6 Minimiere and aktiviere das nächste top-level Fenster in der Z
                  Reihenfolge.
               7 Minimiere. Das aktive Fenster bleibt aktiv.
               8 Blende das Fenster in seinem derzeitigen Zustand ein. Das
                  aktive Fenster bleibt aktiv.
               9 Aktiviere und stelle wieder her. Nutze diesen Wert um ein
                  minimiertes Fester wiederherzustellen.
              10 Setze das Erscheinungsbild des Fensters basierend auf dem
                  Zustand des Programms das die Anwendung startet.

  sync        (optional) Ganzzahliger Wert, der spezifiziert, ob der Prozess mit
               erhöhten Rechten mit der Ausführung des aufrufenden Prozesses
               synchronisiert wird. Wert 0 steht für "falsch", jeder andere Wert
               steht für "wahr". Standardmäßig ist der Prozess mit erhöhten
               Rechten synchronisiert ("wahr"). Das bedeutet, der aufrufende
               Prozess wartet auf die Beendigung des Prozess mit erhöhten
               Rechten, bevor er mit der Ausführung fortfährt.

"ElevateMe.vbs" stellt das Arbeitsverzeichnis des aufrufenden Prozesses für den
 Prozess mit erhöhten Rechten wieder her. Argumente können Teil der ausgeführten
 Kommandozeile sein, getrennt durch Leerzeichen.

Rückgabewert:
- Wenn ein Fehler im VBScript Code auftritt, wird die VBScript Fehlernummer
  zurückgegeben (z.B. 13 für einen falschen Typ des zweiten oder dritten
  Arguments, oder 450 wenn kein Argument übergeben wurde).
- Ansonsten, wenn die Run Methode fehlschlägt, gibt das Script einen HRESULT
  Code zurück (wie -2147024894 für Datei Nicht Gefunden).
- Ansonsten, wenn 0 als sync Parameter übergeben wurde, gibt das Script 0
  zurück.
- Ansonsten gibt das Script den Exit Code des Prozesses mit erhöhten Rechten an
  den aufrufenden Prozess zurück.



FAQ:

Wie kann das überhaupt funktionieren?
Ein geplanter Task kann so konfiguriert werden, dass er mit den höchsten verfügbaren Privilegien eines Benutzers läuft. Ist der Task einmal erstellt, führt seine Ausführung nicht mehr zu einer Bestätigung über den UAC Prompt. Um diesen geplanten Task wiederverwenden zu können, ist ein Broker Script nötig, das erhöhte Rechte erwirbt und die Schnittstelle zwischen dem Prozess mit niedrigen und dem mit erhöhten Rechten realisiert.

Warum ist die Schnittstelle ein VBScript?
Ja, ich weiß das ist old-school. Aber WScript.exe läuft ohne Fenster. Somit wirst du nie aufblitzende Konsolefenster sehen, die durch die Schnittstelle hervorgerufen werden.

Warum wird die Kommandozeile per Umgebungsvariable übergeben?
Auf den ersten Blick erscheint das eher umständlich. Wenn du allerdings darüber nachdenkst, wie schwierig es werden kann Anführungszeichen korrekt über die Grenzen unterschiedlicher Shells beizubehalten, könntest du eine Idee davon bekommen warum die Definition einer Umgebungsvariable viel einfacher wäre. Einmal definiert, musst du dir keine Sorgen über Einschränkungen der Parser mehr machen.

Warum erstellt das VBScript temporäre Dateien?
Synchronisation und Interprozesskommunikation sind immer etwas schwierig. Die Nutzung von Dateien ist verhältnismäßig einfach. Ein Write-Lock kann dazu verwendet werden Race Conditions zu vermeiden und Daten können in einer Datei zwischen unterschiedlichen Prozessen übermittelt werden.


Beispiele


Example 1a:
Batch Code um einen CMD Prompt mit erhöhten Rechten zu öffnen.

Batch:
set "cmdLn=cmd /k" &%LOCALAPPDATA%\ElevateMe.vbs cmdLn 1 0



Example 1b:
PowerShell Code um einen PowerShell Prompt mit erhöhten Rechten zu öffnen.

Code:
$Env:cmdLn="powershell"; start "$Env:LOCALAPPDATA\ElevateMe.vbs" "cmdLn",1,0 -Wait



Example 2a:
Der Batch Code unten hat eine zusätzlich erste Zeile, die prüft, ob der Prozess erhöhte Rechte hat. Falls er mit niedrigen Rechten läuft, wird die eigene Kommandozeile der Variablen cmdLn zugewiesen und an ElevateMe.vbs weitergegeben, um die Batchdatei erneut mit den höchsten verfügbaren Privilegien auszuführen.
Ziehe eine oder mehrere Dateien auf die Batchdatei um zu zeigen, dass auch Argumente an den Prozess mit erhöhten Rechten weitergereicht werden.
Du kannst diese erste Zeile in jedem Batch Code wiederverwenden, der erhöhte Rechte erfordert.

Batch:
@>nul 2>&1 %__APPDIR__%net.exe session||(setlocal EnableDelayedExpansion&set "cmdLn=!CMDCMDLINE!"&%LOCALAPPDATA%\ElevateMe.vbs cmdLn 1 0&exit /b)
@echo off
title ElevateMe Test
echo current directory: "%cd%"
echo arguments (if any): %*
pause



Example 2b:
Der PowerShell Code unten hat zwei zusätzliche erste Zeilen, die dasselbe tun, wie die erste Batch Zeile in Example 2a.

Code:
If (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)){
  $Env:cmdLn=(gwmi Win32_Process -Filter ProcessId=$PID).CommandLine;start "$Env:LOCALAPPDATA\ElevateMe.vbs" "cmdLn",1,0 -Wait;Exit}
$Host.UI.RawUI.WindowTitle = "ElevateMe Test"
"current directory: `"$PWD`""
"arguments (if any):`n $($ARGS -Join `"`n `")"
pause



Example 2c:
VBScript Code mit demselben Verhalten von Example 2a und 2b.

Code:
Option Explicit
Dim oWSh, isElevated
Set oWSh = CreateObject("WScript.Shell")
On Error Resume Next : oWSh.RegRead "HKEY_USERS\S-1-5-19\Environment\TEMP" : isElevated = (Err.Number = 0) : On Error GoTo 0
If Not isElevated Then
  oWSh.Environment("PROCESS")("cmdLn") = GetOwnCmdLine : oWSh.Run oWSh.Environment("PROCESS")("LOCALAPPDATA") & "\ElevateMe.vbs cmdLn 1 0", 1, True
Else
  Dim out, arg
  out = "current directory: """ & oWSh.CurrentDirectory & """" & vbLf & "arguments (if any):"
  For Each arg In WScript.Arguments
    out = out & vbLf & "  " & arg
  Next
  oWSh.PopUp out, 0, "Elevated", vbSystemModal Or &h00040000& Or &h00200000&
End If

Function GetOwnCmdLine()
  Dim oWmi, colProcs, oProc, pid, guid
  guid = Left(CreateObject("Scriptlet.TypeLib").Guid, 38)
  oWSh.Run """winver.exe"" tag" & guid, 0, False
  Set oWmi = GetObject("winmgmts:\\.\root\cimv2")
  Set colProcs = oWmi.ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE '% tag" & guid & "'")
  For Each oProc In colProcs : pid = oProc.ParentProcessID : oProc.Terminate : Next
  Set colProcs = oWmi.ExecQuery("SELECT * FROM Win32_Process WHERE ProcessID=" & pid)
  For Each oProc In colProcs : GetOwnCmdLine = oProc.CommandLine : Next
End Function



Example 3a:
Dieser Batch Code ruft sich selbst erneut mit erhöhten Rechten auf und wartet auf die Beendigung dieses Prozesses. Er zeigt, wie man den Rückgabewert des Prozesses mit erhöhten Rechten bekommt.

Batch:
@echo off &>nul 2>&1 %__APPDIR__%net.exe session &&goto elevatedBranch

setlocal EnableDelayedExpansion
set "cmdLn=!CMDCMDLINE!"
%LOCALAPPDATA%\ElevateMe.vbs cmdLn 1 1
endlocal &set "ret=%errorlevel%"
echo Return value of the elevated process: %ret%
pause
exit /b

:elevatedBranch
echo Elevated process returning 5 to demonstrate the exit code behavior.
pause
exit /b 5



Example 3b:
PowerShell Code mit demselben Verhalten wie 3a.

Code:
If (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
  $Env:cmdLn = (gwmi Win32_Process -Filter ProcessId=$PID).CommandLine
  $proc = start "$Env:LOCALAPPDATA\ElevateMe.vbs" "cmdLn",1,1 -Wait -PassThru
  "Return value of the elevated process: $($proc.ExitCode)"
  pause
  Exit
}

# elevated branch
"Elevated process returning 5 to demonstrate the exit code behavior."
pause
Exit 5



Example 3c:
VBScript Code mit demselben Verhalten wie 3a und 3b.

Code:
Option Explicit
Dim oWSh, isElevated
Set oWSh = CreateObject("WScript.Shell")
On Error Resume Next : oWSh.RegRead "HKEY_USERS\S-1-5-19\Environment\TEMP" : isElevated = (Err.Number = 0) : On Error GoTo 0
If Not isElevated Then
  Dim ret
  oWSh.Environment("PROCESS")("cmdLn") = GetOwnCmdLine : ret = oWSh.Run(oWSh.Environment("PROCESS")("LOCALAPPDATA") & "\ElevateMe.vbs cmdLn 1 1", 1, True)
  oWSh.PopUp CStr(ret), 0, "Return value of the elevated process:", vbSystemModal Or &h00040000& Or &h00200000&
Else
  oWSh.PopUp "Elevated process returning 5 to demonstrate the exit code behavior.", 0, "Elevated", vbSystemModal Or &h00040000& Or &h00200000&
  WScript.Quit 5
End If

Function GetOwnCmdLine()
  Dim oWmi, colProcs, oProc, pid, guid
  guid = Left(CreateObject("Scriptlet.TypeLib").Guid, 38)
  oWSh.Run """winver.exe"" tag" & guid, 0, False
  Set oWmi = GetObject("winmgmts:\\.\root\cimv2")
  Set colProcs = oWmi.ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE '% tag" & guid & "'")
  For Each oProc In colProcs : pid = oProc.ParentProcessID : oProc.Terminate : Next
  Set colProcs = oWmi.ExecQuery("SELECT * FROM Win32_Process WHERE ProcessID=" & pid)
  For Each oProc In colProcs : GetOwnCmdLine = oProc.CommandLine : Next
End Function


  • Like
Reaktionen: JR Cologne
Autor
german
Downloads
738
Aufrufe
1.688
Erstellt am
Letzte Bearbeitung
Bewertung
0,00 Stern(e) 0 Bewertung(en)

Weitere Ressourcen von german

Letzte Aktualisierungen

  1. Vermeide möglichen Deadlock bei falschem Wert für wndStyle Parameter

    ut supra
  2. Unbedeutende Fixes

    - Plausibilitätscheck in HighestPrivBranch() - Typos
Zurück
Oben Unten