Format GIF okiem hakera

background image

38

HAKIN9

ATAK

7-8/2008

W

pierwszej części artykułu,
opublikowanej w Hakin9 5/2008,
opisałem podstawową strukturę pliku

graficznego GIF oraz omówiłem kompresję
LZW. Niniejsza – druga – część artykułu
poświęcona będzie rozszerzeniom formatu
GIF (takim, jak animacja, komentarze czy
wreszcie rozszerzenia aplikacji), miejscom,
w których można ukryć/szukać dodatkowych
danych oraz możliwym do popełnienia podczas
implementacji błędom.

Przed przystąpieniem do lektury warto

przypomnieć sobie ogólną budowę formatu
GIF, podział na części oraz podział danych
na fragmenty – data Sub-blocks (w tym celu
można posłużyć się na przykład poprzednią
częścią artykułu lub sięgnąć do opisu
standardu GIF [1]).

Animowane GIFy

Plik GIF nawet bez korzystania z rozszerzeń
oferuje możliwość zapisania więcej niż jednej
klatki obrazu – w takim przypadku wszystkie
klatki są używane do stworzenia jednej wynikowej
grafiki. Standard 89a wprowadził dodatkową
strukturę – blok kontroli grafiki (ang. Graphic
Control Extension
, GCE), który zawiera dodatkowe
informacje umożliwiające stworzenie z serii
klatek faktycznej animacji. Blok zawiera między
innymi takie informacje, jak wielkość opóźnienia
przed wyświetleniem następnej klatki czy sposób
przejścia do następnej klatki.

MICHAŁ „GYNVAEL

COLDWIND”

SKŁADNIKIEWICZ

Z ARTYKUŁU

DOWIESZ SIĘ

jakie rozszerzenia zostały

wprowadzone do formatu GIF w

wersji 89a,

na co uważać podczas

implementowania rozszerzeń

formatu GIF,

gdzie szukać błędów w

aplikacjach korzystających z GIF,

gdzie ukryć lub szukać ukrytych

danych w plikach GIF.

CO POWINIENEŚ

WIEDZIEĆ

mieć ogólne pojęcie na temat

plików binarnych,

mieć ogólne pojęcie na temat

bitmap,

mieć pojęcie o plikach GIF.

Według dokumentacji jeden taki blok może

(ale nie musi) poprzedzać dane obrazu (a
konkretniej nagłówek Image Descriptor) lub
rozszerzenie zwykłego tekstu (ang. Plain Text
Extension
). Dany blok ma zasięg lokalny, czyli
wpływa jedynie na następującą po nim klatkę
animacji.

Znaczna część pól w strukturze GCE

(patrz Tabela 1) ma stałą, ustaloną z góry,
wartość. Wyjątkami są pola DisposalMethod,
UserInputFlag, TransparentColorFlag,
DelayTime oraz TransparentColorIndex. Pole
DisposalMethod (metoda usunięcia) określa, w
jaki sposób dana klatka ma zostać skasowana
przed narysowaniem następnej. Dostępne są 4
opcje:

• [0] – Nieokreślona metoda usunięcia

(zazwyczaj równoważna z opcją 1),

• [1] – Nie usuwaj (następna klatka zostanie

wyrysowana na obecnej),

• [2] – Wypełnij obraz kolorem tła,
• [3] – Powróć do poprzedniego obrazu.

Dokumentacja zaleca, aby opcji trzeciej używać
jedynie w przypadku niewielkich fragmentów
obrazu (z uwagi na subiektywnie wysokie zużycie
pamięci – chociaż dla obecnych komputerów nie
stanowi to problemu), a w razie, gdyby dekoder
nie potrafił poradzić sobie z przywróceniem
poprzedniego obrazu, dopuszczalne jest
wypełnienie obrazu kolorem tła.

Stopień trudności

Format GIF

okiem hakera

Format GIF, oprócz podstawowej funkcjonalności oferowanej

przez wszystkie standardowe formaty graficzne, udostępnia

również kilka rozszerzeń umożliwiających stworzenie animacji czy

