|
1. Un pò di teoria
Per Privilegio si intende il diritto di un account, sia esso un utente
od un gruppo, di effettuare varie operazioni a livello di sistema sul computer
locale, come ad esempio spegnere il sistema, caricare device drivers o cambiare
la data e ora di sistema. Di seguito sono elencate le differenze principali tra
Privilegi e Diritti di accesso
1) I Privilegi controllano l' accesso a risorse di sistema e processi
relativi al sistema mentre i Diritti di Accesso controllano l' accesso ai
cosidetti
Securable Objects (oggetti ai quali possa essere assegnato un Security
Descriptor: ad es. File, Cartelle, Chiavi di registro, etc..)
2) Un amministratore di sistema può assegnare Privilegi ad un utente od
un gruppo, mentre il sistema consente o nega l' accesso ad un Securable
Object in relazione ai Diritti di accesso specificati nella ACL
dell' oggetto
Windows XP/Windows 2000/Windows NT dispongono di un database che raccoglie i
Privilegi dei vari utenti e gruppi: si può avere un elenco da
Pannello di controllo -> Strumenti di amministrazione ->
Criteri di protezione locali -> impostazioni protezione -> Criteri locali ->
Assegnazione diritti utente.
Quando un utente esegue un log-in, il sistema produce un token di
accesso che contiene una lista dei Privilegi dell' utente, inclusi
naturalmente quelli garantiti ai gruppi a cui l' utente appartiene . E' da
notare che i Privilegi si applicano solo al computer locale e quindi un
account di dominio può avere Privilegi differenti su computer differenti
Quando un utente tenta di eseguire una operazione che richiede determinati
Privilegi, il sistema controlla il Token di accesso dell' utente per
verificare che l' utente in questione disponga dei Privilegi necessari e,
in caso affermativo, che tali Privilegi siano abilitati. In caso
contrario l' utente non può eseguire l' operazione.
Per determinare i Privilegi inclusi in un Token di Accesso si usa
la funzione GetTokenIformation che indica anche quali Privilegi
sono abilitati e quali no. La maggiorparte sono disabilitati di default.
Per far riferimento ai vari Privilegi nel contesto delle Api di Windows,
è previsto un insieme di stringhe ognuna delle quali identifica uno dei
Privilegi. Per un elenco delle stringhe andare all' url
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthz/security/authorization_constants.asp
In breve sono le seguenti stringhe
SE_CREATE_TOKEN_NAME = 'SeCreateTokenPrivilege';
SE_ASSIGNPRIMARYTOKEN_NAME = 'SeAssignPrimaryTokenPrivilege';
SE_LOCK_MEMORY_NAME = 'SeLockMemoryPrivilege';
SE_INCREASE_QUOTA_NAME = 'SeIncreaseQuotaPrivilege';
SE_UNSOLICITED_INPUT_NAME = 'SeUnsolicitedInputPrivilege';
SE_MACHINE_ACCOUNT_NAME = 'SeMachineAccountPrivilege';
SE_TCB_NAME = 'SeTcbPrivilege';
SE_SECURITY_NAME = 'SeSecurityPrivilege';
SE_TAKE_OWNERSHIP_NAME = 'SeTakeOwnershipPrivilege';
SE_LOAD_DRIVER_NAME = 'SeLoadDriverPrivilege';
SE_SYSTEM_PROFILE_NAME = 'SeSystemProfilePrivilege';
SE_SYSTEMTIME_NAME = 'SeSystemtimePrivilege';
SE_PROF_SINGLE_PROCESS_NAME = 'SeProfileSingleProcessPrivilege';
SE_INC_BASE_PRIORITY_NAME = 'SeIncreaseBasePriorityPrivilege';
SE_CREATE_PAGEFILE_NAME = 'SeCreatePagefilePrivilege';
SE_CREATE_PERMANENT_NAME = 'SeCreatePermanentPrivilege';
SE_BACKUP_NAME = 'SeBackupPrivilege';
SE_RESTORE_NAME = 'SeRestorePrivilege';
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
SE_DEBUG_NAME = 'SeDebugPrivilege';
SE_AUDIT_NAME = 'SeAuditPrivilege';
SE_SYSTEM_ENVIRONMENT_NAME = 'SeSystemEnvironmentPrivilege';
SE_CHANGE_NOTIFY_NAME = 'SeChangeNotifyPrivilege';
SE_REMOTE_SHUTDOWN_NAME = 'SeRemoteShutdownPrivilege';
SE_UNDOCK_NAME = 'SeUndockPrivilege';
SE_SYNC_AGENT_NAME = 'SeSyncAgentPrivilege';
SE_ENABLE_DELEGATION_NAME = 'SeEnableDelegationPrivilege';
SE_MANAGE_VOLUME_NAME = 'SeManageVolumePrivilege';
SE_IMPERSONATE_NAME = 'SeImpersonatePrivilege';
SE_CREATE_GLOBAL_NAME = 'SeCreateGlobalPrivilege';
Le funzioni che ottengono e modificano l' elenco dei Privilegi in un Token di accesso, usano il LUID (Locally Unique identifier) per identificare ognuno dei Privilegi (invece della stringa). Il LUID relativo ad un Privilegio differisce da un computer all' altro ma anche da un boot ad un altro sul medesimo computer unico nel contesto del computer. Per ottenere ogni volta il LUID corrispondente ad un determinato Privilegio si usa la funzione LookupPrivilegeValue. La funzione inversa (restituisce la stringa che da il nome al Privilegio, a partire dal LUID) è LookupPrivilegeName. Il sistema fornisce anche un insieme di stringhe descrittive per ogni Privilegio. Per ottenere la descrizione a partire dal nome del Privilegio si usa la funzione LookupPrivilegeDisplayName. Si può usare la funzione PrivilegeCheck per verificare se un Token di accesso detiene un insieme specifico di Privilegi. 2. Un pò di pratica Di seguito alcune procedure 2.1 Elenco privilegi dell' utente corrente (restituisce l' elenco dei privilegi, con relativo stato di abilitazione, dell' utenza che esegue il programma in cui viene chiamata la procedura stessa)
procedure ElencoPrivilegiutenteCorrente();
var
TokenHandle: THandle;
TokenInformation: PTOKENPRIVILEGES;
ReturnLength: DWORD;
i: Integer;
TokenInformationLength: DWORD;
Nome: PChar;
Descrizione: PChar;
DimensioneNome, DimensioneDescrizione: DWORD;
LangId: DWORD;
Abilitazione: string;
begin
TokenInformationLength := 600;
GetMem(TokenInformation, TokenInformationLength);
OpenProcessToken(
GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
TokenHandle);
GetTokenInformation(
TokenHandle,
TokenPrivileges,
TokenInformation,
TokenInformationLength,
ReturnLength);
GetMem(Nome, 255);
GetMem(Descrizione, 255);
for i := 0 to TokenInformation.PrivilegeCount - 1 do
begin
DimensioneDescrizione := 255;
DimensioneNome := 255;
LookupPrivilegeName(
nil,
TokenInformation.Privileges[i].Luid,
Nome,
DimensioneNome);
LookupPrivilegeDisplayName(
nil,
Nome,
Descrizione,
DimensioneDescrizione,
LangId);
if (TokenInformation.Privileges[i].Attributes = SE_PRIVILEGE_ENABLED) then
Abilitazione := 'Abilitato'
else
Abilitazione := 'Disabilitato';
ShowMessage(Nome + '---' + Descrizione + '---' + Abilitazione);
end;
FreeMem(TokenInformation);
FreeMem(Nome);
FreeMem(Descrizione);
end;
Si noti come la maggiorparte dei privilegi di cui dispone una utenza siano disabilitati. 2.2 Abilita o disabilita un privilegio assegnato all' utenza corrente (ossia l' utenza che esegue il programma in cui viene chiamata la procedura stessa)
procedure ModificaPrivilegio(szPrivilege: pChar; fEnable: Boolean);
var
NewState: TTokenPrivileges;
luid: TLargeInteger;
hToken: THandle;
ReturnLength: DWord;
begin
OpenProcessToken(
GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
hToken);
LookupPrivilegeValue(nil, szPrivilege, luid);
NewState.PrivilegeCount := 1;
NewState.Privileges[0].Luid := luid;
if fEnable then
NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
else
NewState.Privileges[0].Attributes := 0;
AdjustTokenPrivileges(
hToken,
FALSE,
NewState,
sizeof(NewState),
nil,
ReturnLength);
CloseHandle(hToken);
end;
|