Před pár měsíci jsme byli požádáni o pomoc s incident response po ransomware útoku, při kterém došlo, mimo jiné, k zašifrování několika VMWare strojů. Přirozeně nás napadla otázka, zda disky virtuálních strojů není možné obnovit nebo z nich alespoň extrahovat některá data bez zaplacení výkupného.
Hned první pohled na soubor disku nám dodal naději, že nějaká šance na obnovu existuje. Kromě přípony .needhelp296
identifikující typ ransomware, prozrazovalo jméno souboru, že se jedná o tzv. flat virtuální disk. Na rozdíl od sparse formátu virtuálního disku je struktura flat VMDK souboru totožná se strukturou fyzického disku. První bajt souboru odpovídá prvnímu bajtu disku, druhý druhému a tak dále. VMWare může sice disk rozdělit do několika souborů, ale jejich složení by nemělo být obtížné.
Oproti tomu sparse disky nad daty budují několikaúrovňovou abstrakci v podobě grain tables a grain directory. Pokud se ransomware povede tyto záznamy přepsat, může být obnova velmi namáhavá. V dnešní době se s nimi setkáváme stále častěji a častěji, protože umožňují průběžnou expanzi disku, díky které se můžeme vyhnout prealokaci prostoru pro celý disk při vytváření virtuálního stroje.
Pokud se vám nedaří zorientovat ve všech různých typech VMDK souborů, doporučujeme dnes už ztracenou, ale naštěstí archivovanou Technical Note, která formát hezky popisuje. Dalším odrazovým můstkem může být zdrojový kód open-source virtualizačního software QEMU, který VMDK podporuje.
Pohledem dovnitř souboru pomocí hexeditoru jsme zjistili, že zašifrováno bylo prvních 63 MB a posledních 1,5 KB z celkového objemu 17 GB. Existuje tedy šance, že se nám podaří obnovit alespoň nějaká data. To, že ransomware šifruje začátek a konec disku, je běžné chování. Některé moderní souborové systémy, jako např. NTFS, si totiž svoje řídící struktury, které obsahují metadata o uložených souborech a mnoho dalšího, zálohují, a to typicky na konec disku. Zašifrováním začátku a konce disku tedy ransomware minimalizuje šanci na obnovu dat, ale zároveň šetří čas tím, že nešifrují disk celý.
Asi bychom si neodpustili, pokud bychom se nepokusili VMDK soubor prostě spustit ve VMWare nebo připojit k existujícímu virtuálnímu stroji. Ve výše zmiňované specifikaci formátu VMDK se můžeme dočíst, že flat virtuální disky se ve skutečnosti skládají z alespoň dvou souborů. Ten první, tzv. descriptor, udává strukturu virtuálního disku. S jeho pomocí dokáže VMWare mimo jiné porozumět virtuálním diskům, které se skládají z vícero datových souborů. Vzhledem k tomu, že descriptor bývá jen velmi krátký textový soubor, byl v našem případě celý zašifrován při útoku. Nezbývá nám tedy než si vytvořit vlastní.
Nejrychlejší způsob, jak získat platný descriptor je nechat si jej vygenerovat VMWare Workstation. Vytvoříme si tedy virtuální stroj a k němu flat virtuální disk s požadovanou velikostí, v našem případě 17 GB. Toho dosáhneme tím, že při vytváření disku zaškrtneme „Allocate all disk space now“. Dále vybereme „Store virtual disk as a single file“, protože obnovujeme disk, který se skládá pouze z jednoho datového souboru.
Tím vzniknou dva dříve zmíněné soubory. Ten menší z nich bez přípony -flat
je descriptor, který jsme potřebovali. Větší soubor, ten který ve jméně obsahuje příponu -flat
, je datový soubor disku, který můžeme nahradit diskem, který se snažíme obnovit. Posledním krokem je úprava descriptoru tak, aby souhlasil s nahrazeným souborem disku. Přesná velikost diskového souboru byla v našem případě 18 253 612 564 bajtů. VMWare descriptory však velikosti disku udávají v sektorech. Pro získání odpovídajícího údaje tak musíme velikost v bajtech vydělit 512, čímž dostaneme 35 651 587 sektorů. Výsledek pak stačí zapsat do řádku pod „Extent description“.
# Disk DescriptorFile
version=1
encoding="windows-1252"
CID=fffffffe
parentCID=ffffffff
createType="monolithicFlat"
# Extent description
RW 35651587 FLAT "disk-flat.vmdk" 0
# The Disk Data Base
#DDB
ddb.adapterType = "lsilogic"
ddb.geometry.cylinders = "2219"
ddb.geometry.heads = "255"
ddb.geometry.sectors = "63"
ddb.longContentID = "e1d45ffd15ed01ece0067056fffffffe"
ddb.uuid = "60 00 C2 96 44 80 3d cc-69 1f 81 99 dc f8 20 e2"
ddb.virtualHWVersion = "21"
VM nastartujeme a zkusíme si disk zpřístupnit. Pomocí příkazu lshw -class disk
zkontrolujeme, že skutečně došlo k připojení disku a pokusíme se jej připojit příkazem mount
. Příkaz bohužel selže s chybou odkazující na neplatný superblock. Ta naznačuje, že se mount
disk snaží připojit jako oddíl a očekává, že na něm najde platný souborový systém. Superblock je totiž struktura na disku, která obsahuje informace o souborovém systému, jako je jeho typ, velikost sektorů a další. Za pozornost stojí, že společně se speciálním souborem /dev/sdb
, který umožňuje přístup k disku, se nevytvořily speciální soubory jako /dev/sdb1
, /dev/sdb2
a další, které zprostředkovávají přístup k jednotlivým oddílům. Nepřítomnost těchto souborů indikuje možné poškození tabulky oddílů (partition table).
Zvolíme tedy jiný přístup. Pokusíme se disk prohledat na hlavičky oddílů a partition table rekonstruovat. S diskem můžeme pracovat buď v dříve vytvořeném virtuálním stroji, nebo, pokud chcete předchozí kroky analýzy přeskočit a pustit se rovnou do obnovy dat bez nutnosti vytvářet descriptor, můžeme vytvořit virtuální loop device, které nám umožní s VMDK souborem pracovat jako s diskem. Vzniklý speciální soubor si otevřeme v programu testdisk
.
sudo losetup loop0 disk.vmdk
sudo testdisk /dev/loop0
Ten dělá přesně to, co potřebujeme. Na disku se pokusí nalézt oddíly, určí jejich typ a umožní nám zapsat novou partition table. Při výběru parametrů testdisk
musíme vyjít ze znalostí o disku, který obnovujeme, např. zda používá MBR nebo GUID partition table, jaké zhruba oddíly můžeme očekávat nebo zda na virtuálním stroji běžel Windows (často NTFS) nebo Linux (často ext).
Jakmile testdisk
doběhne, zobrazí tabulku prezentující nalezené oddíly. Zde můžeme měnit charakteristiky jednotlivých oddílů (např. jestli jsou bootovatelné), případně si zobrazit soubory, které jsou v oddílu uložené, čehož můžeme využít při odstraňování false-positive nálezů. V našem případě jsou však všechny oddíly platné, volbu tedy ztvrdíme klávesou Enter
a na další obrazovce zvolíme „Write“ pro zapsání partition table. Hodit se může ještě volba „Deeper Search“, která provede detailnější ale časově náročnější prohledání souboru. Pojí se s ní také vyšší riziko nalezení výše zmiňovaných neplatných oddílů.
Pokud s diskem pracujeme skrze loop device musíme nyní nechat vytvořit speciální soubory pro všechny nalezené oddíly. Pokud máme disk připojený k virtuálnímu stroji napřímo, mělo by stačit jej rebootovat a k vytvoření souborů by mělo dojít automaticky.
sudo kpartx -av /dev/loop0
Příkazem výše dojde k vytvoření souborů /dev/mapper/loop0p1
, /dev/mapper/loop0p2
a dalších odpovídajících jednotlivým oddílům. Než oddíly připojíme, můžeme použít nástroj fsck
pro detekci chyb nebo jiných narušení integrity. Poté už zbývá jen oddíl připojit:
sudo fsck /dev/mapper/loop0p1
sudo mount -o ro /dev/mapper/loop0p1 /mnt/vmdk
Pokud vše proběhne úspěšně, měli bychom mít k dispozici soubory v daném oddílu. Kvalita výsledků se bude odvíjet od množství zašifrovaných dat na disku a správnosti obnovené partition table. Pokud mount
neproběhne úspěšně, může to indikovat, že je část oddílu poškozená, nebo že partition table není správná.
Ne tak úplně. Postup, který jsme právě prošli, není aplikovatelný na všechny případy, i když se nám jej podařilo reprodukovat pro několik různých VMDK souborů zašifrovaných stejným ransomware. Pomohlo nám zejména, že z disku o velikosti 17 GB bylo zašifrováno jen zhruba 64 MB, což je pouhých 0,38 %, a že se jednalo o VMDK soubor typu flat. Přesto se však hodí mít na paměti, že některé soubory je možné obnovit i bez zaplacení výkupného. Problematický však může být tzv. dvojí model ransomware, kdy útočníci data jak zašifrují, tak exfiltrují a vyhrožují jejich zveřejněním.
Přestože jsme ukázali, že zašifrování disku ještě nutně neznamená ztrátu všech dat, je mnohem efektivnějším a spolehlivějším řešením pravidelné zálohování. Pokud je virtuální stroj dostatečně důležitý, aby stál za několikahodinové zkoumání zašifrovaných souborů, je i dostatečně důležitý pro pravidelné zálohování.