też dodanie komentarza do grafiki.

background image

39

HAKIN9

FORMAT GIF OKIEM HAKERA

7-8/2008

Pozostałe opcje (4-7) są

zarezerwowane do przyszłego użytku
– ale w praktyce różne dekodery
(przy testach zostały wykorzystane: FF
– Mozilla Firefox 2.0.0.14, O – Opera 9.24,
S – Safari 3.1 (525.13), IE – Microsoft
Internet Explorer 7.0.6000.16643, IV
– IrfanView 4.10) już je implementują, i to
w odmienny sposób:

• [4] – IE, IV i FF traktują jako powrót do

poprzedniego obrazu, O i S jako nie
usuwaj
,

• [5] – IE i IV traktują jako powrót do

poprzedniego obrazu, a FF, O, S jako
nie usuwaj,

• [6] – IE i IV traktują jako powrót do

poprzedniego obrazu, FF jako nie
usuwaj
, a O i S jako wypełnij obraz
kolorem tła
,

• [7] – IE, IV, S i O traktują jako powrót

do poprzedniego obrazu, a FF jako nie
usuwaj
.

Jak widać, nie ma w dekoderach zgody
co do tego, jak traktować metody
niezdefiniowane przez dokumentację.
IE oraz IV są zgodne, iż wszystkie
niestandardowe wartości powinny być
traktowane jako powrót do poprzedniego
obrazu, natomiast pozostałe dekodery
nie mają jednego określonego zdania.
Różnice te teoretycznie pozwalają na
stworzenie GIFa, który wyglądać będzie
inaczej w każdej z wspomnianych
przeglądarek graficznych czy
internetowych.

Należy jeszcze dodać, iż Safari ma

poważne problemy wydajnościowe
w przypadku opcji nie usuwaj – dla

porównania, testowy GIF (50 klatek
256x256) na Firefoksie renderował
się około 5 sekund, natomiast Safari
poświęciło na niego prawie 3 minuty,
dodatkowo każda kolejna klatka
renderowała się dłużej od poprzedniej,
a przeglądarka odpowiadała na
polecenia użytkownika tylko pomiędzy
klatkami. Końcowe klatki renderowały
się około 20 sekund, więc możliwe
jest przeprowadzenie skutecznego
ataku DoS przy pomocy odpowiednio
spreparowanej strony WWW (test został
wykonany na komputerze Intel Core 2
Quad 2.4GHz z 4GB RAM).

Pole TransparentColorFlag

(flaga przezroczystości) oraz
TransparentColorIndex (numer
przezroczystego koloru) odpowiedzialne
są oczywiście za istnienie i wybór koloru,
który będzie uznany za przezroczysty
– czyli oznaczał piksele nie narysowane,
pod którymi prześwitywać będzie
poprzednia zawartość bufora. Warto
zaznaczyć, iż jeżeli flaga przezroczystości
jest wygaszona (tj. równa 0), to pole
TransparentColorIndex może zostać
przeznaczone na przechowanie
dowolnego bajtu danych.

Pole DelayTime (opóźnienie) jest

informacją o wielkości opóźnienia (w
setnych sekundy) przed wyświetleniem
kolejnej klatki. Ostatnie pole (a w zasadzie
flaga) – UserInputFlag – określa, czy
dekoder powinien zaczekać na interakcję
z użytkownikiem (pojęcie to nie jest
definiowane przez dokumentację, tak
więc interakcją z użytkownikiem może
być dowolne zdarzenie uznane za
takowe przez dekoder, np. naciśnięcie

przycisku myszy lub dowolnego
klawisza). W przypadku, gdy flaga jest
aktywna oraz gdy ustawiony jest czas
opóźnienia (tj. jest niezerowy), dekoder
powinien zaprezentować kolejną klatkę
po odczekaniu wskazanego czasu lub
po zaistnieniu określonego zdarzenia. W
praktyce wszystkie z testowanych przeze
mnie dekoderów ignorowały tę flagę i nie
czekały na interakcję.

