La risposta di Process Explorer funziona una volta, ma probabilmente vuoi applicarla anche dopo il riavvio del computer. Per fare ciò, puoi usare PowerShell:
Param (
[string[]]$ProcessNames,
[string]$DenyUsername
)
$cscode = @"
using System;
using System.Security;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
public class ProcessSecurity : NativeObjectSecurity
{
public ProcessSecurity(SafeHandle processHandle)
: base(false, ResourceType.KernelObject, processHandle, AccessControlSections.Access)
{
}
public void AddAccessRule(ProcessAccessRule rule)
{
base.AddAccessRule(rule);
}
// this is not a full impl- it only supports writing DACL changes
public void SaveChanges(SafeHandle processHandle)
{
Persist(processHandle, AccessControlSections.Access);
}
public override Type AccessRightType
{
get { return typeof(ProcessAccessRights); }
}
public override AccessRule AccessRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
{
return new ProcessAccessRule(identityReference, (ProcessAccessRights)accessMask, isInherited, inheritanceFlags, propagationFlags, type);
}
public override Type AccessRuleType
{
get { return typeof(ProcessAccessRule); }
}
public override AuditRule AuditRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)
{
throw new NotImplementedException();
}
public override Type AuditRuleType
{
get { throw new NotImplementedException(); }
}
}
public class ProcessAccessRule : AccessRule
{
public ProcessAccessRule(IdentityReference identityReference, ProcessAccessRights accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
: base(identityReference, (int)accessMask, isInherited, inheritanceFlags, propagationFlags, type)
{
}
public ProcessAccessRights ProcessAccessRights { get { return (ProcessAccessRights)AccessMask; } }
}
[Flags]
public enum ProcessAccessRights
{
STANDARD_RIGHTS_REQUIRED = (0x000F0000),
DELETE = (0x00010000), // Required to delete the object.
READ_CONTROL = (0x00020000), // Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right.
WRITE_DAC = (0x00040000), // Required to modify the DACL in the security descriptor for the object.
WRITE_OWNER = (0x00080000), // Required to change the owner in the security descriptor for the object.
PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, //All possible access rights for a process object.
PROCESS_CREATE_PROCESS = (0x0080), // Required to create a process.
PROCESS_CREATE_THREAD = (0x0002), // Required to create a thread.
PROCESS_DUP_HANDLE = (0x0040), // Required to duplicate a handle using DuplicateHandle.
PROCESS_QUERY_INFORMATION = (0x0400), // Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob).
PROCESS_QUERY_LIMITED_INFORMATION = (0x1000),
PROCESS_SET_INFORMATION = (0x0200), // Required to set certain information about a process, such as its priority class (see SetPriorityClass).
PROCESS_SET_QUOTA = (0x0100), // Required to set memory limits using SetProcessWorkingSetSize.
PROCESS_SUSPEND_RESUME = (0x0800), // Required to suspend or resume a process.
PROCESS_TERMINATE = (0x0001), // Required to terminate a process using TerminateProcess.
PROCESS_VM_OPERATION = (0x0008), // Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory).
PROCESS_VM_READ = (0x0010), // Required to read memory in a process using ReadProcessMemory.
PROCESS_VM_WRITE = (0x0020), // Required to write to memory in a process using WriteProcessMemory.
SYNCHRONIZE = (0x00100000), // Required to wait for the process to terminate using the wait functions.
}
"@
Add-Type -TypeDefinition $cscode
$ProcessNames | % {
Get-Process -ProcessName $_ | % {
$handle = $_.SafeHandle
$acl = New-Object ProcessSecurity $handle
$ident = New-Object System.Security.Principal.NTAccount $DenyUsername
$ace = New-Object ProcessAccessRule ($ident, 'PROCESS_TERMINATE, PROCESS_SUSPEND_RESUME, WRITE_DAC', $false, 'None', 'None', 'Deny')
$acl.AddAccessRule($ace)
$acl.SaveChanges($handle)
}
}
Si basa su questa risposta Stack Overflow . Fondamentalmente, gli fornisci l'elenco dei processi da proteggere e l'utente da proteggere, e confonde gli ACL dei processi in modo appropriato. Salvalo come .ps1file (da qualche parte l'utente può leggere ma non scrivere), quindi inserisci un file batch contenente qualcosa di simile all'avvio dell'utente:
powershell \path\to\script.ps1 ('snippingtool', 'mspaint') 'Guest' -executionpolicy bypass
Ciò protegge snippingtool.exee mspaint.exe(lo strumento di cattura e la pittura) dall'essere ucciso dall'ospite.
Si noti che questo deve essere eseguito dopo l' avvio di tali processi. Potrebbe essere necessario aggiungere circa una volta sleep 10dopo il Paramblocco dello script PowerShell. Una volta terminato, provare a uccidere quei processi con Task Manager causerà questo:

Nota inoltre che non farà nulla di utile se l'account con cui lo collaudi è un amministratore, o più precisamente lo ha SeDebugPrivilege.
Facendo clic sulla X nelle finestre o utilizzando la funzionalità di chiusura delle applicazioni, i processi continueranno comunque a uscire, poiché tutti i processi sono liberi di decidere di interrompere l'esecuzione. Potrebbe essere necessario nascondere l'area di notifica, come descritto in un'altra risposta. Inoltre, poiché questi importanti processi vengono eseguiti come utenti guest, l'utente è il proprietario degli oggetti di processo e sarà in grado di regolare l'ACL in ogni caso, oppure potrebbe utilizzare le PROCESS_VM_WRITEabilità per scarabocchiare sulla memoria dei processi e bloccarli. Quelli potrebbero essere risolti aggiungendo un ACE vuoto per OWNER RIGHTSe cambiando 'PROCESS_TERMINATE, PROCESS_SUSPEND_RESUME, WRITE_DAC'a 'PROCESS_ALL_ACCESS', rispettivamente.
Negare l'accesso a Task Manager tramite GPO impedirebbe all'utente di utilizzare Task Manager (ovviamente) ed è la soluzione più semplice, ma non c'è nulla che impedisce loro di eseguire il proprio programma (o taskkill) che non obbedisce a Criteri di gruppo. Sarebbe meglio se i processi che stai cercando di difendere funzionassero come un utente diverso da quello contro cui stai cercando di difenderti.
Naturalmente, se il tuo ospite è disposto a fare tutto il possibile per aggirare queste varie "protezioni", potresti avere più di un problema sociale che tecnico.