Skip to content

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ı:

SetProcessMitigationPolicy=1 gle=0

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.

References