Dodatkowe dane mogą zostać

przechowane w polu Reserved, które
zazwyczaj nie jest kontrolowane przez
dekodery.

Warto zaznaczyć, iż w praktyce

możliwe jest wielokrotne umieszczenie
struktury GCE przed danymi.
Wszystkie testowane dekodery traktują
wtedy ostatnią strukturę GCE jako
obowiązującą, a resztę ignorują – jest to
więc całkiem niezłe miejsce na ukrycie
dodatkowych informacji.

Dodatkowo, programista może

popełnić ewentualny błąd zakładając, iż
BlockSize będzie na pewno równe 4 i
jednocześnie korzystając z niego w celu
załadowania danych do statycznego
bufora – taka sytuacja prowadzi w
prostej linii do przepełnienia bufora. W
praktyce większość dekoderów wymaga,
aby BlockSize był rzeczywiście równy 4
(jest to sprawdzane, w przypadku innej
wartości dekoder przerywa pracę).

Rozszerzenie Netscape

W GCE zabrakło informacji o tym,
czy animacja jest jednorazowa,
czy też powinna być zapętlona w
nieskończoność. W tym celu powstało
rozszerzenie aplikacji NETSCAPE2.0
(jego obsługa została wprowadzona
w Netscape Navigator 2.0 Beta 4),
którego pole NumberOfIterations (patrz
Tabela 2) określa, czy aplikacja powinna
animować GIF w nieskończoność
(wartość 0), czy zaprzestać po określonej

Tabela 1.

Struktura Graphic Control Extension

Typ i nazwa pola

Opis

BYTE ExtensionIntroducer

Znacznik rozszerzenia, zawsze 0x21

BYTE GraphicControlLabel

Rodzaj rozszerzenia, zawsze 0xF9

BYTE BlockSize

Wielkość następującego bloku danych, zawsze 4

BYTE Reserved:3

Zarezerwowane

BYTE DisposalMethod:3

Metoda usunięcia klatki

BYTE UserInputFlag:1

Flaga oczekiwania na interakcje

BYTE TransparentColorFlag:1

Flaga przezroczystości

WORD DelayTime

Czas opóźnienia

BYTE TransparentColorIndex

Numer koloru przezroczystego

BYTE BlockTerminator

Terminator bloku, zawsze 0

Rysunek 1.

Artystyczna wizja własnej

interpretacji GIF przez różne przeglądarki

background image

ATAK

40

HAKIN9 7-8/2008

FORMAT GIF OKIEM HAKERA

41

HAKIN9

7-8/2008

liczbie przebiegów. Co ciekawe,
NN 2.0 Beta 4 uznawała wszystkie
animacje posiadające niniejszą
strukturę jako mające się wykonywać w
nieskończoność, bez względu na wartość
pola NumberOfIterations ; zostało to
poprawione w wersji Beta 5. Animacja
nie posiadająca tej struktury (która
powinna się znajdować zaraz za GCT)
jest traktowana przez dekodery wedle
uznania – zazwyczaj jako animacja,
którą powinno odegrać się raz (IE, FF,
O, S). Istnieją jednak dekodery (IV),
które uznają, iż animacja powinna być
odgrywana w nieskończoność.

Niektóre dekodery (np. IE i FF)

wyświetlają klatki animacji również
podczas ładowania GIFa. To wyświetlenie
nie jest przez nie zaliczane jako
faktyczne wyświetlenie animacji, przez
co efektywnie animacja wyświetlana jest
o jeden raz więcej. IrfanView natomiast
ignoruje nagłówek całkowicie.

Pole One powinno mieć zawsze

wartość 1, natomiast nie wszystkie
dekodery je testują. Ze sprawdzonych
dekoderów jedynie Firefox zwrócił uwagę
na jego zmianę – jest to więc miejsce, w
którym można ukryć bajt danych.

Kolejną możliwą modyfikacją jest

