"Christoph Schneegans" <Chri...@Schneegans.de> schrieb:
> Stefan Kanthak schrieb:
>
>> Aktivieren von "SeRestorePrivilege" und Verwendung von "REG_OPTION_BACKUP_RESTORE"
>> in den Funktionen zum Oeffnen von Registry-Schluesseln genuegt.
>
> Okay. Ich habe es mit dem von
> <
https://gallery.technet.microsoft.com/Adjusting-Token-Privileges-9b6724fc>
> bereitgestellten Cmdlet
>
> Set-LHSTokenPrivilege -Privilege SeRestorePrivilege
AUTSCH!
Das ist kap0tt:
0. es schliesst es den von ihm selbst geoeffneten "process token" NICHT;
1. es wertet den von LookupPrivilegeValue() gelieferten Rueckgabewert
NICHT aus; dadurch kann AdjustTokenPrivilege() mit einer beliebigen
LUID aufgerufen werden.
Zudem ist es UNGESCHICKT, zuerst den "process token" zu oeffnen und erst
danach LookupPrivilegeValue() aufzurufen: falls letzteres einen Fehler
liefert, dann war das Oeffnen umsonst.
JFTR: den ueber 20 Jahre alten, von Microsoft auf MSDN unter
<
https://msdn.microsoft.com/en-us/library/aa446619.aspx>
veroeffentlichten UNGESCHICKTEN Code-Schnipsel haben dummerweise
viel zu viele Ahnunglose wie dieser Lee Holmes abgeschrieben:
<
https://www.leeholmes.com/blog/2010/09/24/adjusting-token-privileges-in-powershell/>
Ausserdem gibt's SeUnsolicitedInputPrivilege schon LAAAANGE nicht
mehr; dafuer fehlt SeDelegateSessionUserImpersonatePrivilege...
In ANSI C sieht das wie folgt RICHTIG aus (fuer den EIGENEN Prozess;
GetLastError() enthaelt im Fehlerfall den Win32-Fehlercode):
BOOL EnableSinglePrivilege(LPCWSTR PrivilegeName)
{
BOOL b = FALSE;
TOKEN_PRIVILEGES tp = {1L, {0L, 0L, SE_PRIVILEGE_ENABLED}};
HANDLE token = INVALID_HANDLE_VALUE;
if (LookupPrivilegeValue((LPCWSTR) NULL,
PrivilegeName,
&tp.Privileges[0].Luid))
{
if (OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES,
&token))
{
b = AdjustTokenPrivileges(token,
FALSE,
&tp, sizeof(TOKEN_PRIVILEGES),
(TOKEN_PRIVILEGES *) NULL, (LPDWORD) NULL))
CloseHandle(token);
}
}
return b;
}
JFTR: nicht nur Prozesse haben einen Token, sondern auch deren Threads
koennen einen Token haben; in solchen Faellen muss der "thread
token" verwendet werden!
In ANSI C sieht das wie folgt aus (fuer den EIGENEN Thread bzw. Prozess):
BOOL EnableSinglePrivilege(LPCWSTR PrivilegeName)
{
BOOL b = FALSE;
TOKEN_PRIVILEGES tp = {1L, {0L, 0L, SE_PRIVILEGE_ENABLED}};
HANDLE token = INVALID_HANDLE_VALUE;
if (LookupPrivilegeValue((LPCWSTR) NULL,
PrivilegeName,
&tp.Privileges[0].Luid))
{
if (OpenThreadToken(GetCurrentThread(),
TOKEN_ADJUST_PRIVILEGES,
&token)
|| OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES,
&token))
{
b = AdjustTokenPrivileges(token,
FALSE,
&tp, sizeof(TOKEN_PRIVILEGES),
(TOKEN_PRIVILEGES *) NULL, (LPDWORD) NULL))
CloseHandle(token);
}
}
return b;
}
JFTR: GetCurrentProcess() liefert DOKUMENTIERT immer die Konstante -1,
und GetCurrentThread() liefert ebenso dokumentiert immer die
Konstante -2.
RegCreateKeyEx() ist hier UNGESCHICKT, da dieses ggf. nicht existierende
Schluessel erzeugt. Verwende RegOpenKeyEx()!
> und tatsächlich den Rückgabewert ERROR_SUCCESS zu erhalten. (Ohne
> SeRestorePrivilege erhalte ich erwartungsgemäß ERROR_ACCESS_DENIED.)
> Schreibenden Zugriff traue ich mich damit aber bestimmt nicht...
SeRestorePrivilege brauchst Du aber NUR fuer SCHREIBENDE Zugriffe;
Loeschen von Werten und Schluessel sind schreibende Zugriffe!
Falls Du nur Lesen moechtest, dann aktivierst Du das Privileg
SeBackupPrivilege.
Stefan
PS: LookupPrivilegeValue() liefert seit Anbeginn der eNTen folgende
KONSTANTEN Werte im niederwertigen Teil der LUID (der hoeherwertige
Teil ist 0):
enum _PRIVILEGES
{
SE_MIN_WELL_KNOWN_PRIVILEGE = 2,
SE_CREATE_TOKEN_PRIVILEGE,
SE_ASSIGNPRIMARYTOKEN_PRIVILEGE,
SE_LOCK_MEMORY_PRIVILEGE,
SE_INCREASE_QUOTA_PRIVILEGE,
SE_MACHINE_ACCOUNT_PRIVILEGE,
SE_TCB_PRIVILEGE,
SE_SECURITY_PRIVILEGE,
SE_TAKE_OWNERSHIP_PRIVILEGE,
SE_LOAD_DRIVER_PRIVILEGE,
SE_SYSTEM_PROFILE_PRIVILEGE,
SE_SYSTEMTIME_PRIVILEGE,
SE_PROF_SINGLE_PROCESS_PRIVILEGE,
SE_INC_BASE_PRIORITY_PRIVILEGE,
SE_CREATE_PAGEFILE_PRIVILEGE,
SE_CREATE_PERMANENT_PRIVILEGE,
SE_BACKUP_PRIVILEGE,
SE_RESTORE_PRIVILEGE,
SE_SHUTDOWN_PRIVILEGE,
SE_DEBUG_PRIVILEGE,
SE_AUDIT_PRIVILEGE,
SE_SYSTEM_ENVIRONMENT_PRIVILEGE,
SE_CHANGE_NOTIFY_PRIVILEGE,
SE_REMOTE_SHUTDOWN_PRIVILEGE,
SE_UNDOCK_PRIVILEGE,
SE_SYNC_AGENT_PRIVILEGE,
SE_ENABLE_DELEGATION_PRIVILEGE,
SE_MANAGE_VOLUME_PRIVILEGE,
SE_IMPERSONATE_PRIVILEGE,
SE_CREATE_GLOBAL_PRIVILEGE,
SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE,
SE_RELABEL_PRIVILEGE,
SE_INCREASE_WORKING_SET_PRIVILEGE,
SE_TIME_ZONE_PRIVILEGE,
SE_CREATE_SYMBOLIC_LINK_PRIVILEGE,
SE_DELEGATE_SESSION_USER_IMPERSONATE_PRIVILEGE,
SE_MAX_WELL_KNOWN_PRIVILEGE
} PRIVILEGES;
Die wohlbekannte, von NTDLL.dll exportierte Funktion
__declspec(dllimport)
NTSTATUS NTAPI RtlAdjustPrivilege(DWORD Privilege,
BOOLEAN Enable,
BOOLEAN CurrentThread,
BOOLEAN *Enabled);
kannst Du direkt mit diesen Konstanten fuettern.