Skip to content

Block remote images

Bir process'in UNC share gibi remote bir device'ta bulunan executable image'ları map etmesini engelleyen ve network-path DLL hijack yüzeyini ortadan kaldıran bir Windows process-mitigation policy'si.

Mechanism

Note

Windows image loader, DLL adlarını remote path'lere (UNC \\server\share\..., mapped network drive'lar, WebDAV) ulaşabilen bir search order üzerinden çözer. Victim'in search order'ının dokunduğu bir network konumunu kontrol eden bir saldırgan, zararlı bir .dll/.exe'yi hat üzerinden servis edebilir — aynı zamanda NTLM-relay ve "living off the land" load'larını da mümkün kılan bir remote DLL-planting / search-order-hijack primitive'i. NoRemoteImages policy'si basit bir invariant enforce eder: kernel image loader, remote bir device tarafından backing edilen herhangi bir dosyadan executable section oluşturmayı reddeder. Karar kernel'da section creation'da verildiğinden, her load path'ini kapsar (LoadLibrary, delay-load, SxS/manifest activation, CreateProcess image mapping) ve user mode'daki path-canonicalization hileleriyle aşılamaz.

Flag, PROCESS_MITIGATION_IMAGE_LOAD_POLICY'nin ilk bit'idir:

typedef struct _PROCESS_MITIGATION_IMAGE_LOAD_POLICY {
  union {
    DWORD Flags;
    struct {
      DWORD NoRemoteImages : 1;              // <-- this technique
      DWORD NoLowMandatoryLabelImages : 1;
      DWORD PreferSystem32Images : 1;
      DWORD AuditNoRemoteImages : 1;
      DWORD AuditNoLowMandatoryLabelImages : 1;
      DWORD ReservedFlags : 27;
    } DUMMYSTRUCTNAME;
  } DUMMYUNIONNAME;
} PROCESS_MITIGATION_IMAGE_LOAD_POLICY, *PPROCESS_MITIGATION_IMAGE_LOAD_POLICY;

Microsoft'a göre, NoRemoteImages 0x1 olarak ayarlandığında "process'in UNC share gibi remote bir device'tan image load etmesini engeller."

Walkthrough

Çağıran process'i startup'ta opt-in yap:

#include <windows.h>
#include <processthreadsapi.h>

int main(void) {
    PROCESS_MITIGATION_IMAGE_LOAD_POLICY p = {0};
    p.NoRemoteImages = 1;                    // refuse images from remote devices

    BOOL ok = SetProcessMitigationPolicy(
        ProcessImageLoadPolicy, &p, sizeof(p));

    printf("SetProcessMitigationPolicy=%d gle=%lu\n", ok, GetLastError());
    return 0;
}

Beklenen çıktı (Windows 10 / Server 2016+):

SetProcessMitigationPolicy=1 gle=0

Artık UNC bir path'ten DLL load etmek için yapılan herhangi bir girişim map zamanında reddedilir:

> rundll32 \\attacker\share\payload.dll,Entry   (from the hardened process)
... fails: ERROR_ACCESS_DENIED — the image is on a remote device

Policy'yi process'in ilk DLL load'undan önce aktif yapmak için spawn zamanında ayarla. UpdateProcThreadAttribute, 64-bit bir mask ile PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY alır; ilgili bit PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_REMOTE_ALWAYS_ON'dur:

SIZE_T sz = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &sz);
auto al = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, sz);
InitializeProcThreadAttributeList(al, 1, 0, &sz);

DWORD64 mask = PROCESS_CREATION_MITIGATION_POLICY_IMAGE_LOAD_NO_REMOTE_ALWAYS_ON;
UpdateProcThreadAttribute(al, 0,
    PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &mask, sizeof(mask), NULL, NULL);
// pass `al` via STARTUPINFOEX to CreateProcess(... EXTENDED_STARTUPINFO_PRESENT ...)

Warning

"Remote", process'in path'in nereyi gösterdiğine inandığına göre değil, backing file'ın device tipine göre değerlendirilir. Mount edilip sonra bir local junction üzerinden erişilen bir remote share hâlâ remote'tur. Tersine, bu local planting'i durdurmazNoLowMandatoryLabelImages ve PreferSystem32Images ile birleştir.

Detection

Denenen remote load'ları bloklamadan log'lamak için AuditNoRemoteImages = 1 ayarla. Audit event'leri, enforcement'ı açmadan önce network path'lerine olan legitimate bağımlılıkları keşfetmene izin verir ve kendi kendine yol açacağın arızalardan kaçınmanı sağlar.

Mitigation

Bir mitigation olarak yalnızca payload'ı bir local volume'a sokarak (remote kriterini aşarak) ya da hiç opt-in yapmamış bir process'e saldırarak bypass edilir. Bit'i mitigation mask üzerinden CreateProcess zamanında always-on enforce etmek, post-init bir policy set'inden kesinlikle daha güçlüdür.

References