powiększenie bloku zawierającego
wartość Magic. Dekodery zawarte
w IE oraz FF nie zwróciły uwagi na
zmianę (powstało trochę miejsca
do umieszczenia danych), natomiast
dekoder zawarty w Operze uznał, iż
animację należy odtworzyć jedynie raz,
a dekoder z Safari – że animację należy
odtwarzać w nieskończoność.

W przypadku zwiększenia drugiego

sub-bloku danych jedynie Opera
zareagowała identycznie, jak poprzednim
razem, reszta dekoderów zignorowała
zmianę i zachowała się tak, jak gdyby
otrzymała prawidłowo wypełniony
nagłówek.

Analogicznie, jak w poprzednim

przypadku, programista powinien zwrócić
uwagę na możliwość wystąpienia
przepełnienia bufora.

Komentarze

Struktura komentarzy (ang. Comment
Extension
, CE) jest bardzo prosta (co
pokazuje Tabela 3) – składa się ze
stałego nagłówka komentarzy, po nim
następuje seria sub-bloków z danymi
(dla przypomnienia: każdy sub-blok
składa się z bajtu określającego
wielkość danych w bajtach oraz
odpowiednią ilość bajtów danych)
i wreszcie sub-blok terminujący (z
wielkością danych równą 0).

Komentarze z plików GIF wyświetlają

jedynie nieliczne aplikacje, większość
dekoderów je ignoruje.

Głównym błędem, jaki można

popełnić podczas obsługi komentarzy
GIF, jest brak sprawdzania, co komentarz
faktycznie zawiera – czy nie znajdują
się w nim znaki specjalne (np. końca
linii, terminatora tekstu) lub specjalnych
sekwencji. Tego typu błąd został
znaleziony w roku 2001 w przeglądarce
Netscape Navigator przez Floriana
Wescha i umożliwiał umieszczenie kodu
JavaScript wewnątrz komentarza. Skrypt
ten zostałby wykonany w momencie
wyświetlenia pliku GIF (NN wyświetlał
również komentarze) przez przeglądarkę,
np. w wyniku wejścia przez użytkownika
na daną stronę WWW.

Programista może łatwo przeoczyć

także inny błąd, zakładając podczas
implementacji obsługi komentarzy, iż
komentarz nie będzie większy od jednego
sub-bloku (czyli nie będzie przekraczał
255 znaków) – takie założenie może
doprowadzić do przepełnienia bufora.

Plik GIF może zawierać dowolną ilość

struktur CE.

Rozszerzenie Plain Text

Ostatnim rozszerzeniem GIF jest Plain
Text Extension
– rozszerzenie teoretycznie
umożliwiające zapisanie tekstu na
bitmapie jako faktycznego tekstu, a nie
serii pikseli. W takim wypadku dekoder
byłby odpowiedzialny za prawidłowe
wyrysowanie tekstu na wynikowej bitmapie.
Niestety, w praktyce okazuje się, iż
żaden z przetestowanych dekoderów nie
miał zaimplementowanej obsługi tego
rozszerzenia.

Co więcej, w kilku artykułach, na które

natknąłem się podczas badań, autorzy
sugerują, iż jest to martwe rozszerzenie
i powinno zostać zignorowane przez
programistę.

Niemniej jednak z uwagi na

możliwość przyszłego pojawienia się
tego typu dekoderów, lub pojawienia się
potrzeby zaimplementowania takiego

Tabela 2.

Struktura NETSCAPE2.0

Typ i nazwa pola

Opis

BYTE

ExtensionIntroducer

Znacznik rozszerzenia, zawsze 0x21

BYTE ApplicationExtensi

onLabel

Rodzaj rozszerzenia, zawsze 0xFF

BYTE BlockSize1

Długość sub-bloku danych, zawsze 0x0B

BYTE Magic[11]

Zawsze „NETSCAPE2.0”

BYTE BlockSize2

Długość sub-bloku danych, zawsze 0x03

BYTE One

Zawsze 0x01

WORD

NumberOfIterations

Ilość powtórzeń animacji

BYTE BlockTerminator

Terminator bloku, zawsze 0

Tabela 3.

Struktura Comment Extension

