Vectored Overloading PE Injection

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Επισκόπηση τεχνικής

Vectored Overloading είναι ένα Windows PE injection primitive που συγχωνεύει το κλασικό Module Overloading με Vectored Exception Handlers (VEHs) και hardware breakpoints. Αντί να τροποποιήσει το LoadLibrary ή να γράψει τον δικό του loader, ο επιτιθέμενος:

  1. Δημιουργεί ένα SEC_IMAGE section που στηρίζεται σε ένα νόμιμο DLL (π.χ., wmp.dll).
  2. Επικαλύπτει το mapped view με ένα πλήρως relocated κακόβουλο PE αλλά κρατάει το section object να δείχνει στην benign εικόνα στο δίσκο.
  3. Εγγράφει έναν VEH και προγραμματίζει τα debug registers ώστε κάθε κλήση σε NtOpenSection, NtMapViewOfSection, και προαιρετικά NtClose να προκαλεί breakpoint σε user-mode.
  4. Καλεί LoadLibrary("amsi.dll") (ή οποιοδήποτε άλλο benign target). Όταν ο Windows loader καλεί αυτά τα syscalls, ο VEH παρακάμπτει τη μετάβαση στον kernel και επιστρέφει τα handles και τις base addresses της προετοιμασμένης malicious εικόνας.

Επειδή ο loader εξακολουθεί να πιστεύει ότι έγινε map το απαιτούμενο DLL, εργαλεία που κοιτάζουν μόνο τα section backing files βλέπουν wmp.dll παρόλο που η μνήμη τώρα περιέχει το payload του επιτιθέμενου. Ταυτόχρονα, τα imports/TLS callbacks επιλύονται ακόμα από τον γνήσιο loader, μειώνοντας σημαντικά την ανάγκη για custom PE-parsing λογική από πλευράς επιτιθέμενου.

Stage 1 – Build the disguised section

  1. Create and map a section for the decoy DLL
NtCreateSection(&DecoySection, SECTION_ALL_ACCESS, NULL,
0, PAGE_READWRITE, SEC_IMAGE, L"\??\C:\\Windows\\System32\\wmp.dll");
NtMapViewOfSection(DecoySection, GetCurrentProcess(), &DecoyView, 0, 0,
NULL, &DecoySize, ViewShare, 0, PAGE_READWRITE);
  1. Copy the malicious PE into that view section by section, honouring SizeOfRawData/VirtualSize and updating protections afterwards (PAGE_EXECUTE_READ, PAGE_READWRITE, etc.).
  2. Apply relocations and resolve imports exactly as a reflective loader would. Because the view is already mapped as SEC_IMAGE, section alignments and guard pages match what the Windows loader expects later.
  3. Normalize the PE header:
  • If the payload is an EXE, set IMAGE_FILE_HEADER.Characteristics |= IMAGE_FILE_DLL and zero the entry point to keep LdrpCallTlsInitializers from jumping into EXE-specific stubs.
  • DLL payloads can keep their headers unchanged.

Σε αυτό το σημείο η διεργασία έχει ένα RWX-capable view του οποίου το backing object εξακολουθεί να είναι wmp.dll, ενώ τα bytes στη μνήμη ελέγχονται από τον επιτιθέμενο.

Stage 2 – Hijack the loader with VEHs

  1. Register a VEH and arm hardware breakpoints: προγράμματα Dr0 (ή άλλο debug register) με τη διεύθυνση του ntdll!NtOpenSection και θέτεις DR7 ώστε κάθε εκτέλεση να προκαλεί STATUS_SINGLE_STEP. Επανάλαβε αργότερα για NtMapViewOfSection και προαιρετικά NtClose.
  2. Trigger DLL loading με LoadLibrary("amsi.dll"). LdrLoadDll τελικά θα καλέσει NtOpenSection για να λάβει το πραγματικό section handle.
  3. VEH hook for NtOpenSection:
  • Εντόπισε το stack slot για το [out] PHANDLE SectionHandle όρισμα.
  • Γράψε το προηγουμένως δημιουργημένο handle DecoySection σε αυτό το slot.
  • Προχώρησε το RIP/EIP στην εντολή ret ώστε ο kernel να μην κληθεί ποτέ.
  • Επανέφερε το hardware breakpoint για να παρακολουθεί το NtMapViewOfSection στη συνέχεια.
  1. VEH hook for NtMapViewOfSection:
  • Επικαλύπτεις το [out] PVOID *BaseAddress (και τα outputs για size/protection) με τη διεύθυνση του ήδη mapped malicious view.
  • Παράκαμψε το σώμα του syscall όπως και πριν.
  1. (Optional) VEH hook for NtClose ελέγχει ότι το fake section handle καθαρίζεται, αποτρέποντας resource leaks και παρέχοντας έναν τελικό έλεγχο ορθότητας.

Επειδή τα syscalls δεν εκτελούνται ποτέ, callbacks του kernel (ETWti, minifilter, κ.λπ.) δεν παρατηρούν τα ύποπτα γεγονότα NtOpenSection/NtMapViewOfSection, μειώνοντας δραστικά την τηλεμετρία. Από την οπτική του loader όλα πέτυχαν και το amsi.dll είναι στη μνήμη, οπότε προχωρά με την επίλυση imports/TLS απέναντι στα bytes του επιτιθέμενου.

Stage 3 – Execute the payload

  • EXE payload: Ο injector απλά πηδά στο original entry point μόλις γίνουν οι relocations. Όταν ο loader πιστεύει ότι θα καλέσει DllMain, ο custom κώδικας εκτελεί αντ’ αυτού το EXE-style entry.
  • DLL payload / Node.js addon: Επίλυσε και κάλεσε το προοριζόμενο export (ο Kidkadi εκθέτει μια named function προς το JavaScript). Επειδή το module έχει ήδη καταχωρηθεί στο LdrpModuleBaseAddressIndex, επόμενες αναζητήσεις το βλέπουν ως το benign DLL.

Όταν συνδυάζεται με ένα Node.js native addon (.node file), όλο το Windows-internals heavy lifting παραμένει έξω από το JavaScript layer, βοηθώντας τον threat actor να διανείμει τον ίδιο loader με πολλά διαφορετικά obfuscated Node wrappers.

References

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks