Câu trả lời Process Explorer hoạt động một lần, nhưng bạn có thể muốn áp dụng điều này ngay cả sau khi máy tính được khởi động lại. Để làm điều đó, bạn có thể sử dụng 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)
}
}
Nó dựa trên câu trả lời Stack Overflow này . Về cơ bản, bạn cung cấp cho nó danh sách các quy trình cần bảo vệ và người dùng để bảo vệ chống lại, và nó xử lý các ACL của quy trình một cách thích hợp. Lưu nó dưới dạng .ps1
tệp (nơi nào đó người dùng có thể đọc nhưng không thể ghi), sau đó đặt tệp bó chứa nội dung như thế này trong Khởi động của người dùng:
powershell \path\to\script.ps1 ('snippingtool', 'mspaint') 'Guest' -executionpolicy bypass
Điều đó bảo vệ snippingtool.exe
và mspaint.exe
(Công cụ Snipping và Sơn) khỏi bị giết bởi Khách.
Lưu ý rằng điều này phải chạy sau khi các quá trình bắt đầu. Bạn có thể phải thêm một sleep 10
hoặc nhiều hơn sau Param
khối tập lệnh PowerShell. Khi nó kết thúc, cố gắng giết các tiến trình đó bằng Trình quản lý tác vụ sẽ gây ra điều này:
Cũng lưu ý rằng nó sẽ không có gì hữu ích nếu tài khoản bạn kiểm tra nó là quản trị viên, hoặc chính xác hơn là có SeDebugPrivilege
.
Nhấp vào X trên cửa sổ của họ hoặc sử dụng chức năng đóng riêng của ứng dụng sẽ vẫn khiến các quy trình thoát ra, vì tất cả các quy trình đều tự do quyết định ngừng chạy. Bạn có thể cần ẩn khu vực thông báo, như được mô tả trong câu trả lời khác. Ngoài ra, vì các quy trình quan trọng này chạy với tư cách là người dùng khách, người dùng đó là chủ sở hữu của các đối tượng quy trình và sẽ có thể điều chỉnh lại ACL hoặc có thể sử dụng các PROCESS_VM_WRITE
khả năng để viết nguệch ngoạc trên bộ nhớ của quy trình và khắc phục chúng. Những vấn đề này có thể được giải quyết bằng cách thêm một ACE trống cho OWNER RIGHTS
và bằng cách thay đổi 'PROCESS_TERMINATE, PROCESS_SUSPEND_RESUME, WRITE_DAC'
thành 'PROCESS_ALL_ACCESS'
, tương ứng.
Từ chối quyền truy cập vào Trình quản lý tác vụ thông qua GPO sẽ ngăn người dùng sử dụng Trình quản lý tác vụ (rõ ràng) và là giải pháp đơn giản nhất, nhưng không có gì ngăn họ chạy chương trình của riêng họ (hoặc taskkill
) không tuân thủ Chính sách nhóm. Sẽ là tốt nhất nếu các quy trình bạn đang cố bảo vệ chạy với tư cách là một người dùng khác với quy trình bạn đang cố gắng chống lại.
Tất nhiên, nếu khách của bạn sẵn sàng đi đến tất cả những rắc rối đó để phá vỡ những "sự bảo vệ" khác nhau này, bạn có thể gặp nhiều vấn đề xã hội hơn là vấn đề kỹ thuật.