La réponse Process Explorer fonctionne une fois, mais vous souhaitez probablement que cela s'applique même après le redémarrage de l'ordinateur. Pour ce faire, vous pouvez utiliser 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)
}
}
C'est basé sur cette réponse de débordement de pile . Fondamentalement, vous lui fournissez la liste des processus à protéger et les utilisateurs contre lesquels il doit se protéger, et il manipule les listes de contrôle d'accès des processus de manière appropriée. Enregistrez-le en tant que .ps1
fichier (quelque part que l'utilisateur peut lire mais pas écrire), puis mettez un fichier de commandes contenant quelque chose comme ceci au démarrage de l'utilisateur:
powershell \path\to\script.ps1 ('snippingtool', 'mspaint') 'Guest' -executionpolicy bypass
Qui protège snippingtool.exe
etmspaint.exe
(l'outil de découpage et la peinture) d'être tués par Guest.
Notez que cela doit être exécuté après le démarrage de ces processus. Il se peut que vous deviez en ajouter sleep 10
environ après le Param
bloc du script PowerShell. Une fois l'opération terminée, essayer de supprimer ces processus avec le Gestionnaire des tâches aura les conséquences suivantes:
Notez également que cela ne servira à rien si le compte avec lequel vous le testez est un administrateur, ou plus précisément SeDebugPrivilege
.
En cliquant sur le X dans leur fenêtre ou en utilisant la fonctionnalité de fermeture des applications, les processus resteront fermés, car tous les processus sont libres de décider de s’arrêter. Vous devrez peut-être masquer la zone de notification, comme décrit dans une autre réponse. De plus, étant donné que ces processus importants sont exécutés en tant qu'utilisateur invité, cet utilisateur est le propriétaire des objets de processus et pourra quand même réajuster la liste de contrôle d'accès PROCESS_VM_WRITE
. Ceux-ci pourraient être résolus en ajoutant un ACE vierge pour OWNER RIGHTS
et en changeant 'PROCESS_TERMINATE, PROCESS_SUSPEND_RESUME, WRITE_DAC'
pour'PROCESS_ALL_ACCESS'
, respectivement.
Refuser l’accès au gestionnaire de tâches via un objet de stratégie de groupe empêcherait l’utilisateur d’utiliser le gestionnaire de tâches (évidemment) et constitue la solution la plus simple, mais rien ne les empêche d’exécuter leur propre programme (ou taskkill
) qui ne respecte pas la stratégie de groupe. Il serait préférable que les processus que vous essayez de défendre soient exécutés sous un utilisateur différent de celui contre lequel vous essayez de vous défendre.
Bien sûr, si votre invité est prêt à tout mettre en œuvre pour contourner ces différentes "protections", vous aurez peut-être davantage un problème social que technique.