Typ i nazwa pola

Opis

BYTE ExtensionIntroducer

Znacznik rozszerzenia, zawsze 0x21

BYTE CommentLabel

Rodzaj rozszerzenia, zawsze 0xFE

SubBlock CommentData[]

Jeden lub więcej sub-bloków danych

BYTE BlockTerminator

Terminator bloku, zawsze 0

W Sieci

http://www.w3.org/Graphics/GIF/spec-

gif89a.txt – standard GIF89a.

background image

ATAK

40

HAKIN9 7-8/2008

FORMAT GIF OKIEM HAKERA

41

HAKIN9

7-8/2008

dekodera, postanowiłem omówić również
i to rozszerzenie.

Rozszerzenie PTE opiera się o

koncept stary jak świat znany z konsoli
poleceń – stałą wielkość pojedynczego
znaku oraz podzielenie ekranu na siatkę
o stałej całkowitej rozdzielczości. W
strukturze PTE podaje się takie informacje
jak początek siatki (położenie lewego
górnego rogu) – pola TextGridLeftPosition
oraz TextGridTopPosition (siatka
w cale nie musi się zaczynać na
0,0!), szerokość i wysokość siatki
– pola TextGridWidth i TextGridHeight,
szerokość i wysokość pojedynczego
znaku – pola CharacterCellWidth oraz
CharacterCellHeight, i kolor czcionki
oraz tła (kolor korzysta z Global Color
Table
). Sam tekst który ma zostać
wyrenderowany jest podzielony na
sub-bloki i jest dołączony po sub-
bloku zawierającym konfigurację PTE.
Całość zakończona jest podobnie jak
w przypadku poprzednich rozszerzeń
– terminującym bajtem o wartości 0.

Standard zaleca aby korzystać

jedynie ze znaków o wielkości 8x8 lub
8x16, oraz aby szerokość i wysokość
siatki była tak dobrana aby ilość znaków
w wierszu czy kolumnie była całkowita
– w przypadku gdy nie jest, część
ułamkowa powinna zostać zignorowana.

Należy zauważyć iż wybór kroju

czcionki należy całkowicie do dekodera,
i jest niezależne od intencji osoby
tworzącej GIF'a.

Pierwszym wektorem ataku, który

nasuwa się od razu po przeczytaniu
zaleceń standardu, jest użycie innej
wielkości znaku niż 8x8 czy 8x16.
Zauważmy iż dla programisty ważną
informacją będzie ilość znaków w
linii, którą wylicza się za pomocą
prostego dzielenia – TextGridWidth/
CharacterCellWidth
(można się obyć
bez tego równania, jednak z dużym
prawdopodobieństwem pojawi się ono
w programie; analogicznie liczy się
maksymalną ilość linii w siatce). Celnym
atakiem na każde dzielenie jest użycie z
zera w mianowniku – co, niesprawdzone,
powoduje wygenerowanie wyjątku Divide
By Zero
, a z kolei nieobsłużony wyjątek
prowadzi do skutecznego ataku typu DoS.

Innym podejściem do problemu

wielkości znaku może być użycie
większego znaku od siatki, oraz, w
drugim podejściu, większego znaku
od całego obrazu. Można w tym celu
użyć odpowiednio dużego znaku (np.
255x255), lub odpowiednio małego
obrazu (np. 4x4) dla standardowej
wielkości znaku. Jeżeli programista
zaniedba sprawdzanie takich
przypadków, taki atak doprowadzi do
przepełnienia bufora obrazu – jednak
prawdopodobieństwo uruchomienia
zewnętrznego kodu w takim wypadku
wydaje się być niezwykle niskie.
Niejako rozwinięciem tego pomysłu
jest użycie siatki większej niż obraz,
ale z wieloma małymi znakami

– nieuważny programista mógł nie
sprawdzić wielkości, co skończyło by
się przepełnieniem bufora – z nadal
niewielkim (ale jednak większym niż
poprzednio) prawdopodobieństwem
wykonania kodu.

Innym wektorem ataku mogły by

