Trochę teorii
Macierze RAID, to zespoły dysków łączone w taki sposób, by były przez komputer widziane jako jedna logiczna całość. Istnieją trzy zasadnicze powody łączenia dysków w macierze:
- podniesienie bezpieczeństwa danych przez wykorzystanie nadmiarowości oferowanej przez niektóre typy macierzy,
- zwiększenie wydajności dzięki równoległemu przetwarzaniu danych umieszczonych na wielu dyskach,
- umożliwienie utworzenia logicznych woluminów większych od pojemności dostępnych dysków.
Dyski mogą być łączone w macierze na kilka sposobów. RAID-0 polega na dzieleniu danych na paski (grupy sektorów o określonym rozmiarze) i rozpraszaniu ich na wszystkich dostępnych dyskach. Ten typ macierzy nie oferuje żadnej nadmiarowości, więc awaria jednego z dysków skutkuje utratą dostępu do wszystkich danych.
RAID-1, to tzw. lustro. Polega na tym, że dane są powielane na wszystkich dostępnych dyskach, dzięki czemu w razie awarii jednego z dysków dane można bez problemu odczytać z innego. Dlatego w przypadku naszego pacjenta nawet po podłączeniu pojedynczego dysku do innego takiego samego serwera system powinien się uruchomić.
Pozostałe typy macierzy łączą rozpraszanie danych na wielu dyskach z pewną nadmiarowością (kod Hamminga dla RAID-2, XOR dla RAID-3, 4, 5 i 6 oraz kod Reeda-Solomona dla RAID-6) pozwalającą zachować spójność danych w przypadku awarii jednego (RAID-2, 3, 4 i 5) lub dwóch (RAID-6 – dlatego w tym typie macierzy używa się dwóch różnych rodzajów danych nadmiarowych) dysków. Macierze też można łączyć w macierze na zasadzie podobnej do łączenia dysków. Takie macierze na macierzach zwykle opisuje się symbolami dwucyfrowymi łączącymi oznaczenia typów macierzy. Np. RAID-10 lub RAID-50 oznaczają macierze RAID-1 lub RAID-5 odpowiednio połączone w macierz RAID-0.
Przystępujemy do pracy
Oba dyski z macierzy okazały się sprawne. Tym niemniej dla bezpieczeństwa pracę zaczynamy od wykonania pełnej kopii posektorowej obu SSDków na dyski twarde. Wykonanie takiej kopii trwało mniej, niż pół godziny, a dalsza praca z dyskami twardymi jest obarczona mniejszym ryzykiem. Oczywiście w komputerze używanym do odzyskiwania danych jest wyłączona obsługa funkcji TRIM.
Macierz była zbudowana na SSDkach 240 GB liczących 1DCF2A6F sektorów. Wszystkie liczby w tym artykule dla ułatwienia analiz będą podawane w systemie szesnastkowym bez dodatkowych oznaczeń typu 0x..., czy...h. Jeśli ktoś pracuje w IT lub profesjonalnie zajmuje się cyberbezpieczeństwem, nie powinno to być problemem. Jeśli ktoś się dopiero uczy, tym bardziej przyda mu się kolejna okazja do nauki.
Analizę przeprowadzimy z wykorzystaniem programu DMDE. Do samej analizy, ale w tym przypadku też i dla wykonania całego zadania wystarczająca jest wersja demonstracyjna. Wybór hiszpańskiej wersji językowej interfejsu wynika z tego, że akurat mamy praktykantów z Hiszpanii, ale na nasze potrzeby język programu nie ma znaczenia. Program ma też polską wersję językową.
MBR
Analizę zaczynamy od sprawdzenia głównego sektora rozruchowego (MBR) znajdującego się w LBA0.
Ponieważ klient zadeklarował, że pacjent, to macierz RAID-1, mogliśmy się spodziewać, że zawartość sektora LBA0 na obu dyskach będzie taka sama. A tu już na pierwszy rzut oka widać, że coś tu nie gra. Sektory ewidentnie się różnią. W obu przypadkach widzimy w tablicy partycji odesłanie do partycjonowania GPT (kod EE w offsecie 1C2).
Kto zauważył, że sygnatura 55AA w offsecie 1FE została zmieniona na 55AB? Jest to celowy zabieg powodujący, że komputer będzie widział dyski jako niezainicjalizowane, co chroni nas przed przypadkowym namieszaniem w zawartości przez system operacyjny, np. przez niekontrolowane uruchomienie chkdsku. Tak, na dyskach, z jakich straciliśmy dane nie powinno się wykonywać żadnych zapisów, ale po pierwsze ten zapis jest kontrolowany, wykonywany w określonym celu i łatwo odwracalny, a po drugie, został wykonany nie na oryginale, a na kopii. Oczywiście taka ingerencja jest niedopuszczalna, gdybyśmy mieli do czynienia z dowodami cyfrowymi – wówczas dla zabezpieczenia nienaruszalności zawartości dysków należałoby użyć sprzętowego blokera zapisu.
GPT
Ponieważ analiza MBRu budzi więcej wątpliwości, niż daje odpowiedzi, zajrzyjmy dalej, do nagłówka tablicy GPT, jaki znajduje się w sektorze LBA1.
Także i tu z łatwością zauważymy, że zawartość się różni, co podważa wiarygodność informacji, że mamy do czynienia z macierzą RAID-1. Kolejna wątpliwość pojawi się, kiedy sprawdzimy w offsecie 20 nagłówka zakresy sektorów objętych adresacją GPT. Na dysku 1 widzimy, że partycjonowanie obejmuje sektory do 1DCF2A6E, co, uwzględniając, że sektory numerujemy od zera, daje nam zgodność z pojemnością dysku. Na dysku 0 mamy wartość 38A3300, a więc wyraźnie więcej, niż wynosi pojemność dysku. Prawie dwa razy więcej.
Jakie wnioski możemy wyciągnąć z tych informacji? Gdybyśmy mieli do czynienia z macierzą RAID-1, poprawnie wygląda nagłówek na dysku 1, a to, co się dzieje na dysku 0, to jakieś obce elementy struktur logicznych. Z kolei informacje o zakresie adresacji z dysku 0 każą nam się zastanowić, czy to czasem nie jest RAID-0. Innych typów macierzy na razie nie bierzemy pod uwagę, gdyż nie da się ich postawić na dwóch dyskach, aczkolwiek nie możemy tego całkowicie wykluczyć, bo nie zawsze klienci dostarczają kompletne macierze.
Tablica partycji
Żeby znaleźć odpowiedź na nasze wątpliwości zajrzyjmy do tablicy partycji:
Na dysku 1 widzimy jedynie jedną małą partycję, w dodatku opisaną jako „Microsoft reserved partition”, z kolei na dysku 0 widzimy już co najmniej 4 spójne partycje o całkiem rozsądnych rozmiarach. Ponieważ wiemy, że macierz już była gdzie indziej, możemy postawić hipotezę, że tam, gdzie była, nikt nie czyta Security Magazinu. Bo gdyby przeczytał numer 1(10)/2023, wiedziałby, że inicjalizacja dysku była błędem, a gdyby przeczytał numer 5(14)/2023, powinien też rozumieć dlaczego. Mamy tu coraz więcej powodów, by przypuszczać, że ta macierz, to RAID-0, a bezsensowna inicjalizacja dysku jest najbardziej wiarygodnym wyjaśnieniem tego, że mamy dwa MBRy, choć w takim przypadku powinniśmy mieć jeden.
Zajrzyjmy jeszcze do kolejnego sektora:
Mamy tu informację o kolejnej partycji. To największa z partycji opisanych w tablicy, a więc wykorzystajmy ją do zweryfikowania podejrzenia, że nasza macierz, to w rzeczywistości RAID-0. Jeśli to prawda, do dzieląc początek partycji przez 2 (bo macierz jest na dwóch dyskach) powinniśmy odnaleźć sektor rozruchowy partycji.
Partycja
I faktycznie w sektorze F60B000/2=7B05800 znajdujemy sektor rozruchowy partycji NTFS. Odczytujemy informację o rozmiarze klastra w sektorach (8) oraz o położeniu pliku $MFT (klaster C0000). Mnożąc numer pierwszego klastra $MFT przez rozmiar klastra w sektorach uzyskujemy numer sektora partycji, w jakim zaczyna się ten plik (C0000x8=600000). Dodajemy tę wartość do początkowego sektora partycji (F60B000+600000=FC0B000) i znów dzielimy przez dwa (FC0B000/2=7E05800). Sprawdzamy wyliczony sektor:
Tak, znajdujemy w nim początek $MFT. Równolegle sprawdzamy zawartość tego samego sektora na dysku nr 1. Znajduje się tam 20 rekord $MFT. A więc mamy nie tylko kolejną różnicę wykluczającą możliwość, że na tych dyskach była macierz RAID-1, ale też informację pozwalającą określić kolejność dysków (tej mogliśmy się już domyślać na podstawie informacji o partycjonowaniu – dla hipotezy, że to jednak RAID-0 dysk 0 wyglądał o wiele wiarygodniej od zanieczyszczonego nieumiejętnymi działaniami dysku 1, a więc MBR macierzy powinien się znajdować na dysku 0) i rozmiar paska. Ze znalezienia rekordu $MFT na dysku 1 mamy też jeszcze jedną ważną informację. TRIM nie wyczyścił tego dysku, choć po jego niepotrzebnej inicjalizacji było takie ryzyko.
Ponieważ rekord $MFT zajmuje 1 kB = 2 sektory mnożymy 20x2 = 40 – i takiego rozmiaru paska się spodziewamy. Jest to zgodne z wiedzą teoretyczną mówiącą o tym, że rozmiar paska jest potęgą dwójki. Dla pewności sprawdzamy jeszcze sektory 7E05840, gdzie znajdujemy rekordy 40 na dysku 0 i 60 na dysku 1:
oraz 7E05840-2=7E0583E, gdzie mamy rekordy 1F i 3F odpowiednio:
Złożenie macierzy
Macierz złożona jako RAID-0 według określonych w opisany wyżej parametrów (kolejność dysków: 0, 1, rozmiar paska: 40 sektorów) okazała się w zasadzie (prócz początku zanieczyszczonego utworzoną po awarii na dysku 1 partycją „Microsoft reserved partition”) spójna i poprawna. Po jej wyeksportowaniu na dysk i niewielkiej ingerencji udało się poprawnie uruchomić i system operacyjny. Pomimo błędu polegającego na inicjalizacji jednego z dysków, dane zostały odzyskane w 100 %.
Wcześniejsza próba odzyskiwania danych musiała zakończyć się odzyskaniem uszkodzonych plików, gdyż samo podejście polegające na skanowaniu tych dysków osobno nie mogło dać lepszych rezultatów. Użyty program, jaki by on nie był, znajdował nagłówki plików, ale z uwagi na rozproszenie tych plików na dwóch dyskach, w ten sposób można było poprawnie odzyskać jedynie pliki mniejsze od rozmiaru paska, czyli 40 sektorów. Zasada działania programów do odzyskiwania danych została bardziej szczegółowo przedstawiona w Security Magazine nr 4(25)/2024.
Administrator informację o tym, że była to macierz RAID-0 przyjął z zaskoczeniem. Nie on ją konfigurował, a według dokumentacji powinna być RAID-1. Inna sprawa, że jakoś nikogo nie zdziwiło, że macierz RAID-1 postawiona na dwóch dyskach 240 GB może pomieścić partycje o łącznej pojemności blisko 500 GB. Administrujesz macierzami RAID? Czy znasz parametry swoich macierzy? Druga sprawa – w razie awarii wymagającej odzyskiwania danych pamiętaj, że do tego trzeba nie tyle animuszu, ile kompetencji i o ile w prostych przypadkach nawet orangutan jakoś sobie poradzi, to oddawanie dysków do odzyskania danych w ręce kogoś, kto nie ma elementarnego pojęcia o strukturach logicznych jest wysoce ryzykowne.