64
OBRONA
HAKIN9 7-8/2009
G
ry komputerowe towarzyszyły
ludziom niemal od początku
istnienia komputerów. Już w latach
pięćdziesiątych powstawały proste gry
komputerowe, które wykorzystywały możliwości
ówczesnych komputerów. Pierwszą grę datuje się
na 1947 rok. Cel gry był dość prosty – należało
tak sterować pociskiem rakietowym, aby trafić
w cel. Pewną trudnością był fakt, iż nie umiano
wtedy tworzyć elektronicznie wyświetlanego
obrazu, toteż musiano specjalnie zmodyfikować
ekran CRT stosowany np. w oscyloskopach.
W kolejnych latach branża rozrywki
komputerowej przeżywała rozkwit. Powstawały
nowe tytuły, które często były przełomowymi
produkcjami jak na ówczesne lata. Większość
gier komputerowych tworzono na uniwersytetach,
rozpowszechniano je w lokalnych sieciach
akademickich, to utrudniało przepływ informacji
pomiędzy różnymi uczelniami – krążyły one
wewnątrz sieci lokalnej danego uniwersytetu.
Dopiero wraz z rozpowszechnieniem się Internetu
nastąpił gwałtowny rozwój technologii rozrywkowych.
W dzisiejszych czasach możemy wyróżnić
wiele gatunków gier komputerowych. Mamy
tytuły FPS, w których wcielamy się w bohatera,
którego zadaniem jest zastrzelenie wszystkich
wrogów; ogromną popularność zdobyły sobie gry
strategiczne, w których osadzeni jesteśmy czy to
w przyszłości, teraźniejszości, czy też kilkaset lat
temu, a naszym zadaniem jest poprowadzenie
imperium do chwały.
KONRAD ZUWAŁA
Z ARTYKUŁU
DOWIESZ SIĘ
w jaki sposób gra komputerowa
może zagrozić bezpieczeństwu
systemu,
jak działa silnik gry
komputerowej i czym on tak
naprawdę jest,
jakie są wektory ataku na grę
komputerową.
CO POWINIENEŚ
WIEDZIEĆ
znać podstawy asemblera,
znać podstawowe techniki
eksploitacji,
orientować się w systemie
operacyjnym Windows.
Inną ciekawą grupą gier są RPG i MMORPG.
Są to gry, w których wcielamy się w rolę
głównego bohatera i przeżywamy najróżniejsze
przygody. W grach typu MMORPG gramy na
serwerach sieciowych z ludźmi z całego świata
– podnosi to zdecydowanie jakość rozgrywki.
Gry sieciowe
Gry komputerowe zdobyły sobie ogromną
popularność ze względu na możliwość grania
w Sieci. Sprawia to, iż rozgrywka nabiera nowej
jakości, staje się ciekawsza i przez to bardziej
wciągająca. Dlatego większość graczy korzysta
ze swojego oprogramowania rozrywkowego
przede wszystkim w Sieci. Zresztą, liczby
mówią same za siebie. W roku 2007 przychody
segmentu rynku gier sieciowych wyniosły prawie
dwa miliardy dolarów. Na rok 2010 planowane
jest osiągnięcie przychodu rzędu czterech i pół
miliarda dolarów. Robi wrażenie?
Co więcej, w 2006 roku przychody tej branży
wyniosły tylko 1,4mld dolarów amerykańskich
– w ciągu roku wzrosły o prawie jedną trzecią.
Świadczy to o stale rosnącym zainteresowaniu
tym niezwykle ciekawym rynkiem.
Wśród gier sieciowych dostępnych jest
niezwykle wiele tytułów. Na swojej prezentacji
na konferencji Sysday wymieniłem tylko kilka
z nich i tak postąpię i tym razem. Wśród gier
FPS, czyli takich, w których naszym celem jest
zastrzelenie jak największej ilości przeciwników,
wymienię Counter Strike, Quake, Medal of
Stopień trudności
Bezpieczne
gry
komputerowe
W kwestiach dotyczących bezpieczeństwa informatycznego
zwykło pomijać się oprogramowanie rozrywkowe, takie jak gry
komputerowe. Czy rzeczywiście niewinna z pozoru gra nie może
posłużyć do kompromitacji firmowego komputera zawierającego
ważne dane?
65
BEZPIECZEŃSTWO GIER KOMPUTEROWYCH
HAKIN9
7-8/2009
Honor, Call of Duty – każda z tych gier
powstała w różnych wersjach, są one stale
rozwijane i udoskonalane. Wśród tytułów
RPG/MMORPG sporą popularnością
cieszy się World of Warcraft, gra, w której
przeżywamy przygody z różnymi ludźmi
z całego świata. Inną grą tego typu, choć
bardziej symulacyjną, jest Second Life,
gdzie wcielamy się w postać... No właśnie,
czyją? Chyba samego siebie, tyle, że w
wirtualnym wydaniu.
Wśród gier strategicznych, które
są również niezwykle popularne w
rozgrywkach sieciowych warto nadmienić
takie tytuły, jak Hearts of Iron, Warcraft, Age
of Empires, Cywilizacja oraz wiele innych,
które również warte są uwagi, jednak
wymienienie ich nie byłoby możliwe ze
względu na ograniczone ramy niniejszego
artykułu.
Skąd biorą się tak ogromne przychody
związane z branżą gier komputerowych?
Cóż, wystarczy popatrzeć na ceny samych
gier oraz abonamentu do niektórych z
nich. Weźmy za przykład World of Warcraft.
W momencie wydania kosztowała ona w
Polsce 199 złotych, co jest niemałą ceną.
Żeby móc grać w tę grę na oficjalnych
serwerach musimy wykupić odpowiedni
abonament. Miesięczny koszt takiej usługi
wynosi 60 zł, co daje nam 720 zł rocznie
+ 200 zł jako kosz zakupu gry – mamy
więc około 900 złotych wydanych w jeden
rok na grę komputerową. Co więcej, do gry
wyszły dodatki, które z pewnością warte
są nabycia – mamy zatem dodatkowe
koszty.
Gry sieciowe zapewniają
zdecydowanie lepszą jakość rozrywki
– nieporównywalnie przyjemniej (i trudniej)
gra się przeciwko graczowi ludzkiemu
– nawet najlepszy algorytm sztucznej
inteligencji nie zapewnia tak ciekawej
rozgrywki.
Granie w godzinach pracy
Aby w ogóle podejść do analizy
bezpieczeństwa samych gier
komputerowych należy się najpierw
zastanowić czy w przeciętnej firmie są
one używane. Bo przecież zamierzamy
się skupić na atakach imających się
firmowej infrastruktury, w których głównym
wektorem ataku ma być właśnie gra
komputerowa. Jeśli więc nikt nie gra
w godzinach pracy to nie mamy tego
problemu. Jednak gdyby tak było artykuł
musiałby skończyć się właśnie w tym
miejscu – pisanie dalej nie miałoby sensu.
Można się więc domyślić, że skoro zostało
jeszcze kilka stron, to problem ten istnieje
– ludzie grają w swoich miejscach pracy.
Listing 1.
Skracacz.c
#include <stdio.h>
#include <stdlib.h>
int
main
(
int
argc
,
char
**
argv
)
{
FILE
*
wejscie
,
*
wyjscie
;
int
licznik
=
0
;
int
i
;
char
bufor
;
if
(
argc
<
3
)
{
printf
(
"Uzycie: skracacz.exe wejscie wyjscie\n"
);
return
1
;
}
wejscie
=
fopen
(
argv
[
1
],
"rb"
);
wyjscie
=
fopen
(
argv
[
2
],
"wb"
);
if
(
!
wejscie
|| !
wyjscie
)
{
printf
(
"Blad plikow.\n"
);
return
1
;
}
// 1. badanie dlugosci pliku
while
(
fgetc
(
wejscie
)
!=
EOF
)
licznik
++
;
fseek
(
wejscie
,
0
,
0
);
//ustawiamy sie na zero
for
(
i
=
0
;
i
<
(
licznik
-
1
);
i
++
)
{
bufor
=
fgetc
(
wejscie
);
fputc
(
bufor
,
wyjscie
);
}
fclose
(
wejscie
);
fclose
(
wyjscie
);
return
0
;
}
Rysunek 1.
Ewolucja silnika Id3Tech
OBRONA
66
HAKIN9 7-8/2009
BEZPIECZEŃSTWO GIER KOMPUTEROWYCH
67
HAKIN9
7-8/2009
Z przeprowadzonych przeze mnie
badań wynika, iż około trzech czwartych
ludzi, którzy pracują na stanowisku
skomputeryzowanym i z dostępem
do Internetu przynajmniej raz w życiu
użyło w miejscu pracy oprogramowania
rozrywkowego – czy to w postaci
prostej gry, w którą gramy za pomocą
przeglądarki internetowej czy przy
użyciu odpowiedniego pliku binarnego,
zainstalowanego w systemie.
Problem ten jest szczególnie istotny
w działach informatycznych. Zwykle ich
pracownicy mają dostęp do komputerów,
które w jakiś sposób zarządzają całą
infrastrukturą przedsiębiorstwa, mając
dostęp do krytycznych węzłów lokalnej
sieci. Skuteczny atak na taki komputer,
prowadzący do kompromitacji jego
systemu, pozwala na dosłowne przejęcie
sieci informatycznej przedsiębiorstwa.
Działy informatyczne winny więc
zachować szczególną ostrożność
jeśli chodzi o używanie różnego
rodzaju oprogramowania, w tym gier.
Tak jednak nie jest – nagminne są
przypadki korzystania z oprogramowania
rozrywkowego w godzinach pracy właśnie
przez dział informatyczny.
Statystycznie rzecz ujmując, ludzi
grających na komputerze można podzielić
na sześć grup, dzieląc ich ze względu na
ilość czasu spędzanego przy komputerze.
I tak, power gamers, czyli mocni gracze
spędzają przy komputerze tyle czasu,
ile zdołają na to wygospodarować.
Gracze społeczni (social gamers)
używają gier jako narzędzia do interakcji
z innymi ludźmi, środka do tworzenia i
podtrzymywania więzi społecznych.
Kolejne cztery grupy to gracze, który
grają tylko w czasie wolnym (leisure
gamers), gracze, których ograniczają
obowiązki zawodowe i domowe
(dormant gamers) oraz dwie grupy
rzadko grających – gracze okazjonalni
i incydentalni (occassional & incidental
gamers).
W tym momencie kluczowym
wydaje się być pytanie – do której grupy
należy pracownik naszej firmy? Czy gra
nałogowo, nawet w godzinach pracy?
Gra komputerowa
jako wektor ataku
Zastanówmy się teraz nad kolejną istotną
kwestią – czy gra komputerowa może
być traktowana jako wektor ataku? Na
pierwszy rzut oka wydaje się to być
nieco irracjonalne. W końcu najczęściej
wektorami ataku są demony nasłuchujące
na portach komputera (http, ftp, ssh),
przeglądarki internetowe czy też szeroko
rozumiane oprogramowanie użytkowe.
Ale gra komputerowa? Mogłoby się
wydawać, że to kompletna bzdura, jednak
mamy tu do czynienia z czymś z serii
niewiarygodne, ale prawdziwe.
Technicznie rzecz ujmując, gra
komputerowa to normalny program
stworzony z wykorzystaniem zwyczajnego
języka programowanie – najczęściej jest
nim C++. Program taki zawiera wszystkie
części składowe typowe dla programu
napisanego dla Windows (bo na tym
systemie się skupiłem) – funkcję WinMain,
procedury z wykorzystaniem API systemu
oraz te pochodzące ze standardowej
Listing 2.
Bajt.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
int
main
(
int
argc
,
char
**
argv
)
{
//fuzzer pliku - zmienia losowy bajt w pliku
FILE
*
plik
,
*
plik2
;
char
*
nowaNazwa
;
int
licznik
=
0
,
i
;
int
losowyBajt
;
char
znak
;
char
*
buf
;
nowaNazwa
=
malloc
(
64
);
memset
(
nowaNazwa
,
'\0'
,
64
);
if
(
argc
<
2
)
{
puts
(
"Uzycie: bajt.exe nazwaPliku\n"
);
return
1
;
}
srand
(
time
(
0
));
// inicjacja generatora liczb losowych
plik
=
fopen
(
argv
[
1
],
"rb"
);
while
(
fgetc
(
plik
)
!=
EOF
)
licznik
++
;
printf
(
"Ilosc bajtow w pliku: %d\n"
,
licznik
);
#ifdef RAND_MAX
#undef RAND_MAX
#endif
#define RAND_MAX licznik
losowyBajt
=
rand
();
printf
(
"losowyBajt: %d\n"
,
losowyBajt
);
fclose
(
plik
);
for
(
i
=
0
;
i
<
strlen
(
argv
[
1
]);
i
++
)
{
znak
=
argv
[
1
][
i
];
if
(
znak
!=
'.'
)
nowaNazwa
[
i
]
=
znak
;
else
if
(
znak
==
'.'
)
i
=
strlen
(
argv
[
1
])
+
1
;
}
strcat
(
nowaNazwa
,
"fuzzed"
);
strcat
(
nowaNazwa
,
".scm"
);
printf
(
"Nowa nazwa: %s\n"
,
nowaNazwa
);
plik
=
fopen
(
argv
[
1
],
"rb"
);
plik2
=
fopen
(
nowaNazwa
,
"wb"
);
buf
=
malloc
(
licznik
+
1
);
memset
(
buf
,
'\0'
,
licznik
+
1
);
fread
(
buf
,
1
,
losowyBajt
,
plik
);
buf
[
losowyBajt
]
=
'A'
;
fgetc
(
plik
);
fread
(
buf
+
losowyBajt
+
1
,
1
,
licznik
-
(
losowyBajt
+
1
),
plik
);
fwrite
(
buf
,
1
,
licznik
,
plik2
);
fclose
(
plik
);
fclose
(
plik2
);
}
OBRONA
66
HAKIN9 7-8/2009
BEZPIECZEŃSTWO GIER KOMPUTEROWYCH
67
HAKIN9
7-8/2009
biblioteki C. Cechą specjalną takiego
programu jest to, iż zawiera on biblioteki
do obsługi grafiki – dziś wszystkie gry
komputerowe mają zaawansowane
możliwości wyświetlania grafiki.
Gra komputerowa jest więc
zwyczajnym programem komputerowym.
Jeśli dodać do tego ogromną ilość
operacji, jakie ma ona wykonać,
otrzymujemy program o dużej złożoności.
To, w połączeniu z wyświetlaniem
grafiki daje nam program niezwykle
złożony, potrzebujący znacznych mocy
obliczeniowych do wykonania swojego
zadania. Jest to więc idealny wektor ataku
– im wyższa złożoność oprogramowania,
tym większe prawdopodobieństwo
wystąpienia w nim błędów.
Dodatkowym faktem przemawiającym
na naszą korzyść jest fakt, iż powszechne
jest myślenie, które staram się w
niniejszym artykule obalić. Myślenie,
że gra komputerowa nie musi być
bezpieczna, bo nie zostanie wykorzystana
jako wektor ataku. To błędne myślenie
powoduje, iż często kwestie związane z
bezpieczeństwem są przez twórców gier
zaniedbywane, jako całkowicie nieistotne.
Tak samo wygląda sytuacja z
poprawkami (patchami) publikowanymi
do gier. Wiele luk w bezpieczeństwie
pozostaje niezałatanych, same patche
odnoszą się tylko do rozgrywki,
poprawiając znalezione tam błędy, nie zaś
do kwestii związanych z likwidowaniem
podatności odkrytych w takich aplikacjach.
Błędy mogą więc być częstym zjawiskiem
i tak w istocie jest, co zresztą (mam
nadzieję) udało mi się pokazać na
konferencji Sysday i uda się to w niniejszej
publikacji.
Silnik gry komputerowej
Aby lepiej zrozumieć możliwość
eksploatacji gry komputerowej, musimy
przyjrzeć się temu jak jest zbudowana
– jej wnętrznościom, czyli silnikowi gry
komputerowej.
O pojęciu silnika gry komputerowej
słyszał pewnie każdy – jest to coś, co
sprawia, że gra komputerowa działa
– wyświetla grafikę i jest grywalna. Jest
to prawda, ale silnik gry komputerowej
spełnia o wiele więcej funkcji, niż same
operacje na grafice. Można w nim
wyróżnić wiele elementów składowych,
które odpowiedzialne są za całościowe
działanie programu:
• ładowanie map,
• obsługa różnych formatów graficznych,
• moduły sieciowe,
• zapisywanie i odczytywanie stanu gry,
• i wiele innych.
Każdy z wymienionych powyżej modułów
składa się z podmodułów – żeby
załadować mapę musimy ją wczytać
z pliku, sprawdzić, czy format pliku jest
poprawny, załadować odpowiednie dane
do pamięci. Każda z tych czynności
może być obarczona błędami, które
sprawią, że możliwe będzie... no właśnie,
co? Mamy możność dokonania dwóch
ataków – DoS, czyli zawieszenia bądź to
gry, bądź całego komputera oraz code
execution – wykonania własnego kodu na
komputerze ofiary.
Rysunek 3.
Serwer
Rysunek 2.
Wow
OBRONA
68
HAKIN9 7-8/2009
BEZPIECZEŃSTWO GIER KOMPUTEROWYCH
69
HAKIN9
7-8/2009
Błędy, jakie mogą wystąpić w
silniku graficznym są zwykłymi błędami
programistycznymi, spotykanymi w
różnych aplikacjach o całkowicie
odmiennym przeznaczeniu – kategorie
błędów pozostają takie same:
przepełnienia bufora na stercie, stosie,
błędy związane z liczbami (integer
overflow, underflow), write-what-where, etc.
Słowem kategorie błędów są te same,
co w zwykłym oprogramowaniu (o ile
możemy rozpatrywać grę komputerową
jako coś niezwykłego).
Wektory ataku na taką grę są
bardzo różne – każdy z elementów
wymienionych powyżej jest potencjalną
furtką, którą możemy wykorzystać do
zaatakowania systemu ofiary poprzez
grę komputerową. Narzuca się jednak
jedna cecha wspólna – wszystkie dane,
które są przetwarzane pochodzą w jakiś
sposób od użytkownika. Musimy zatem
sprawdzić, czy aby na pewno program,
czyli gra komputerowa, poprawnie
przetwarza dane, które zaaplikował mu
użytkownik. W tym celu posłużymy się
fuzzingiem.
Fuzzujemy grę komputerową
Gra komputerowa, jako bardzo złożona
aplikacja, daje nam możliwość
fuzzowania niezwykle wielu jej
elementów. Musimy więc skupić się
na jakiejś konkretniej jej części, aby
dokładnie przeanalizować ten fragment
silnika gry. Analiza całości byłaby
bowiem niezwykle pracochłonna, a
kto wie czy możliwa do wykonania w
rozsądnym czasie.
Idąc dalej tym tokiem rozumowania,
należy skupić się na części silnika
odpowiedzialnej za ładowanie map
– nazwijmy ją MapLoader'em. Co
dokładnie robi taki MapLoader ?
Jego zadaniem jest otwarcie pliku z
mapą, sprawdzenie jego poprawności
(nagłówek oraz sposób zapisania
danych), wczytanie danych z pliku z i do
pamięci, po czym skopiowanie ich do
odpowiednich struktur odpowiedzialnych
za dany fragment mapy.
Fuzzing pliku z mapą polegał będzie
zatem na odpowiednim zmienieniu
danych wejściowych tak, aby były one
zgodne z ogólnym formatem pliku w
takim stopniu, w jakim wymaga tego
MapLoader. Możemy zmieniać dane w
pliku, nagłówek zaś i sposób zapisania
tych danych powinny być poprawne,
inaczej MapLoader wykryje, że ładowany
jest nieodpowiedni plik i zakończy swoje
działanie.
Na potrzeby tych testów stworzyłem
proste narzędzia, programy, których
zadaniem było kolejno skrócenie pliku
o bajt, zmiana jednego bajtu w pliku na
inny oraz zmiana kilkunastu/set/tysięcy
bajtów na określony znak. Programy
te nazywały się kolejno skracacz.exe,
bajt.exe, bajtyLosowe.exe. Program
bajtyLosowe.exe pozwalał dodatkowo
na możliwość określenia, czy bajty mają
być nadpisane począwszy od losowego
miejsca w pliku (pozycja, od której
Rysunek 4.
Quake III Arena
Rysunek 5.
PunkBuster Service Setup
OBRONA
68
HAKIN9 7-8/2009
BEZPIECZEŃSTWO GIER KOMPUTEROWYCH
69
HAKIN9
7-8/2009
zaczniemy nadpisywać generowana
będzie na podstawie odpowiedniego
wywołania funkcji
random()
), czy też
zacząć zmienianie bajtów w miejscu
ustalonym przeze mnie. Kody źródłowe
tych trzech programów zaprezentowane
zostały na Listingach od 1 do 3.
Dlaczego zdecydowaliśmy się akurat
na fuzzing? Fuzzing, jako zmienianie
danych wejściowych w oczekiwaniu
na ich niepoprawną obsługę, jest
bardzo dobrą (czyli skuteczną) metodą
znajdywania błędów w oprogramowaniu.
Poza tym testy fuzzerami pozwalają
na zaoszczędzenie czasu, bowiem
cały proces można w pewnym stopniu
zautomatyzować. Niestety w przypadku
gier komputerowych konieczne jest
ręczne ładowaniu danego pliku z mapą
– automatyczne wywoływanie funkcji,
która ma za zadanie załadowanie map
do pamięci byłoby niezwykle trudne,
choć wykonalne.
Rozpoczynamy testy –
na rozgrzewkę Starcraft
Na rozgrzewkę postanowiłem dokonać
testu gry Starcraft – gra ta, mimo
swojego wieku, ciągle cieszy się
ogromnym zainteresowaniem graczy.
Dodatkowo ze względu na swoje
niewielkie wymagania sprzętowe,
możliwe jest jej uruchomienia na
niemal każdym komputerze biurowym
– w dzisiejszych czasach każdy
komputer, nawet ten, ze zintegrowanym
układem graficznym i niezbyt szybkim
procesorem, jest w stanie udźwignąć
Starcrafta.
Generalnie rzecz biorąc moim celem
były gry, które nie mają oszołamiających
wymagań sprzętowych – mają to być
przecież tytuły, które z powodzeniem dają
się uruchomić na zupełnie przeciętnym
komputerze biurowym, a więc
najnowsze gry odpadają. Jednak jak
pokazuje doświadczenie, największym
zainteresowaniem graczy cieszą się
tytuły nieco starsze, albowiem wielu
z nich ma w nich doświadczenie, co
powoduje, że ilość osób chętnych zagrać
w dobrze już oklepany tytuł jest często
większa, niż tych, którzy zakupili dopiero
co wydany tytuł.
Na pierwszy ogień poszedł Starcraft.
Zmiana jednego tylko bajtu pozwoliła na
Listing 3.
BajtyLosowe.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
//size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
//size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
int
main
(
int
argc
,
char
**
argv
)
{
FILE
*
wejscie
,
*
wyjscie
;
unsigned
long
iloscNadpisywanych
=
0
;
unsigned
long
dlugoscPliku
=
0
,
i
=
0
,
poczatek
=
0
,
wznowienie
=
0
;
char
decyzja
;
int
what
;
if
(
argc
<
3
)
{
printf
(
"Uzycie: bajtyLosowe.exe wejscie wyjscie\n"
);
return
1
;
}
printf
(
"Ile bajtow nadpisac? "
);
scanf
(
"%u"
,
&
iloscNadpisywanych
);
printf
(
"Czy nadpisac konkretne miejsce czy losowo? 0/1 "
);
scanf
(
"%d"
,
&
what
);
wejscie
=
fopen
(
argv
[
1
],
"rb"
);
wyjscie
=
fopen
(
argv
[
2
],
"wb"
);
while
(
fgetc
(
wejscie
)
!=
EOF
)
dlugoscPliku
++
;
printf
(
"Plik ma dlugosc %u bajtow.\n"
,
dlugoscPliku
);
if
(
what
==
0
)
{
printf
(
"Podaj poczatkowy bajt: "
);
scanf
(
"%u"
,
&
poczatek
);
}
else
{
srand
(
time
(
0
));
#ifdef RAND_MAX
#undef RAND_MAX
#define RAND_MAX dlugoscPliku
#endif
poczatek
=
rand
();
}
fseek
(
wejscie
,
0
,
0
);
printf
(
"Stage 1\n"
);
while
(
i
<
poczatek
)
{
fread
(
&
decyzja
,
1
,
1
,
wejscie
);
fwrite
(
&
decyzja
,
1
,
1
,
wyjscie
);
i
++
;
wznowienie
=
i
;
}
printf
(
"Stage 2\n"
);
// printf("Podaj czym nadpisac: ");
// scanf("%c",&decyzja);
for
(
i
=
0
;
i
<
iloscNadpisywanych
;
i
++
)
{
decyzja
=
'A'
;
fwrite
(
&
decyzja
,
1
,
1
,
wyjscie
);
fread
(
&
decyzja
,
1
,
1
,
wejscie
);
wznowienie
++
;
}
printf
(
"Stage 3\n"
);
while
(
wznowienie
<
dlugoscPliku
)
{
fread
(
&
decyzja
,
1
,
1
,
wejscie
);
fwrite
(
&
decyzja
,
1
,
1
,
wyjscie
);
wznowienie
++
;
}
printf
(
"Zapisano %u bajtow.\n"
,
wznowienie
);
return
0
;
}
OBRONA
70
HAKIN9 7-8/2009
wywołanie ataku DoS – gra zawiesiła się
podczas wczytywania mapy. Co więcej,
niemożliwe było zrobienie czegokolwiek
na komputerze – przestał reagować
na polecenia wydawane z klawiatury.
Konieczny był twardy reset.
Niestety nie dokonaliśmy wielkiego
odkrycia – Gynvael Coldwind opisał
na swojej stronie internetowej ten błąd
dawno przed nami, choć znaleźliśmy go
zupełnie niezależnie, nie korzystając z
materiałów, które udostępnił.
Jednak ten prosty przykład pokazuje,
iż bardzo łatwo znaleźć błąd w grze
komputerowej. Zmiana tylko jednego
bajtu spowodowała konieczność
restartowania komputera. Gdybyśmy
mieli do czynienia z ważną stacją
roboczą, pełniącą np. rolę serwera,
każdy jej przestój mógłby narazić firmę
na jakieś określone straty. W ten bardzo
prosty sposób możemy spowodować, iż
pracownikom nie pozostanie nic innego
jak zresetować komputer, oczywiście,
jeśli nie zostawią gry włączonej w trakcie
ładowania mapy, uprzednio odchodząc
na dłuższy czas od komputera – wtedy
przestój może być jeszcze większy.
Wstęp do ID3Tech – Quake 3
Po dłuższej analizie możliwych do
wykorzystania tytułów doszedłem do
wniosku, że warto byłoby skorzystać
z gry, której kod źródłowy jest ogólnie
dostępny. Pozwala to na lepszą
ilustrację omawianych przykładów
– kod asemblera można wykorzystać
do niskopoziomowej analizy problemu,
C/C++ posłuży nam natomiast
do zrozumienia i pokazania błędu
popełnionego w języku programowania
wysokiego poziomu.
Wybór padł na silnik ID3Tech, który
użyty został między innymi w takich
grach jak Quake 3, Call of Duty oraz
Medal of Honor: Allied Assault. Widać
więc, iż jest to silnik popularny – istotnie,
jego popularność doskonale ilustruje
Rysunek 1.
Jak już zostało wspomniane,
ogromną zaletą tego silnika jest fakt,
iż całość kodu źródłowego została
udostępniona przez twórców gry.
Pozwala to na zwiększenie naszych
możliwości w kwestii poszukiwania
błędów – możemy użyć fuzzerów oraz
dodatkowo czytać kod źródłowy, co
pozwoli na odnalezienie kolejnych
podatności.
W przypadku tego silnika skupimy się
na kwestiach związanych z ładowaniem
pliku z mapą oraz obsługą plików
graficznych. Ogromna popularność
silnika, jego użycie w kilkunastu różnych
tytułach otwiera przed nami pewną furtkę
– możemy sprawdzić, czy podatności
odkryte w grze A będą również
występowały w grze B.
Podsumowanie
Niniejszy artykuł pozwolił wstępnie
zapoznać się z tematyką gier
komputerowych. W kolejnym artykule
dokonamy dokładnej analizy gry Quake
3 – czy uda nam się znaleźć podatności
czy też jakiekolwiek niebezpieczeństwo
wynikające z grania na komputerze to
tylko wymysł autora? O tym w kolejnym
artykule.
Listing 4.
Wywołanie wyjątku w grze Starcraft
Exception
code:
C0000005
ACCESS_VIOLATION
Fault
address:
00441
C3E
01
:
00040
C3E
D:
\
Starcraft
\
StarCraft
.
exe
Registers:
EAX:
00000730
EBX:
0282000
C
ECX:
0000
BAE3
EDX:
030964
AC
ESI:
02
AB325C
EDI:
02
A8325C
CS:EIP:
001
B:
00441
C3E
SS:ESP:
0023
:
0012F
A78
EBP:
0282000
C
DS:
0023
ES:
0023
FS:
003
B
GS:
0000
Flags:
00210206
Call
stack:
Address
Frame
Logical
addr
Module
00441
C3E
0282000
C
0001
:
00040
C3E
D:
\
Starcraft
\
StarCraft
.
exe
Rysunek 6.
Call of Duty 2
Konrad Zuwała
Autor zajmuje się bezpieczeństwem aplikacji
internetowych oraz szeroko rozumianą ochroną
systemów komputerowych. W wolnych chwilach
programuje (głównie C/C++, PHP) oraz zarządza
portalem internetowym.
Kontakt z autorem: kzuwala@poczta.onet.pl