być indeksy kolorów – tła i znaku. Jeżeli
programista nie sprawdzi czy index nie
wykracza po za paletę kolorów, może
to doprowadzić do wycieku informacji
(analogicznego jak w przypadku palety,
plików BMP i przeglądarek Mozilla
Firefox i Opera – błąd został opisany
w hakin9 3/2008), lub odmowy usługi
(DoS). Pojawia się również pytanie – a
co jeśli plik nie będzie w ogóle posiadał
globalnej palety kolorów? Kolejny
możliwy wyciek informacji lub DoS.

Podobnie jak w przypadku

poprzednich rozszerzeń, można
przetestować zachowanie dekodera
w przypadku zmiany wielkości sub-
bloku konfiguracyjnego. Warto również
sprawdzić czy dekoder jest w jakiś
sposób wrażliwy na nieobecność
sub-bloku konfiguracyjnego, oraz
na ekstremalną ilość sub-bloków
zawierających tekst.

Z uwagi na fakt iż obecnie mało który

dekoder obsługuje rozszerzenie PTE, to
rozszerzenie staje się bardzo dobrym
miejscem na ukrycie dodatkowych
informacji.

Podsumowanie

We wszystkich wymienionych
rozszerzeniach warto zwrócić również
uwagę na możliwość dołożenia
kolejnego sub-bloku danych do
wymaganych sub-bloków – powinno
to pomóc stworzyć miejsce do ukrycia
kolejnych danych.

Tym artykułem kończę tematykę

plików GIF. Po lekturze obu artykułów
uważny Czytelnik powinien być w stanie
zaimplementować bezpiecznie obsługę
formatu GIF, wraz z rozszerzeniami, a
także skutecznie odnaleźć błędy ukryte w
testowanych aplikacjach.

Michał Składnikiewicz

Michał Składnikiewicz, inżynier informatyki, ma

wieloletnie doświadczenie jako programista oraz

reverse engineer. Obecnie pracuje w Hispasec

– międzynarodowej firmie specjalizującej się w

bezpieczeństwie komputerowym.

Kontakt z autorem: gynvael@coldwind.pl

Tabela 4.

Struktura Plain Text Extension

Typ i nazwa pola

Opis

BYTE ExtensionIntroducer

Znacznik rozszerzenia, zawsze 0x21

BYTE PlainTextLabel

Rodzaj rozszerzenia, zawsze 0x01

BYTE BlockSize

Wielkość sub-bloku – zawsze 0x0C

WORD TextGridLeftPosition

Początek siatki – współrzędna X

WORD TextGridTopPosition

Początek siatki – współrzędna Y

WORD TextGridWidth

Szerokość siatki

WORD TextGridHeight

Wysokość siatki

BYTE CharacterCellWidth

Szerokość pojedynczego znaku

BYTE CharacterCellHeight

Wysokość pojedynczego znaku

BYTE TextForegroundColorIndex

Kolor znaku

BYTE TextBackgroundColorIndex

Kolor tła znaku

SubBlock PlainTextData[]

Sub-bloki zawierające tekst

BYTE BlockTerminator

Terminator bloku, zawsze 0


Wyszukiwarka

Podobne podstrony:
2008 05 Format GIF okiem hakera
Format GIF okiem hakera
Format BMP okiem hakera
2008 03 Format BMP okiem hakera
opisz formaty plików jpg, gif, bmp
Prezentacja formatka
Formaty plików dźwiękowych
Przekroje Format A2
h 1 formatka 2012 budowa hv
P3 PLAN KONSERWATORSKI (FORMAT 2000x2500)
Formatki do zaj z OC Cwiczenie Nieznany
[demo] Vademecum Hakera Edycja plików binarnych
Automatyczne formatowanie dokumentu, informatyka, grafika
Formatowanie(1), Edukacja, Informatyka
2013.09.17 FORMATKA RYSUNKOWA A4
format[1], Szkoła, Systemy Operacyjnie i sieci komputerowe, systemy, semestr I

więcej podobnych podstron