You are on page 1of 7

Format BMP okiem hakera

Atak
Micha Gynvael Coldwind Skadnikiewicz

stopie trudnoci

Pliki graficzne s dzi szeroko rozpowszechnionym nonikiem informacji, spotyka si je praktycznie na kadym komputerze. Dobry programista powinien wiedzie jak wygldaj nagwki poszczeglnych formatw plikw graficznych, i jak s przechowywany jest sam obraz. A jak to zwykle bywa, diabe tkwi w szczegach.

iniejszy artyku ma na celu zapozna czytelnika z formatem przechowywania obrazu BMP, wskaza w nich miejsca ktre mona wykorzysta do przemycenia ukrytych danych, miejsca w ktrych programista moe popeni bd podczas implementacji oraz zapozna ze samym formatem. Przykady bd w miar moliwoci zilustrowane pewnymi bugami w istniejcym oprogramowaniu, znalezionymi przez autora oraz inne osoby.

Wstp do BMP

niezalenie od wersji) ktra zawiera m.in. identyfikator pliku tzw. liczb magiczn (ang. magic number), oraz offset na ktrym znajduj si dane bitmapy. Bezporednio po BITMAPFILEHEADER, na offsecie 0Eh, znajduje si struktura BITMAPINFOHEADER (dodam e deklaracje omawianych struktur mona znale w pliku wingdi.h w Platform SDK), ktra zawiera informacje o obrazie, jego rozdzielczoci, gbi kolorw czy uytej metody kodowania/kompresji. W przypadku bitmap o gbi 4 lub 8 bitw, zaraz za struktur BITMAPINFOHEADER znajduje si

