La respuesta de Process Explorer funciona una vez, pero probablemente desee que esto se aplique incluso después de reiniciar la computadora. Para hacer eso, puede usar 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)
}
}
Se basa en esta respuesta de desbordamiento de pila . Básicamente, usted le proporciona la lista de procesos para proteger y el usuario para proteger, y manipula las ACL de los procesos de manera adecuada. Guárdelo como un .ps1archivo (en algún lugar donde el usuario pueda leer pero no escribir), luego coloque un archivo por lotes que contenga algo como esto en el Inicio del usuario:
powershell \path\to\script.ps1 ('snippingtool', 'mspaint') 'Guest' -executionpolicy bypass
Eso protege snippingtool.exey mspaint.exe(la herramienta de corte y pintura) de ser asesinado por el invitado.
Tenga en cuenta que esto tiene que ejecutarse después de que comiencen esos procesos. Es posible que deba agregar más sleep 10o menos después del Parambloque del script de PowerShell. Una vez que termine, tratar de matar esos procesos con el Administrador de tareas causará esto:

También tenga en cuenta que no hará nada útil si la cuenta con la que lo prueba es un administrador, o más precisamente lo tiene SeDebugPrivilege.
Hacer clic en la X en sus ventanas o usar la funcionalidad de cierre de las aplicaciones seguirá haciendo que los procesos salgan, ya que todos los procesos son libres de decidir dejar de ejecutarse. Es posible que deba ocultar el área de notificación, como se describe en otra respuesta. Además, dado que estos procesos importantes se ejecutan como el usuario invitado, ese usuario es el propietario de los objetos del proceso y podrá ajustar la ACL de todos modos, o podría usar las PROCESS_VM_WRITEhabilidades para garabatear sobre la memoria de los procesos y bloquearlos. Esos podrían resolverse agregando un ACE en blanco para OWNER RIGHTSy cambiando 'PROCESS_TERMINATE, PROCESS_SUSPEND_RESUME, WRITE_DAC'a 'PROCESS_ALL_ACCESS', respectivamente.
Negar el acceso al Administrador de tareas a través de GPO impediría que el usuario use el Administrador de tareas (obviamente) y es la solución más sencilla, pero no hay nada que les impida ejecutar su propio programa (o taskkill) que no obedezca a la Política de grupo. Sería mejor si los procesos que intenta defender se ejecutan como un usuario diferente del que está tratando de defender.
Por supuesto, si su invitado está dispuesto a tomarse la molestia de eludir estas diversas "protecciones", es posible que tenga más problemas sociales que técnicos.