Відповідь Провідника процесу працює один раз, але ви, мабуть, хочете, щоб це застосувалося навіть після перезавантаження комп'ютера. Для цього ви можете використовувати 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)
}
}
Він заснований на цій відповіді на переповнення стека . В основному, ви надаєте йому список процесів для захисту та користувача, щоб захистити їх, і він належним чином знайде ACL-адреси процесів. Збережіть його як .ps1файл (десь користувач може читати, а не писати), а потім помістіть пакетний файл, що містить щось подібне, у запуск користувача:
powershell \path\to\script.ps1 ('snippingtool', 'mspaint') 'Guest' -executionpolicy bypass
Це захищає snippingtool.exeта mspaint.exe(інструмент для знімання та фарбу) від вбивства Гість.
Зауважте, що це потрібно запустити після запуску цих процесів. Можливо, вам доведеться додати sleep 10або близько того після Paramблоку сценарію PowerShell. Як тільки це закінчиться, спроба вбити ці процеси за допомогою диспетчера завдань призведе до цього:

Також зауважте, що це не дасть нічого корисного, якщо обліковий запис, на який ви його тестуєте, є адміністратором, а точніше SeDebugPrivilege.
Клацання X на їхніх вікнах або використання власних функціональних можливостей додатків все одно змусить процеси вийти, оскільки всі процеси вільні вирішити припинити роботу. Можливо, вам доведеться приховати область сповіщень, як описано в іншій відповіді. Крім того, оскільки ці важливі процеси виконуються як гостьовий користувач, той користувач є власником об'єктів процесу, і він зможе будь-коли відрегулювати ACL назад, або може використати PROCESS_VM_WRITEвміння прокручувати пам'ять процесів і збивати їх. Ті , може бути вирішена шляхом додавання порожній ACE для OWNER RIGHTSі зміни , 'PROCESS_TERMINATE, PROCESS_SUSPEND_RESUME, WRITE_DAC'щоб 'PROCESS_ALL_ACCESS', відповідно.
Заборона доступу до диспетчера завдань через GPO заважає користувачеві використовувати диспетчер завдань (очевидно) і є найбільш простим рішенням, але ніщо не заважає їм запускати власну програму (або taskkill), яка не підпорядковується груповій політиці. Було б найкраще, якщо б процес, який ви намагаєтесь захистити, вевся як інший користувач, ніж той, проти якого ви намагаєтесь захистити.
Звичайно, якщо ваш гість готовий піти на всі проблеми, щоб обійти ці різні "захисти", у вас може виникнути більше соціальна проблема, ніж технічна.