Skip to content

KernelCallbackTable Injection

Détourner un processus GUI en modifiant une entrée de sa KernelCallbackTable dans le PEB pour pointer vers du shellcode injecté, puis déclencher l'exécution avec un message de fenêtre tel que WM_COPYDATA.

L'injection par KernelCallbackTable cible les processus GUI (classiquement explorer.exe) en abusant d'une table de répartition que user32.dll utilise pour rappeler le mode utilisateur lorsque le noyau délivre des messages de fenêtre. Le PEB de chaque processus GUI contient un pointeur KernelCallbackTable ; le noyau l'indexe (via KeUserModeCallback) pour des rappels comme fnCOPYDATA. En modifiant une entrée pour qu'elle pointe vers du shellcode injecté puis en envoyant le bon message de fenêtre, l'attaquant amène le système d'exploitation lui-même à invoquer la charge utile.

Fonctionnement

L'injecteur écrit du shellcode dans la cible, lit la KernelCallbackTable d'origine depuis le PEB de la cible, en fait une copie avec une entrée (p. ex. fnCOPYDATA) repointée vers le shellcode, réécrit la table modifiée, et met à jour PEB->KernelCallbackTable pour qu'elle la référence. L'envoi d'un message WM_COPYDATA à la fenêtre de la cible amène alors user32 à répartir via l'entrée modifiée et à exécuter le shellcode dans le contexte de la cible.

text
WriteProcessMemory(hProc, shellAddr, shellcode, len)
ReadProcessMemory(hProc, &peb->KernelCallbackTable, &origTable, ...)
ReadProcessMemory(hProc, origTable, &localCopy, sizeof(localCopy))
localCopy.__fnCOPYDATA = shellAddr                  // patch one callback entry
newTable = VirtualAllocEx(hProc, ...); WriteProcessMemory(hProc, newTable, &localCopy, ...)
WriteProcessMemory(hProc, &peb->KernelCallbackTable, &newTable, sizeof(PVOID))
SendMessage(hWnd, WM_COPYDATA, ...)                  // kernel dispatches the patched entry

Détection & contournement

  • Statique — L'injecteur importe WriteProcessMemory/ReadProcessMemory ainsi que des API de fenêtre/message (FindWindow, SendMessage/SendNotifyMessage avec WM_COPYDATA). Des références au PEB (NtQueryInformationProcess pour le localiser) combinées à des API de messagerie et au nom d'une cible GUI forment un couplage distinctif.
  • Dynamique — Le déclencheur de haute fidélité est une écriture inter-processus vers le champ PEB->KernelCallbackTable distant (ou vers la table qu'il référence), suivie d'un message WM_COPYDATA/de fenêtre qui pilote l'exécution. Surveillez un WriteProcessMemory dont la destination est le décalage PEB de KernelCallbackTable dans un processus GUI. Les traces de threads/pile ETW montreront un rappel (fnCOPYDATA) retournant vers de la mémoire non-user32.
  • Forensique mémoire — Inspectez la KernelCallbackTable de la cible : les entrées d'une table saine résolvent toutes à l'intérieur de user32.dll ; une entrée écrasée pointe vers de la mémoire privée/non adossée ou un autre module. La région du shellcode elle-même est typiquement de la mémoire exécutable privée que pe-sieve/Moneta signalent, et le pointeur de table modifié peut être comparé à une base de référence user32 propre.
  • Outils — Process Hacker / WinDbg (dt nt!_PEB KernelCallbackTable, dump et validation des entrées), pe-sieve et Moneta (région de shellcode exécutable privée), API Monitor / Sysmon ETW (écritures PEB distantes, messages de fenêtre), et Volatility (inspection peb/VAD plus validation de la table de rappels).
Votes

Commentaires(0)