background image

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 StrikeQuakeMedal 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?

background image

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

background image

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

);

}

background image

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

background image

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.exebajtyLosowe.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

background image

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

;

}

background image

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