Niesawny format BMP znany jest przede wszystkim z plikw o ogromnych wielkociach (w porwnaniu do JPEG czy PNG). Format ten stworzony zosta przez firmy IBM oraz Microsoft na potrzeby systemw OS/2 oraz Windows, obie firmy rozwijay go jednak oddzielnie, co spowodowao powstanie kilku wariantw tego formatu. Niniejszy tekst skupia si na BMP w wersji Windows V3, pozostae wersje (OS/2 V1 i V2 oraz Windows V4 i V5) pozostawiam czytelnikowi do wasnej analizy jako zadanie domowe :). Niezalenie od wersji, oglna budowa pliku, przedstawiona na Rysunku 1, pozostaje taka sama. Na samym pocztku pliku znajduje si struktura BITMAPFILEHEADER (jest ona staa,

Z artykuu dowiesz si
jak zbudowany jest plik BMP, na co uwaa podczas implementowania obsugi formatu BMP, gdzie szuka bdw w aplikacjach korzystajcych z BMP.

Co powiniene wiedzie
mie oglne pojcie na temat plikw binarnych, mie oglne pojcie na temat bitmap.

hakin9 Nr 3/2008

www.hakin9.org

Format BMP okiem hakera

paleta barw, ktr jest odpowiedniej wielkoci tablica struktur RGBQUAD. W przypadku bitmap o gbi kolorw 16 bitw zamiast palety barw w tym miejscu znajduj si prosta struktura skadajca si z trzech DWORD'w ktre s maskami bitowymi okrelajcymi ktre bity w danych obrazu odpowiadaj za barw, kolejno, czerwon, zielon oraz niebiesk, natomiast w bitmapach, o gbi 24 bity lub wikszejm paleta barw nie wystpuje. Dane obrazu zaczynaj si na offsecie podanym w BITMAPFILEHEADER, zazwyczaj od razu po ostatnim nagwku. Budowa danych zaley za rwno od uytego kodowania jak i gbi kolorw. Tak przedstawia si oglna budowa formatu BMP. Szczegowa budowa formatu BMP przedstawiona jest w dalszej czci artykuu.

Nagwek BITMAPFILEHEADER

Nagwek BITMAPFILEHEADER (patrz Tabela 1) rozpoczyna si na pocztku pliku (offset 0 ) i ma wielko 14 bajtw (0Eh). Najmniej interesujcym polem struktury jest pierwsze pole bfType, ktre zawsze ma warto odpowiadajc cigowi ASCII BM. Kolejnym polem jest DWORD bfSize w ktrym wg. specyfikacji powinna znale si cakowita wielko pliku w bajtach. Wielko pliku prawidowego pliku atwo obliczy dodajc wielkoci poszczeglnych nagwkw, palety barw oraz danych obrazu. To pole stanowi pierwsz puapk, ale w ni wpadaj jedynie nieuwani programici. Rozwamy kod z Listingu 1 programista wczyta nagwek, zaufa polu bfSize i zaalokowa tyle pamici

ile wg. bfSize jest potrzebne, po czym wczyta cay plik (a do koca) do zaalokowanego bufora. Funkcja dziaa wymienicie, pod warunkiem e warto bfSize jest rwna lub wiksza od faktycznej wielkoci pliku. Jeli warto bfSize bdzie mniejsza, dojdzie do klasycznego bdu przepenienia bufora ktry wprawny wamywacz mg by wykorzysta do wykonania wasnego kodu. Dobrym pomysem jest zignorowanie wartoci tego pola, i korzystanie jedynie z wielkoci pliku otrzymanej od systemu plikw. Stanowcza wikszo aplikacji faktycznie ignoruje to pole, co z kolei pozwala wykorzysta je w celu ukrycia 32 bitw danych. Dwa kolejne pola bfReserved1 oraz bfReserved2 wedug specyfikacji powinny by wyzerowane, poniewa s zarezerwowane na przyszo. Pki co s jednak niewykorzystywane, wic mog posuy do ukrycia kolejnych 32 bitw danych (oba pola s WORDami, czyli maj po 16 bitw kade). Warto zaznaczy i adna z testowanych przez autora aplikacji nie sprawdzaa czy w w/w polach faktycznie znajduj si zera. Ostatnie pole stanowi kolejn puapk. Pole bfOffBits, bo o nim mowa, jest 32 bitow wartoci bez znaku (DWORD, czyli w terminologii C jest to unsigned int) ktra mwi o tym w ktrym miejscu pliku (a dokadniej, od ktrego bajtu pliku) zaczynaj si faktyczne dane obrazu. Zdarzaj si przypadki w ktrych to pole jest wyzerowane cz aplikacji w tym wypadku uznaje e dane obrazu znajduj si bezporednio za nagwkami. Programista implementujcy obsug BMP moe popeni kilka bdw.

Rysunek 1. Budowa pliku BMP Na pocztek najbardziej trywialny programista z gry zakada e dane obrazu znajduj si za nagwkami i ignoruje pole bfOffBits tak dziao si w przypadku starszych wersji Total Commander (na przykad 6.51, wersje nowsze, na przykad 7.01 nie ignoruj ju tego pola). Pomijajc problemy z wywietlaniem prawidowych bitmap ktre maj dane obrazu odsunite od nagwkw, pozwala to na przykad stworzy plik BMP ktry wywietlany w Total Commanderze bdzie prezentowa inn grafik ni gdyby ten tam plik BMP poda innej, prawidowo obsugujcej pole bfOffBits, aplikacji. Taki wanie efekt zaprezentowany jest na Rysunku 2 (uyte grafiki pochodz z http://icanhascheezburger.com), dla ukazania efektu ten sam plik BMP podano Listerowi (cz Total Commandera odpowiedzialna za podgld plikw) oraz IrfanView 4.10. Naley zaznaczy i plik jest oczywicie dwa razy wikszy ni byby normalnie (poniewa zawiera dwa obrazki). Drugim bdem ktry programista moe popeni jest zaoenie e polu bfOffBits mona zaufa i bdzie ono na pewno mniejsze od wielkoci pliku, a tym bardziej dodatnie (jak pisaem wczeniej jest to DWORD, czyli liczb bez znaku, ale naley pamita e suma dwch liczb 32 bitowych

Tabela 1. Struktura BITMAPFILEHEADER Typ i nazwa pola WORD bfType DWORD bfSize WORD bfReserved1 WORD bfReserved2 DWORD bfOffBits Opis Identyfikator BMP, zazwyczaj litery BM Cakowita wielko pliku Zarezerwowane, zaleca si nadanie wartoci 0 Zarezerwowane, zaleca si nadanie wartoci 0 Pozycja (offset) danych w pliku

www.hakin9.org

hakin9 Nr 2/2008

Atak

jest nadal liczb 32 bitow, czyli nie ma tak na prawd rnicy czy jest to DWORD czy SDWORD jeli nastpi integer overflow ). Tego typu bd, niegrony ale jednak, wystpuje w Microsoft Paint do wersji 5.1 wcznie (czyli tej doczonej do Microsoft Windows XP SP2, wersja 6.0, doczona do Microsoft Windows Vista, zostaa poprawiona). Przykadowe wykorzystanie wida na Rysunku 3, zestawiono na nim aplikacj Microsoft Paint oraz IrfanView, ktre wywietlaj ten sam plik BMP. Jak mona domyli si z rysunku IrfanView postanowi zignorowa bdnie wypenione pole bfOffBits i uzna e dane obrazu znajduj si bezporednio za nagwkami, natomiast mspaint.exe wykona operacje WywietlBitmap(PocztekDanych + bfOffBits), co poskutkowao wywietleniem fragmentu pamici nalecej do aplikacji. Naley doda e w wypadku gdy PocztekDanych + bfOffBits wskazuje na nieistniejcy fragment pamici, zostaje rzucony wyjtek (Naruszenie Ochrony Podczas Odczytu, ang. Read Access Violation), w wypadku mspaint.exe jest on jednak obsugiwany. Naley zauway i jeeli tego typu bd wystpi by w aplikacji posiadajcej w pamici wraliwe dane, to sprawny socjotechnik mg by z powodzeniem wydoby od niewiadomego uytkownika zrzut ekranu na ktrym wida le wywietlan bitmap ktra tak na prawd przedstawiaa by fragment pamici na przykad z hasem i loginem danego uytkownika.

Warto zauway i odsunicie danych od nagwkw stwarza dowoln ilo miejsca na ukrycie ewentualnych dodatkowych danych. Podsumowujc struktur BITMAPFILEHEADER, s tu dwa miejsca w ktrych programista moe popeni bd, a take 64 bity (8 bajtw) w samym nagwku, w ktrych mona zapisa (ukry) dodatkowe dane.

rokoci bitmapy (biWidth), jej wysokoci (biHeight) oraz gbi kolorw, czyli iloci bitw ktre opisuj kady kolejny piksel (biBitCount). Wartoci z tych pl bardzo czsto su do wyliczenia cakowitej iloci bajtw potrzebnej do przechowania bitmapy w pamici. W tym celu implementuje si nastpujce rwnanie:
PotrzebnaIloBajtw = Szeroko * Wysoko * (Gbia / 8)

Nagwek BITMAPINFOHEADER

Drugim z kolei nagwkiem plikw BMP w wersji Windows V3 jest BITMAPINFOHEADER, struktura skadajca si z 11 pl o cznej dugoci 40 bajtw (28h), rozpoczynajca si od offsetu 0Eh. Pierwsze pole biSize okrela wielko niniejszego nagwka, po tej wielkoci aplikacje rozpoznaj czy nagwkiem jest faktycznie BITMAPINFOHEADER, i czy plik BMP jest na pewno wersj Windows V3 formatu BMP. Prawidow wartoci jest oczywicie 40 (28h). Niektre aplikacje, takie jak IrfanView czy Mozilla, przyjmuj e plik BMP jest plikiem w wersji Windows V3 nawet w wypadku gdy biSize posiada jak inn, nieznan, warto daje to moliwo ukrycia kolejnych 32 bitw danych, z tym e nie wszystkie programy bd potrafiy poradzi sobtie z wywietleniem bitmapy w takim wypadku. Drugim, trzecim oraz pitym z kolei polem s kolejno biWidth, biHeight oraz biBitCount. S to, jak nazwa wskazuje, informacje o sze-

W przypadku BMP szeroko, czyli biWidth, w tym rwnaniu zaokrglana jest w gr do najbliszego iloczynu liczby 4 (wicej o tym bdzie w paragrafie Dane obrazu BI _ RGB), czyli jeli bitmapa na przykad ma szeroko 109 pikseli, to w tym rwnaniu zostanie uyta warto 112. Tak wic to rwnanie w przypadku BMP ma nastpujc posta:
PotrzebnaIloBajtw = ZaokrglonaSzeroko * Wysoko * (Gbia / 8)

Tabela 2. Struktura BITMAPINFOHEADER Typ i nazwa pola DWORD biSize LONG biWidth LONG biHeight WORD biPlanes WORD biBitCount DWORD biCompression DWORD biSizeImage LONG biXPelsPerMeter LONG biYPelsPerMeter DWORD biClrUsed DWORD biClrImportant Opis Wielko nagwka, w tym wypadku 28h Szeroko bitmapy Wysoko bitmapy Ilo paszczyzn, przyjto warto 1 Ilo bitw na piksel Rodzaj zastosowanego kodowania/kompresji Wielko nieskompresowanej bitmapy w pamici DPI poziome DPI pionowe Uyta ilo kolorw Ilo wanych kolorw

Tak wyliczona warto uywana jest zazwyczaj do alokacji pamici na potrzeby docelowej bitmapy. Jest to jednoczenie miejsce, w ktrym istnieje prawdopodobiestwo bdnej implementacji. Zamy na chwil e programista zaoy e PotrzebnaIloBajtw jest wartoci typu LONG lub DWORD (32 bity), a tak si czsto zdarza. Jeeli wynik rwnania bdzie wikszy od FFFFFFFFh, czyli maksymalnej liczby ktr mona zapisa w 32 bitowej zmiennej typu cakowitego/naturalnego, to nastpi przepenienie zmiennej cakowitej (ang. Integer Overflow ), co z kolei moe doprowadzi do bdu typu przepenienia bufora. Wemy pod uwag kod z Listingu 2. Programista zaokrgla szeroko po czym wylicza potrzebn ilo bajtw, a nastpnie alokuje pami i wczytuje wiersz po wierszu ca bitmap do zaalokowanej pamici. Wszystko wydaje si by w porzdku, ale zamy na chwil e otrzymalimy bitmap o wielkoci 65536x65536x8, czyli szeroko i wysoko maj warto 10000h. Po podstawieniu wartoci w rwna-

hakin9 Nr 2/2008

www.hakin9.org

Format BMP okiem hakera

niu na potrzebn ilo bajtw otrzymamy 10000h * 10000h * (8/8), czyli 100000000h. DWORD pomieci moe jedynie najmodsze 32 bity tej liczby, w zwizku z czym w zmiennej size zapisane zostanie 00000000h, czyli 0. Nastpnie dojdzie do alokacji pamici, ktra zakoczy si sukcesem (przykadowo system Windows zaalokuje 16 bajtw, mimo ze malloc dosta 0 w parametrze), a potem zostanie w to miejsce wczytane 65536 wierszy po 65536 pikseli kady, czyli 4 GB danych, co spowoduje przepenienie bufora oraz wyrzucenie wyjtku (ang. Write Access Violation). W przypadku gdy wyjtek zostanie obsuony prawdopodobnie bdzie rwnie moliwo wykonania kodu, a w wypadku gdy nie zostanie obsuony, aplikacja po prostu zakoczy dziaanie z odpowiednim komunikacje o bdzie. Czwartym z kolei polem, pominitym wczeniej, jest biPlanes, ktre mwi o iloci paszczyzn. Przyjte jest e w tym polu powinna by warto 1. Niektre programy ignoruj warto tego pola, przez co moliwe jest ukrycie kolejnych 16 bitw danych. Kolejnym, szstym polem jest biCompression field. To pole przyjmuje pewne z gry ustalone wartoci ktre mwi o sposobie kodowania i kompresji uytej w przypadku danego pliku BMP. Dostpne wartoci w BMP Windows V3 to BI _ RGB (0), BI _ RLE8 (1) , BI _ RLE4 (2) oraz BI _ BITFIELDS (3). Kolejne wersje formatu BMP zakadaj rwnie dwie inne wartoci: BI _ JPEG (4) oraz BI _ PNG (5). Rne rodzaje kodowanie BMP s omwione w kolejnych podpunktach. Nastpnym polem jest biSizeImage okrelajce cakowit wielko bitmapy po ewentualnej dekompresji (jeeli bitmapa nie jest kompresowana, to pole moe by ustawione na 0). Tabela 3. Struktura RGBQUAD Typ i nazwa pola BYTE rgbBlue BYTE rgbGreen BYTE rgbRed BYTE rgbReserved

Listing 1. Niebezpieczny kod wczytujcy bitmap


void *ReadBMPtoMemory(const char *name, unsigned int *size) { char *data = NULL; BITMAPFILEHEADER bmfh; FILE *f = NULL; size_t ret = 0; /* Otwrz plik */ f = fopen(name, rb); if(!f) return NULL; /* Wczytaj naglowek i zaalokuj pami */ fread(&bmfh, 1, sizeof(bmfh)); *size = bmfh.bfSize; data = malloc(bmfh.bfSize); if(!data) goto err; memset(data, 0, bmfh.bfSize); /* Wczytaj plik */ fseek(f, 0, SEEK_SET); do { ret += fread(data + ret, 1, 0x1000, f); } while(!feof(f)); /* Powrt */ fclose(f); return data; /* Obsluga bledow */ err: if(f) fclose(f); if(data) free(data); return NULL; }

W przypadku tego pola puapka wyglda bardzo podobnie jak w przypadku pola bfSize z BITMAPFILEHEADER, zaleca si wic zignorowanie wartoci tego pola. Nieostrone uycie wartoci biSizeImage przy alokacji pamici, a nastpnie brak kontroli pozycji wskanika zapisu przy dekompresji moe prowadzi do przepenienia bufora. Dwa kolejne pola biXPelsPerMeter oraz biYPelsPerMeter mwi o poziomej i pionowej iloci pikseli przypadajcych na metr (informacja analogiczna do DPI, ang. Dots Per Inch). Informacje te s potrzebne gwnie w przypadku drukowania danej bitmapy. Pojawia si tutaj pewna groba w przypadku implementacji drukowania bitmap rozdzielczo ta moe przyOpis Warto barwy niebieskiej Warto barwy zielonej Warto barwy czerwonej Zarezerwowane

j bardzo ma warto (na przykad 1), i wtedy nawet maa bitmapa moe zaj kilkanacie kartek A4, lub bardzo du warto, przez co caa bitmapa bdzie wielkoci milimetr na milimetr. To pole moe zosta wykorzystane rwnie do przechowania pewnej informacji (64 bity cznie), szczeglnie jeli nie zaley nam na poprawnoci rozdzielczoci drukowanej. Przedostatnim polem jest biClrUsed ktre mwi o iloci kolorw w palecie barw. Jeeli to pole jest wyzerowane, przyjmuje si e ilo kolorw w palecie jest rwna liczbie 2 podniesionej do potgi biBitCount (do 8 bitw wcznie), czyli na przykad w przypadku 8-bitowej bitmapy przyjmuje si e paleta ma 256 kolorw. Co ciekawe, programici maj tendencje ufa temu polu i zakada e jeeli biClrUser wynosi na przykad 1, to w bitmapie pojawi si jedynie pierwszy z kolei kolor, czyli 00. Jeeli w bitmapie pojawi si wicej kolorw prawidowym dziaaniem powinno by albo wywietlanie pozostaych kolorw jako czarny (czyli wyzerowanie pozo-

www.hakin9.org

hakin9 Nr 2/2008

Atak

staej czci palety), albo wykonanie operacji modulo (wywietlony _ kolor = kolor % biClrUsed). Tak zachowuj si MSPaint, Internet Explorer, czy Paint Shop Pro. Bardzo duo programw jednak rysuje bitmap na swj wasny sposb, czego przykad jest przedstawiony na Rysunku 4. W tym miejscu naleao by si zainteresowa czemu tak si dzieje, oraz skd si bior pozostae kolory poniewa w palecie w pliku BMP zadeklarowany zosta tylko jeden. Odpowied na to drugie pytanie jest do prosta najwyraniej programy alokuj pami na pen palet kolorw (256 kolorw), po czym wczytuj z pliku ca tam zawart palet (1 kolor). Reszta palety, jako e nie bya wyzerowana, zawiera w takim przypadku dane ktre znajdoway si wczeniej w pamici, a konkretniej na stogu (ang. heap). Drug moliwa odpowied jest taka e program alokuje palet o wielkoci biClrUsed, a kolory powyej biClrUsed po prostu korzystaj z pamici po za palet tak jak by to by dalszy cig palety (tzw. boundary condition error). W obu przypadkach kolory ktre wedug pola biClrUsed nie powinny by uywane, s opisane przez dane znajdujce si w pamici. Idc o krok dalej, mona stworzy BMP o wielkoci 256x1 w ktrej dane obrazu bd kolejnymi kolorami, od 00 do FFh, dziki temu wywietlona bitmapa bdzie praktycznie rzecz biorc skopiowan palet kolorw, czyli na ekranie pojawi si, w postaci kolorowych pikseli, dane z pamici. Czy jednak mona w jaki sposb przesa automatycznie przesa t bitmap do jakiego zdalnego serwera? Okazuje si e w przypadku Firefox 2.0.0.11 oraz Opera 9.50 beta jest to moliwe. Obie

Rysunek 2. Wykorzystanie ignorowania pola bfOffBits te przegldarki obsuguj wprowadzony w HTML 5 tag <canvas>, ktry umoliwia rysowanie po ptnie, kopiowanie bitmap z tagw <img> na ptno, oraz odczyt wartoci kolorw z ptna. Moliwe jest wic stworzenie skryptu ktry wywietli odpowiednio spreparowany plik BMP a nastpnie skopiuje go na canvas, odczyta wartoci kolorw i przele je na zdalny serwer. Wg. bada przeprowadzonych przez autora dane przesyane na zdalny serwer mog zawiera fragmenty innych stron, fragmenty ulubionych, fragmenty historii oraz inne informacje. W momencie pisania tego artykuu powysza, znaleziona przez autora, luka, klasyfikowana jako Remote Information Disclosure, nie zostaa jeszcze poprawiona. Ostatnim polem tego nagwka jest biClrImportant mwice o iloci istotnych kolorw w bitmapie. Stanowcza wikszo aplikacji ignoruje jednak to pole, dziki czemu moe ono zosta uyte do przechowania 32 bitw danych niezwizanych z bitmap. Podsumowujc, w nagwku BITMAPINFOHEADER znajduje si wiele pl ktre nieuwany programista moe potraktowa ze zbytnim zaufaniem naraajc tym samym uytkownika na wyciek informacji a nawet wykonanie kodu. Dodatkowo w tym nagwku mona ukry kolejne bajty informacji dodatkowych, niezwizanych z bitmap.

Paleta barw

Paleta barw jest tablic struktur RGBQUAD (patrz Tabela 3) ktre opisuj warto barw, kolejno niebieskiej, zielonej i czerwonej, danego koloru. Dodatkowo kada struktura dopeniona jest jedno bajtowym polem rgbReserved, dziki czemu caa struktura ma wielko 32 bitw (4 bajtw). Standard nakazuje aby to ostatnie pole byo wyzerowane, jednak w rzeczywistoci aplikacje nie sprawdzaj tego. To pole moe zosta uyte do ukrycia dodatkowych informacji, lub do zapisania kanau alfa (w przypadku bitmap 32 bitowych). Paleta barw wystpuje w przypadku bitmap 1 (1 bitowa bitmapa wcale nie musi by czarno-biaa!), 4 oraz 8 bitowych (patrz pole biBitCount z BITMAPINFOHEADER ). W przypadku tych bitmap, jeli pole biClrUsed nie mwi inaczej, paleta zawiera kolejno 2, 16 lub 256 struktur RGBQUAD.

Dane obrazu BI_RGB

Listing 2. Niebezpieczny kod alokujcy pami i wczytujcy dane


/* Wylicz szerokosc i wielkosc */ DWORD padded_width = (bmih.biWidth + 3) & (~3); DWORD size = padded_width * bmih.biHeight * (bmih.biBitCount / 8); /* Alokacja pamieci */ char *data = malloc(size), *p; if(!data) goto err; /* Wczytaj dane */ fseek(f, bmfh.biOffBits, SEEK_SET); for(p = data, y = 0; y < bmih.biHeight; y++, p += padded_width) fread(p, 1, padded_width, f);

Dane obrazu w przypadku BI_RGB naley rozwaa w dwch kategoriach faktycznych kolorw RGB (bitmapa 24 bitowa), oraz numerw kolorw w palecie barw (1 bitowe, 4 bitowe lub 8 bitowe bitmapy). Niemniej jednak kilka rzeczy jest wsplne. Pierwsz z nich jest zapis bitmapy do gry nogami, czyli pierwsze w pliku znajduj si wiersze ktre trafi na d bitmapy, a kolejne zawieraj informacje o wierszach znajdujcych si co-

hakin9 Nr 2/2008

www.hakin9.org

Format BMP okiem hakera

raz wyej w faktycznym obrazie. Drug rzecz jest wspomniane wczeniej dopenianie iloci danych (bajtw) w wierszy do iloczynu liczby 4. W przypadku kiedy iloczyn szerokoci i iloci bajtw przypadajcych na piksel nie jest podzielny przez 4, na koniec danych wiersza dopisywana jest odpowiednia ilo (od 1 do 3) bajtw zerowych, tak aby cakowita ilo danych opisujcych wiersz bya iloczynem liczby 4. Jak si atwo domyli adna aplikacja nie sprawdza czy w dopenieniu zostay uyte zera, mona wic wykorzysta dopenienie do ukrycia wasnych danych. Korzystajc z tego sposobu mona ukry, w zalenoci od szerokoci wiersza, od 1 do 3 bajty na wiersz razy wysoko bitmapy. W przypadku 24-bitowej bitmapy i BI _ RGB kolejne bajty zawieraj, podobnie jak w palecie barw, warto barwy niebieskiej, zielonej oraz czerwonej kadego piksela (po 3 bajty na piksel). Przykadowo, 00 00 00 zostanie wywietlone na ekranie na kolor czarny, a 00 FF 00 na kolor zielony. Popularn metod steganograficzn jest uycie najmniej znaczcego bitu kadej barwy w kadym pikselu do przechowania ukrytych informacji. W przypadku 8-bitowej bitmapy kolejne bajty zawieraj numery kolorw z palety kolorw, a podczas przenoszenia bitmapy na 24-bitowy ekran kady piksel jest zamieniany z numeru koloru na wartoci poszczeglnych barw pobrane z palety kolo-

rw. W przypadku 8-bitowej bitmapy w wypadku gdy nie wszystkie kolory s uywane (lub w wypadku bitmap 1-bitowych i 4-bitowych skonwertowanych do 8-bitowej bitmapy) mona ukry dodatkowe informacje bez zmiany wygldu bitmapy poprzez powielenie czci palety kolorw i stosowanie zamiennie kolorw z czci oryginalnej (0) lub powielonej (1). W przypadku 4-bitowych bitmap (czyli 16-kolorowych) skonwertowanych do 8-bitowych palet kolorw mona powieli 16 razy (256/16 = 16), dziki czemu na dobr spraw najbardziej znaczce 4 bity kadego bajtu mog zawiera dowolne ukryte dane.

Dane obrazu BI_RLE8

Ostatni poruszan w tym artykule kwesti dotyczc BMP jest kodowanie RLE 8-bitowych bitmap. RLE (ang. Run Length Encoding) jest bardzo prost metod kompresji polegajc na zapisie danych w postaci pary ilo wystpie oraz znak. Przykadowo cig AAAABBB za pomoc RLE zosta by skompresowany do 4A3B. W przypadku BMP za rwno ilo wystpie oraz znak maj wielkoci jednego bajtu (czyli razem 16 bitw). Oprcz tego BMP RLE posiada rwnie specjalne znaczniki zaczynajce si od bajtu zerowego (czyli ilo wystpie wynosi zero), s to: 00 00 Przejcie na pocztek nastpnego wiersza bitmapy (czyli kolejne dane opisuj nowy wiersz, przyjmuje si e do koca obecnego wiersza dane maj kolor 0).

Wikszo aplikacji oczekuje e kady wiersz bdzie zakoczony 00 00, ale istniej rwnie takie (IrfanView) u ktrych jest to niekonieczne. 00 01 Zakoczenie bitmapy. Jeeli pozostay jakie niezapisane piksele, nadaje si im kolor 0. 00 02 XX YY Ten znacznik skada si z czterech bajtw. Dwa dodatkowe bajty zawieraj liczb kolumn oraz wierszy o jak wskanik zapisu naley przesun (czyli mwi o tym ile pikseli i wierszy dalej znajduj si nastpne dane). Wszystkie pominite piksele przyjmuje si e maj kolor 0. 00 NN ... (gdzie NN >= 3 ) Jest to znacznik przeczajcy dekompresje w tzw. tryb bezwzgldny. Zaraz po nim nastpuj bajty ktre nie s zakodowane RLE, a po prostu przepisane z kompresowanej bitmapy o iloci tych bajtw mwi drugi bajt znacznika (oznaczony jako NN ). Bajty nastpujce po znaczniku powinny zosta po prostu przepisane na rozpakowan bitmap. W przypadku gdy liczba NN jest nieparzysta, naley nastpujce bajty dopeni jednym bajtem zerowym, w celu uzyskania parzystej liczby bajtw. Oczywicie adna aplikacja nie sprawdza czy jest to bajt zerowy, mona wic zapeni do ukrytymi informacjami. Tak skonstruowana kompresja RLE stawia wiele puapek przed programist, i jednoczenie stwarza wiele miejsc na ukrycie danych. Przykadowo osoba chcca ukry dane moe posuy si rnymi sposobami skompresowania tej samej bit-

Rysunek 4. Ta sama bitmapa rnie rysowana w rnych programach

Rysunek 3. Brak kontroli wartoci pola bfOffBits w mspaint.exe

www.hakin9.org

hakin9 Nr 2/2008

Atak

mapy uywajc rnych znacznikw. Przykadowo bitmapa skadajca si z kolorw AABBBCC moe zosta zapisana jako 02 A 03 B 02 C, lub jako 01 A 01 A 02 B 01 B 01 C 01 C, lub nawet korzystajc ze specjalnych znacznikw jako 00 03 A A B 00 00 02 00 00 01 B 02 C. Pomijajc sprawy skutecznoci kompresji, liczba moliwoci w jaki sposb mona zapisa tak bitmap jest nieskoczona (choby dlatego e znacznik 00 02 00 00 mona wstawia bezkarnie dowoln ilo razy) mona wic stworzy pewnego rodzaju kod dziki ktremu mona by przechowywa informacje w bitmapie, bez zmiany jej faktycznego wygldu. Jeeli za chodzi o puapki, to pierwsz rzucajc si w oczy jest przepenienie bufora w przypadku gdy programista nie sprawdzi czy dekompresja pojedynczej pary RLE nie przepeni bufora. atwo wyobrazi sobie przypadek w ktrym bitmapa o wielkoci 1x1 zawiera w danych obrazu znacznik FF 00 (czyli 255 razy bajt 0). W przypadku braku kontroli czy wskanik dekompresji nie wyjdzie po za bufor, takie co moe spowodowa w najlepszym wypadku wyjtek, a w najgorszym wykonanie kodu. Analogiczna puapka wystpuje w przypadku znacznika wczajcego tryb bezwzgldny. Zapis 00 FF <shellcode> 00 w danych bitmapy moe doprowadzi do faktycznego wykonania kodu (prawdopodobnie bdzie to trudne, ale jednak moliwe). Powysze puapki s jednak bardzo oczywiste, i mao ktry programista w nie wpada. Troszeczk mniej oczywist puapk jest znacznik 00 02 XX YY sucy do przesuwania do przodu znacznika zapisu dekompresowanych danych. Ivan Fratric 6 kwietnia roku 2007 opublikowa informacje na temat wykorzystania tagu 00 02 XX YY do wykonania kodu w ACDSee oraz IrfanView. Problem polega na tym i programici w obu przypadkach nie sprawdzali czy wskanik zapisu po wykonaniu znacznika 00 02 XX YY nie opuci bufora bitmapy. Moliwe zatem stao si nakierowanie wskanika zapisu na dowolny fragment pamici, i na-

O autorze

Micha Skadnikiewicz, inynier informatyki, ma wieloletnie dowiadczenie jako programista oraz reverse engineer. Obecnie jest koordynatorem dziau analiz w midzynarodowej firmie specjalizujcej si w bezpieczestwie komputerowym. Kontakt z autorem: gynvael@coldwind.pl

stpnie nadpisanie go dowolnymi danymi. W przypadku IrfanView, ktry w tej wersji spakowany by ASPackiem, sytuacj dodatkowo pogarsza fakt i sekcja .text (w ktrej znajduje si kod programu, patrz pliki PE) miaa prawa do zapisu, czyli atakujcy mg przesun wskanik zapisu za pomoc serii 00 02 FF FF na sekcje .text, a nastpnie nadpisa znajdujcy si tam kod wasnym kodem na przykad uruchamiajcym backdoora. Nowsze wersje IrfanView (od 4.00 wcznie) nie s jednak ju podatne na ten bd. Pewien mniej grony bd, ale mogcy utrudni ycie uytkownikowi, znalaz autor (wsppracujc z hakerem o pseudonimie Simey) w przegldarce Opera (9.24 oraz 9.50 beta). Programici Opery popenili bd podczas implementowania tagu 00 02 XX YY ktry powodowa i obsuga tego znacznika bya niewiarygodnie wolna. Dziki temu stao si moliwe stworzenie bitmapy ktrej przetwarzanie w Operze trwa 4 minuty na bardzo szybkim komputerze, a 20 minut na rednim w tym czasie Opera nie reaguje na adne bodce zewntrzne. Atakujcy mgby stworzy stron WWW zawierajc setki takich bitmap, przez co przegldarka niewiadomego uytkownika moga by odmwi posuszestwa na dugie godziny. Podsumowujc, kodowanie RLE stwarza wiele moliwoci ataku oraz ukrycia informacji. Naley zachowa szczegln ostrono implementujc obsug RLE w formacie BMP.

dynie w czci ze standardem mog przysporzy sporo problemw. Wdajc si w szczegy techniczne, programista powinien zwraca uwag szczeglnie na sprawdzenia granic uywanych buforw i tablic buforu obrazu, buforu skompresowanych danych, czy palety kolorw. Granice, co nie dla wszystkich jest oczywiste, powinny by sprawdzane z obu stron, aby zapobiec zarwno bdom typu buffer overflow , jak i bdom typu buffer underflow . Programista powinien rwnie uywa odpowiedniego rozmiaru zmiennych, lub stosownego ograniczania wartoci, aby zapobiec sytuacjom z przepenieniem zmiennej cakowitej (ang. integer overflow ) warto w tym wypadku zwrci uwag szczeglnie na rwnanie obliczajce wielko bitmapy. Czytajc standard naley myle nie tylko o tym, jak go zaimplementowa, ale rwnie jak zabezpieczy przed nieprawidowym uyciem kadej pojedynczej cechy formatu, co moe si sta, gdyby ktre pole nagwka przyjo nieprawidow (z logicznego punktu widzenia) warto, oraz jakie mog by tego konsekwencje. Naley pamita, i programista musi zabezpieczy wszystko, poniewa atakujcy musi znale tylko jeden bd.

Podsumowanie

Bezpieczna implementacja

Programista powinien pamita, i zgodno ze standardem zapewnia bezpieczn obsug jedynie poprawnych bitmap faktycznie zgodnych ze standardem pliki BMP zgodne je-

Format BMP, mimo swojej pozornej prostoty (w porwnaniu do np. PNG czy JPEG) jest najeony puapkami, miejscami gdzie mona popeni choby drobny bd, oraz zawiera wiele miejsc w ktrych mona ukry dodatkowe dane, bez wpywania na wywietlan bitmap. Jako zadanie domowe pozostawiam czytelnikowi analiz zapisu danych obrazu metod BI_BITFIELD, oraz analiz pozostaych wersji formatu BMP. l

hakin9 Nr 2/2008

www.hakin9.org

You might also like