Block low integrity images¶
Dosyası Low mandatory integrity label taşıyan herhangi bir executable image'ı map etmeyi reddeden ve low-IL-yazılabilir konumlardan DLL-loading'i kesen bir Windows process-mitigation policy'si.
Mechanism¶
Note
Windows dosyalara bir mandatory integrity label (object'in SACL'sinde bir
integrity SID) iliştirir. Low integrity-level (IL) bir process tarafından
üretilen içerik — en önemlisi AppContainer / Protected-Mode browser cache'i
ve indirilenler — Low label ile yazılır. Image-load policy bir
invariant enforce eder: loader, backing file'ı Low-label'lı bir image'ı asla
medium/high-IL bir process'e map etmemelidir. Bu, Low-IL bir renderer'ın
world-readable bir directory'ye zararlı bir DLL drop edip sonra daha yüksek
privilege'lı bir process'i onu load etmeye kandırdığı (planting / search-order
hijack) klasik bir sandbox-escape kalıbını kapatır. Check, kernel image loader
tarafından section-creation zamanında yapıldığından, LoadLibrary, delay-load
ve manifest/SxS activation path'lerini tek tip olarak kapsar — userland string
sanitization'a güvenilmez.
Flag, PROCESS_MITIGATION_IMAGE_LOAD_POLICY içinde yaşar:
typedef struct _PROCESS_MITIGATION_IMAGE_LOAD_POLICY {
union {
DWORD Flags;
struct {
DWORD NoRemoteImages : 1;
DWORD NoLowMandatoryLabelImages : 1; // <-- this technique
DWORD PreferSystem32Images : 1;
DWORD AuditNoRemoteImages : 1;
DWORD AuditNoLowMandatoryLabelImages : 1;
DWORD ReservedFlags : 27;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
} PROCESS_MITIGATION_IMAGE_LOAD_POLICY, *PPROCESS_MITIGATION_IMAGE_LOAD_POLICY;
NoLowMandatoryLabelImages 0x1 olarak ayarlandığında "process'in low IL
tarafından yazıldığı şekilde Low mandatory label taşıyan image'ları load
etmesini engeller."
Walkthrough¶
Çağıran process için startup'ta enable et (image'lar load edilmeden önce uygulanmalı; mitigation'lar process init sırasında en etkilidir):
#include <windows.h>
#include <processthreadsapi.h>
int main(void) {
PROCESS_MITIGATION_IMAGE_LOAD_POLICY p = {0};
p.NoLowMandatoryLabelImages = 1; // refuse Low-labeled images
BOOL ok = SetProcessMitigationPolicy(
ProcessImageLoadPolicy, // PROCESS_MITIGATION_POLICY value
&p, sizeof(p));
printf("SetProcessMitigationPolicy=%d gle=%lu\n", ok, GetLastError());
return 0;
}
Desteklenen bir build'de (Windows 10 / Server 2016+) beklenen çıktı:
Low-IL bir process tarafından yazılmış bir DLL'i LoadLibrary etmek için
sonradan yapılan bir girişim böylece başarısız olur. icacls ile Low-label'lı
bir dosya üretebilir ve reddi gözlemleyebilirsin:
> icacls evil.dll /setintegritylevel Low
> rundll32 evil.dll,Entry (from the hardened process)
... fails: STATUS_ACCESS_DENIED / ERROR_ACCESS_DENIED at load time
Aynı policy, CreateProcess'e geçirilen 64-bit mitigation mask'inde
PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY ve
PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_LOW_LABEL_ALWAYS_ON bit'iyle
UpdateProcThreadAttribute üzerinden spawn zamanında uygulanabilir (böylece
ilk DLL map edilmeden önce aktif olur).
Warning
Bu yalnızca dosyanın integrity label'ını inceler, signature'ını veya
içeriğini değil. Medium-label'lı bir konuma yerleştirilmiş zararlı bir DLL
bloklanmaz — defense in depth için NoRemoteImages, code/binary signature
policy ve PreferSystem32Images ile eşleştir.
Detection¶
Load'u başarısız etmeden olası block'ları log'lamak için
AuditNoLowMandatoryLabelImages = 1 ayarla (enforcing bit yerine veya onunla
birlikte). Image-load mitigation event'leri Security-Mitigations / Win32k
operational channel'larında ve WDAC/audit tooling üzerinden görünür, böylece
enforce etmeden önce Low-label'lı image'lara bağımlı uygulamaları bulabilirsin.
Mitigation¶
Bu zaten bir mitigation. Onu zayıflatmak/bypass etmek için bir saldırgan
payload'ını Medium-veya-üstü bir label ile yazdırmalı (örn. ayrı bir elevation
veya bir Medium-IL helper'daki write primitive üzerinden) ya da opt-in yapmamış
bir process'i hedeflemelidir. Create-time'da always-on enforcement, post-init bir
SetProcessMitigationPolicy çağrısından bypass etmesi daha zordur.