将进程提升至PPL权限 PPL介绍 Windows 的 PPL(Protected Process Light,受保护的进程 Light)是一种安全机制,用于保护关键系统进程和受信任的程序免受恶意软件的篡改和攻击。它通过限制对受保护进程的访问来实现这一点,即使是管理员用户也无法随意修改或终止这些进程。
为什么要提升权限 为什么要研究将进程提升至到PPL权限呢??
因为我准备尝试使用ETW-TI
,也就是Microsoft-Windows-Threat-Intelligence
这个provider,之前我一直不知道什么是ETW-TI😅,直到我发现原来是这个玩意。。。。
Microsoft-Windows-Threat-Intelligence
这个provider,它主要用于记录与安全和威胁情报相关的信息。
我们可以看看这玩意的关键字,几乎都是敏感的操作
据说杀软也是依赖这个的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 提供程序 GUID ------------------------------------------------------------------------------- Microsoft-Windows-Threat-Intelligence {F4E1897C-BB5D-5668 -F1D8-040F 4D8DD344} 值 关键字 描述 ------------------------------------------------------------------------------- 0x0000000000000001 KERNEL_THREATINT_KEYWORD_ALLOCVM_LOCAL0x0000000000000002 KERNEL_THREATINT_KEYWORD_ALLOCVM_LOCAL_KERNEL_CALLER0x0000000000000004 KERNEL_THREATINT_KEYWORD_ALLOCVM_REMOTE0x0000000000000008 KERNEL_THREATINT_KEYWORD_ALLOCVM_REMOTE_KERNEL_CALLER0x0000000000000010 KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL0x0000000000000020 KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL_KERNEL_CALLER0x0000000000000040 KERNEL_THREATINT_KEYWORD_PROTECTVM_REMOTE0x0000000000000080 KERNEL_THREATINT_KEYWORD_PROTECTVM_REMOTE_KERNEL_CALLER0x0000000000000100 KERNEL_THREATINT_KEYWORD_MAPVIEW_LOCAL0x0000000000000200 KERNEL_THREATINT_KEYWORD_MAPVIEW_LOCAL_KERNEL_CALLER0x0000000000000400 KERNEL_THREATINT_KEYWORD_MAPVIEW_REMOTE0x0000000000000800 KERNEL_THREATINT_KEYWORD_MAPVIEW_REMOTE_KERNEL_CALLER0x0000000000001000 KERNEL_THREATINT_KEYWORD_QUEUEUSERAPC_REMOTE0x0000000000002000 KERNEL_THREATINT_KEYWORD_QUEUEUSERAPC_REMOTE_KERNEL_CALLER0x0000000000004000 KERNEL_THREATINT_KEYWORD_SETTHREADCONTEXT_REMOTE0x0000000000008000 KERNEL_THREATINT_KEYWORD_SETTHREADCONTEXT_REMOTE_KERNEL_CALLER0x0000000000010000 KERNEL_THREATINT_KEYWORD_READVM_LOCAL0x0000000000020000 KERNEL_THREATINT_KEYWORD_READVM_REMOTE0x0000000000040000 KERNEL_THREATINT_KEYWORD_WRITEVM_LOCAL0x0000000000080000 KERNEL_THREATINT_KEYWORD_WRITEVM_REMOTE0x0000000000100000 KERNEL_THREATINT_KEYWORD_SUSPEND_THREAD0x0000000000200000 KERNEL_THREATINT_KEYWORD_RESUME_THREAD0x0000000000400000 KERNEL_THREATINT_KEYWORD_SUSPEND_PROCESS0x0000000000800000 KERNEL_THREATINT_KEYWORD_RESUME_PROCESS0x0000000001000000 KERNEL_THREATINT_KEYWORD_FREEZE_PROCESS0x0000000002000000 KERNEL_THREATINT_KEYWORD_THAW_PROCESS0x0000000004000000 KERNEL_THREATINT_KEYWORD_CONTEXT_PARSE0x0000000008000000 KERNEL_THREATINT_KEYWORD_EXECUTION_ADDRESS_VAD_PROBE0x0000000010000000 KERNEL_THREATINT_KEYWORD_EXECUTION_ADDRESS_MMF_NAME_PROBE0x0000000020000000 KERNEL_THREATINT_KEYWORD_READWRITEVM_NO_SIGNATURE_RESTRICTION0x0000000040000000 KERNEL_THREATINT_KEYWORD_DRIVER_EVENTS0x0000000080000000 KERNEL_THREATINT_KEYWORD_DEVICE_EVENTS0x0000000100000000 KERNEL_THREATINT_KEYWORD_READVM_REMOTE_FILL_VAD0x0000000200000000 KERNEL_THREATINT_KEYWORD_WRITEVM_REMOTE_FILL_VAD0x0000000400000000 KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL_FILL_VAD0x0000000800000000 KERNEL_THREATINT_KEYWORD_PROTECTVM_LOCAL_KERNEL_CALLER_FILL_VAD0x0000001000000000 KERNEL_THREATINT_KEYWORD_PROTECTVM_REMOTE_FILL_VAD0x0000002000000000 KERNEL_THREATINT_KEYWORD_PROTECTVM_REMOTE_KERNEL_CALLER_FILL_VAD0x0000004000000000 KERNEL_THREATINT_KEYWORD_PROCESS_IMPERSONATION_UP0x0000008000000000 KERNEL_THREATINT_KEYWORD_PROCESS_IMPERSONATION_REVERT0x0000010000000000 KERNEL_THREATINT_KEYWORD_PROCESS_SYSCALL_USAGE0x0000020000000000 KERNEL_THREATINT_KEYWORD_QUEUEUSERAPC_AT_DPC0x0000040000000000 KERNEL_THREATINT_KEYWORD_PROCESS_IMPERSONATION_DOWN0x8000000000000000 Microsoft-Windows-Threat-Intelligence/Analytic
可以看到,使用这个ETW TI其实是有门槛的
签名咱肯定是弄不到了,但是,看资料说提升至PPL也是可以的
原理弄懂了,开始启动
关于PPL,可以看我之前写的一篇文章
[PPL Attack | Cc12138’s blog](https://0xcc12138.github.io/PPL Attack/)
实现代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 #pragma once extern "C" { #include <ntifs.h> #include <ntddk.h> #define DebugPrint(...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,__VA_ARGS__) NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) ; VOID DriverUnloadRoutine (IN PDRIVER_OBJECT DriverObject) ; typedef struct _PS_PROTECTION { UCHAR Type : 3 ; UCHAR Audit : 1 ; UCHAR Signer : 4 ; } PS_PROTECTION, * PPS_PROTECTION; typedef struct _PROCESS_SIGNATURE { UCHAR SignatureLevel; UCHAR SectionSignatureLevel; PS_PROTECTION Protection; } PROCESS_SIGNATURE, * PPROCESS_SIGNATURE; struct ProcessSignature { ULONG Pid; UCHAR SignerType; UCHAR SignatureSigner; }; ULONG SignatureLevelOffset = 0 ; } #include "header.h" ULONG GetSignatureLevelOffset () { return 0x878 ; } NTSTATUS SetProcessSignature (ProcessSignature* ProcessSignature) { if (!SignatureLevelOffset) { SignatureLevelOffset = GetSignatureLevelOffset (); } if (SignatureLevelOffset) { PEPROCESS process; NTSTATUS status = STATUS_SUCCESS; status = PsLookupProcessByProcessId (ULongToHandle (ProcessSignature->Pid), &process); if (!NT_SUCCESS (status)) { return status; } UCHAR newSignatureLevel = (ProcessSignature->SignerType << 4 ) | ProcessSignature->SignatureSigner; PPROCESS_SIGNATURE processSignature = (PPROCESS_SIGNATURE)((UINT64)process + SignatureLevelOffset); processSignature->SignatureLevel = newSignatureLevel; processSignature->Protection.Type = ProcessSignature->SignerType; processSignature->Protection.Signer = ProcessSignature->SignatureSigner; ObDereferenceObject (process); return status; } return STATUS_INVALID_PARAMETER; } NTSTATUS SetProtectedProcess (ULONG Pid) { ProcessSignature ps; ps.Pid = Pid; ps.SignerType = 2 ; ps.SignatureSigner = 5 ; NTSTATUS status = SetProcessSignature (&ps); if (NT_SUCCESS (status)) { DebugPrint ("Successfully set the process to PPL.\n" ); return status; } else { DebugPrint ("Failed to set the process to PPL. Status: 0x%x\n" , status); return status; } } NTSTATUS IrpDispatchRoutine (PDEVICE_OBJECT DeviceObject, PIRP Irp) { DeviceObject; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest (Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } #define IOCTL_EXAMPLE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) NTSTATUS IrpDeviceControlRoutine (PDEVICE_OBJECT DeviceObject, PIRP Irp) { DeviceObject; PIO_STACK_LOCATION ioStackLocation = IoGetCurrentIrpStackLocation (Irp); ULONG inputBufferLength = ioStackLocation->Parameters.DeviceIoControl.InputBufferLength; PVOID inputBuffer = Irp->AssociatedIrp.SystemBuffer; NTSTATUS status = STATUS_SUCCESS; ULONG inputValue = 0 ; switch (ioStackLocation->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_EXAMPLE: if (inputBufferLength >= sizeof (ULONG)) { ANSI_STRING ansiString; RtlInitAnsiString (&ansiString, (PCSZ)inputBuffer); status = RtlCharToInteger (ansiString.Buffer, 10 , &inputValue); if (NT_SUCCESS (status)) { status = SetProtectedProcess (inputValue); } else { DbgPrint ("Error: Failed to convert string to ULONG. Status: 0x%08X\n" , status); status = STATUS_INVALID_PARAMETER; } } else { DbgPrint ("Error: Input buffer too small. Expected size: %d, actual size: %d\n" , sizeof (ULONG), inputBufferLength); status = STATUS_BUFFER_TOO_SMALL; } break ; default : DbgPrint ("Error: Invalid IOCTL control code: 0x%08X\n" , ioStackLocation->Parameters.DeviceIoControl.IoControlCode); status = STATUS_INVALID_DEVICE_REQUEST; break ; } Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0 ; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { UNREFERENCED_PARAMETER (RegistryPath); DebugPrint (("Create!" )); KdBreakPoint (); DriverObject->DriverUnload = DriverUnloadRoutine; NTSTATUS status; PDEVICE_OBJECT DeviceObject = NULL ; UNICODE_STRING DeviceName; RtlInitUnicodeString (&DeviceName, L"\\Device\\MyDevice" ); status = IoCreateDevice ( DriverObject, 0 , &DeviceName, FILE_DEVICE_UNKNOWN, 0 , FALSE, &DeviceObject ); DeviceObject->Characteristics |= DO_BUFFERED_IO; if (!NT_SUCCESS (status)) { DebugPrint ("Failed to create device: %X\n" , status); return status; } DebugPrint (("Device created successfully\n" )); UNICODE_STRING symbolicLink = RTL_CONSTANT_STRING (L"\\??\\MyDevice_Link" ); status = IoCreateSymbolicLink (&symbolicLink, &DeviceName); if (!NT_SUCCESS (status)) { DebugPrint ("Failed to create device: %X\n" , status); return status; } DebugPrint (("Device created successfully\n" )); for (ULONG i = 0 ; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = IrpDispatchRoutine; } DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceControlRoutine; return STATUS_SUCCESS; } VOID DriverUnloadRoutine (IN PDRIVER_OBJECT DriverObject) { if (DriverObject->DeviceObject != NULL ) { UNICODE_STRING symbolicLink = RTL_CONSTANT_STRING (L"\\??\\MyDevice_Link" ); IoDeleteSymbolicLink (&symbolicLink); IoDeleteDevice (DriverObject->DeviceObject); } DebugPrint ("Driver unloaded\n" ); }
应用层代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #include <windows.h> #include <iostream> using namespace std;#define IOCTL_EXAMPLE_DEVICE_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) int main () { system ("pause" ); HANDLE hDevice; DWORD bytesReturned; char inputData[10 ] = {0 }; char outputData[100 ]; cout << "请输入要提升至PPL的进程的PID(十进制)" << endl; cin >> inputData; hDevice = CreateFile ( L"\\\\.\\MyDevice_Link" , GENERIC_READ | GENERIC_WRITE, 0 , NULL , OPEN_EXISTING, 0 , NULL ); if (hDevice == INVALID_HANDLE_VALUE) { printf ("Failed to open device. Error: %d\n" , GetLastError ()); return 1 ; } BOOL result = DeviceIoControl ( hDevice, IOCTL_EXAMPLE_DEVICE_CONTROL, inputData, sizeof (inputData), NULL , NULL , &bytesReturned, NULL ); if (!result) { printf ("DeviceIoControl failed. Error: %d\n" , GetLastError ()); } else { printf ("Device response: %s\n" , outputData); } CloseHandle (hDevice); return 0 ; }
用法展示:
例如我们要将Notepad.exe提升到PPL权限
可以看到此时notepad.exe是没有任何保护的
然后安装好驱动,打开我们的三环程序
效果如下,可以看到已经是加了保护了,而且是禁止访问的