Format BMP okiem hakera.pdf

(722 KB) Pobierz
171785861 UNPDF
Format BMP okiem hakera
Atak
Michał Gynvael Coldwind Składnikiewicz
stopień trudności
Pliki graiczne są dziś szeroko rozpowszechnionym nośnikiem
informacji, spotyka się je praktycznie na każdym komputerze.
Dobry programista powinien wiedzieć jak wyglądają nagłówki
poszczególnych formatów plików graicznych, i jak są
przechowywany jest sam obraz. A jak to zwykle bywa, diabeł tkwi
w szczegółach.
czytelnika z formatem przechowywa-
nia obrazu BMP, wskazać w nich miej-
sca które można wykorzystać do przemycenia
ukrytych danych, miejsca w których programi-
sta może popełnić błąd podczas implementacji
oraz zapoznać ze samym formatem. Przykła-
dy będą w miarę możliwości zilustrowane pew-
nymi bugami w istniejącym oprogramowaniu,
znalezionymi przez autora oraz inne osoby.
niezależnie od wersji) która zawiera m.in. iden-
tyikator pliku – tzw. liczbę magiczną (ang. ma-
gic number ), oraz offset na którym znajdują się
dane bitmapy. Bezpośrednio po BITMAPFILE-
HEADER , na offsecie 0Eh , znajduje się struktu-
ra BITMAPINFOHEADER (dodam że deklara-
cje omawianych struktur można znaleźć w pliku
wingdi.h w Platform SDK), która zawiera infor-
macje o obrazie, jego rozdzielczości, głębi kolo-
rów czy użytej metody kodowania/kompresji. W
przypadku bitmap o głębi 4 lub 8 bitów, zaraz za
strukturą BITMAPINFOHEADER znajduje się
Wstęp do BMP
Niesławny format BMP znany jest przede
wszystkim z plików o ogromnych wielkościach
(w porównaniu do JPEG czy PNG ). Format ten
stworzony został przez irmy IBM oraz Microsoft
na potrzeby systemów OS/2 oraz Windows, obie
irmy rozwijały go jednak oddzielnie, co spowo-
dowało powstanie kilku wariantów tego formatu.
Niniejszy tekst skupia się na BMP w wersji Win-
dows V3, pozostałe wersje (OS/2 V1 i V2 oraz
Windows V4 i V5) pozostawiam czytelnikowi do
własnej analizy jako zadanie domowe :).
Niezależnie od wersji, ogólna budowa pli-
ku, przedstawiona na Rysunku 1, pozostaje ta-
ka sama. Na samym początku pliku znajduje się
struktura BITMAPFILEHEADER (jest ona stała,
Z artykułu dowiesz się
• jak zbudowany jest plik BMP,
• na co uważać podczas implementowania ob-
sługi formatu BMP,
• gdzie szukać błędów w aplikacjach korzystają-
cych z BMP .
Co powinieneś wiedzieć
• mieć ogólne pojęcie na temat plików binarnych,
• mieć ogólne pojęcie na temat bitmap.
2
hakin9 Nr 3/2008
www.hakin9.org
N iniejszy artykuł ma na celu zapoznać
171785861.022.png 171785861.023.png 171785861.024.png 171785861.025.png
Format BMP okiem hakera
paleta barw, którą jest odpowiedniej
wielkości tablica struktur RGBQUAD .
W przypadku bitmap o głębi kolorów
16 bitów zamiast palety barw w tym
miejscu znajduję się prosta struktura
składająca się z trzech DWORD'ów
które są maskami bitowymi określa-
jącymi które bity w danych obrazu od-
powiadają za barwę, kolejno, czerwo-
ną, zieloną oraz niebieską, natomiast
w bitmapach, o głębi 24 bity lub więk-
szejm paleta barw nie występuje. Da-
ne obrazu zaczynają się na offsecie
podanym w BITMAPFILEHEADER ,
zazwyczaj od razu po ostatnim na-
główku. Budowa danych zależy za
równo od użytego kodowania jak i
głębi kolorów.
Tak przedstawia się ogólna budo-
wa formatu BMP. Szczegółowa budo-
wa formatu BMP przedstawiona jest
w dalszej części artykułu.
ile wg. bfSize jest potrzebne, po czym
wczytał cały plik (aż do końca) do za-
alokowanego bufora. Funkcja działa
wyśmienicie, pod warunkiem że war-
tość bfSize jest równa lub większa od
faktycznej wielkości pliku. Jeśli war-
tość bfSize będzie mniejsza, dojdzie
do klasycznego błędu przepełnienia
bufora – który wprawny włamywacz
mógł by wykorzystać do wykonania
własnego kodu. Dobrym pomysłem
jest zignorowanie wartości tego pola,
i korzystanie jedynie z wielkości pliku
otrzymanej od systemu plików. Sta-
nowcza większość aplikacji faktycz-
nie ignoruje to pole, co z kolei pozwa-
la wykorzystać je w celu ukrycia 32
bitów danych.
Dwa kolejne pola – bfReserved1
oraz bfReserved2 – według specyi-
kacji powinny być wyzerowane, po-
nieważ są zarezerwowane na przy-
szłość. Póki co są jednak niewyko-
rzystywane, więc mogą posłużyć do
ukrycia kolejnych 32 bitów danych
(oba pola są WORDami, czyli mają
po 16 bitów każde). Warto zaznaczyć
iż żadna z testowanych przez auto-
ra aplikacji nie sprawdzała czy w w/w
polach faktycznie znajdują się zera.
Ostatnie pole stanowi kolejną pu-
łapkę. Pole bfOffBits , bo o nim mowa,
jest 32 bitową wartością bez znaku
(DWORD, czyli w terminologii C jest
to unsigned int ) która mówi o tym w
którym miejscu pliku (a dokładniej,
od którego bajtu pliku) zaczynają się
faktyczne dane obrazu. Zdarzają się
przypadki w których to pole jest wy-
zerowane – część aplikacji w tym wy-
padku uznaje że dane obrazu znajdu-
ją się bezpośrednio za nagłówkami.
Programista implementujący obsłu-
gę BMP może popełnić kilka błędów.
Rysunek 1. Budowa pliku BMP
Nagłówek
BITMAPFILEHEADER
Nagłówek BITMAPFILEHEADER
(patrz Tabela 1) rozpoczyna się na
początku pliku ( offset 0 ) i ma wielkość
14 bajtów ( 0Eh ). Najmniej interesują-
cym polem struktury jest pierwsze po-
le – bfType , które zawsze ma wartość
odpowiadającą ciągowi ASCII BM .
Kolejnym polem jest DWORD bfSi-
ze w którym wg. specyikacji powinna
znaleźć się całkowita wielkość pliku w
bajtach. Wielkość pliku prawidłowego
pliku łatwo obliczyć dodając wielko-
ści poszczególnych nagłówków, pale-
ty barw oraz danych obrazu. To pole
stanowi pierwszą pułapkę, ale w nią
wpadają jedynie nieuważni programi-
ści. Rozważmy kod z Listingu 1 – pro-
gramista wczytał nagłówek, zaufał
polu bfSize i zaalokował tyle pamięci
Na początek najbardziej trywialny
– programista z góry zakłada że da-
ne obrazu znajdują się za nagłówka-
mi i ignoruje pole bfOffBits – tak dzia-
ło się w przypadku starszych wersji
Total Commander (na przykład 6.51,
wersje nowsze, na przykład 7.01 nie
ignorują już tego pola). Pomijając pro-
blemy z wyświetlaniem prawidłowych
bitmap które mają dane obrazu odsu-
nięte od nagłówków, pozwala to na
przykład stworzyć plik BMP który wy-
świetlany w Total Commanderze bę-
dzie prezentował inną graikę niż gdy-
by ten tam plik BMP podać innej, pra-
widłowo obsługującej pole bfOffBits ,
aplikacji. Taki właśnie efekt zapre-
zentowany jest na Rysunku 2 (użyte
graiki pochodzą z http://icanhasche-
ezburger.com ), dla ukazania efektu
ten sam plik BMP podano Listerowi
(część Total Commandera odpowie-
dzialna za podgląd plików) oraz Irfa-
nView 4.10. Należy zaznaczyć iż plik
jest oczywiście dwa razy większy niż
byłby normalnie (ponieważ zawiera
dwa obrazki).
Drugim błędem który programi-
sta może popełnić jest założenie że
polu bfOffBits można zaufać i będzie
ono na pewno mniejsze od wielkości
pliku, a tym bardziej dodatnie (jak pi-
sałem wcześniej jest to DWORD, czy-
li liczbą bez znaku, ale należy pamię-
tać że suma dwóch liczb 32 bitowych
Tabela 1. Struktura BITMAPFILEHEADER
Typ i nazwa pola
Opis
WORD bfType
Identyikator BMP, zazwyczaj lite-
ry „BM”
DWORD bfSize
Całkowita wielkość pliku
WORD bfReserved1
Zarezerwowane, zaleca się nadanie
wartości 0
WORD bfReserved2
Zarezerwowane, zaleca się nadanie
wartości 0
DWORD bfOffBits
Pozycja (offset) danych w pliku
www.hakin9.org
hakin9 Nr 2/2008
3
 
171785861.001.png 171785861.002.png 171785861.003.png
 
Atak
jest nadal liczbą 32 bitową, czyli nie
ma tak na prawdę różnicy czy jest to
DWORD czy SDWORD jeśli nastą-
pi integer overlow ). Tego typu błąd,
niegroźny – ale jednak, występuje w
Microsoft Paint do wersji 5.1 włącznie
(czyli tej dołączonej do Microsoft Win-
dows XP SP2, wersja 6.0, dołączo-
na do Microsoft Windows Vista, zo-
stała poprawiona). Przykładowe wy-
korzystanie widać na Rysunku 3, ze-
stawiono na nim aplikację Microsoft
Paint oraz IrfanView, które wyświetla-
ją ten sam plik BMP . Jak można do-
myślić się z rysunku IrfanView posta-
nowił zignorować błędnie wypełnione
pole bfOffBits i uznał że dane obrazu
znajdują się bezpośrednio za nagłów-
kami, natomiast mspaint.exe wykonał
operacje WyświetlBitmapę (Początek-
Danych + bfOffBits ), co poskutkowa-
ło wyświetleniem fragmentu pamięci
należącej do aplikacji. Należy dodać
że w wypadku gdy PoczątekDanych
+ bfOffBits wskazuje na nieistnieją-
cy fragment pamięci, zostaje rzuco-
ny wyjątek (Naruszenie Ochrony Pod-
czas Odczytu, ang. Read Access Vio-
lation ), w wypadku mspaint.exe jest
on jednak obsługiwany. Należy za-
uważyć iż jeżeli tego typu błąd wystą-
pił by w aplikacji posiadającej w pa-
mięci wrażliwe dane, to sprawny so-
cjotechnik mógł by z powodzeniem
wydobyć od nieświadomego użyt-
kownika zrzut ekranu na którym wi-
dać źle wyświetlaną bitmapę która tak
na prawdę przedstawiała by fragment
pamięci na przykład z hasłem i logi-
nem danego użytkownika.
Warto zauważyć iż odsunięcie
danych od nagłówków stwarza do-
wolną ilość miejsca na ukrycie ewen-
tualnych dodatkowych danych.
Podsumowując strukturę BIT-
MAPFILEHEADER , są tu dwa miej-
sca w których programista może po-
pełnić błąd, a także 64 bity (8 bajtów)
w samym nagłówku, w których moż-
na zapisać (ukryć) dodatkowe dane.
rokości bitmapy ( biWidth ), jej wyso-
kości ( biHeight ) oraz głębi kolorów,
czyli ilości bitów które opisują każ-
dy kolejny piksel ( biBitCount ). War-
tości z tych pól bardzo często służą
do wyliczenia całkowitej ilości bajtów
potrzebnej do przechowania bitmapy
w pamięci. W tym celu implementuje
się następujące równanie:
Nagłówek
BITMAPINFOHEADER
Drugim z kolei nagłówkiem plików
BMP w wersji Windows V3 jest BIT-
MAPINFOHEADER, struktura skła-
dająca się z 11 pól o łącznej długości
40 bajtów (28h), rozpoczynająca się
od offsetu 0Eh .
Pierwsze pole – biSize – określa
wielkość niniejszego nagłówka, po
tej wielkości aplikacje rozpoznają czy
nagłówkiem jest faktycznie BITMA-
PINFOHEADER , i czy plik BMP jest
na pewno wersją Windows V3 forma-
tu BMP . Prawidłową wartością jest
oczywiście 40 (28h). Niektóre apli-
kacje, takie jak IrfanView czy Mozilla,
przyjmują że plik BMP jest plikiem w
wersji Windows V3 nawet w wypad-
ku gdy biSize posiada jakąś inną, nie-
znaną, wartość – daje to możliwość
ukrycia kolejnych 32 bitów danych, z
tym że nie wszystkie programy będą
potraiły poradzić sobtie z wyświetle-
niem bitmapy w takim wypadku.
Drugim, trzecim oraz piątym z
kolei polem są kolejno biWidth , bi-
Height oraz biBitCount . Są to, jak
nazwa wskazuje, informacje o sze-
PotrzebnaIlośćBajtów =
Szerokość * Wysokość * (Głębia / 8)
W przypadku BMP szerokość, czyli
biWidth, w tym równaniu zaokrągla-
na jest w górę do najbliższego iloczy-
nu liczby 4 (więcej o tym będzie w pa-
ragraie Dane obrazu – BI _ RGB ), czy-
li jeśli bitmapa na przykład ma szero-
kość 109 pikseli, to w tym równaniu
zostanie użyta wartość 112. Tak więc
to równanie w przypadku BMP ma
następującą postać:
PotrzebnaIlośćBajtów =
ZaokrąglonaSzerokość *
Wysokość * (Głębia / 8)
Tak wyliczona wartość używana jest
zazwyczaj do alokacji pamięci na po-
trzeby docelowej bitmapy. Jest to jed-
nocześnie miejsce, w którym istnie-
je prawdopodobieństwo błędnej im-
plementacji. Załóżmy na chwilę że
programista założył że PotrzebnaIlo-
śćBajtów jest wartością typu LONG
lub DWORD (32 bity), a tak się czę-
sto zdarza. Jeżeli wynik równania bę-
dzie większy od FFFFFFFFh, czy-
li maksymalnej liczby którą można
zapisać w 32 bitowej zmiennej typu
całkowitego/naturalnego, to nastą-
pi przepełnienie zmiennej całkowi-
tej (ang. Integer Overlow ), co z ko-
lei może doprowadzić do błędu ty-
pu przepełnienia bufora. Weźmy pod
uwagę kod z Listingu 2. Programista
zaokrągla szerokość po czym wyli-
cza potrzebną ilość bajtów, a następ-
nie alokuje pamięć i wczytuje wiersz
po wierszu całą bitmapę do zaaloko-
wanej pamięci. Wszystko wydaje się
być w porządku, ale załóżmy na chwi-
lę że otrzymaliśmy bitmapę o wielko-
ści 65536x65536x8 , czyli szerokość
i wysokość mają wartość 10000h .
Po podstawieniu wartości w równa-
Tabela 2. Struktura BITMAPINFOHEADER
Typ i nazwa pola Opis
DWORD biSize Wielkość nagłówka, w tym wypadku 28h
LONG biWidth Szerokość bitmapy
LONG biHeight Wysokość bitmapy
WORD biPlanes Ilość płaszczyzn, przyjęto wartość 1
WORD biBitCount Ilość bitów na piksel
DWORD biCompression Rodzaj zastosowanego kodowania/kompresji
DWORD biSizeImage Wielkość nieskompresowanej bitmapy w pamięci
LONG biXPelsPerMeter DPI poziome
LONG biYPelsPerMeter DPI pionowe
DWORD biClrUsed Użyta ilość kolorów
DWORD biClrImportant Ilość ważnych kolorów
4
hakin9 Nr 2/2008
www.hakin9.org
171785861.004.png
 
171785861.005.png
 
171785861.006.png
 
171785861.007.png 171785861.008.png 171785861.009.png
 
171785861.010.png
 
Format BMP okiem hakera
niu na potrzebną ilość bajtów otrzy-
mamy 10000h * 10000h * (8/8) , czy-
li 100000000h . DWORD pomieścić
może jedynie najmłodsze 32 bity tej
liczby, w związku z czym w zmiennej
size zapisane zostanie 00000000h ,
czyli 0. Następnie dojdzie do aloka-
cji pamięci, która zakończy się suk-
cesem (przykładowo system Win-
dows zaalokuje 16 bajtów, mimo ze
malloc dostał 0 w parametrze), a po-
tem zostanie w to miejsce wczytane
65536 wierszy po 65536 pikseli każ-
dy, czyli 4 GB danych, co spowodu-
je przepełnienie bufora oraz wyrzuce-
nie wyjątku (ang. Write Access Viola-
tion ). W przypadku gdy wyjątek zosta-
nie obsłużony prawdopodobnie bę-
dzie również możliwość wykonania
kodu, a w wypadku gdy nie zostanie
obsłużony, aplikacja po prostu zakoń-
czy działanie z odpowiednim komuni-
kacje o błędzie.
Czwartym z kolei polem, pomi-
niętym wcześniej, jest biPlanes, które
mówi o ilości płaszczyzn . Przyjęte jest
że w tym polu powinna być wartość 1.
Niektóre programy ignorują wartość
tego pola, przez co możliwe jest ukry-
cie kolejnych 16 bitów danych.
Kolejnym, szóstym polem jest
biCompression ield . To pole przyj-
muje pewne z góry ustalone war-
tości które mówią o sposobie ko-
dowania i kompresji użytej w przy-
padku danego pliku BMP . Dostęp-
ne wartości w BMP Windows V3 to
BI _ RGB (0) , BI _ RLE8 (1) , BI _ RLE4
(2) oraz BI _ BITFIELDS (3) . Kolejne
wersje formatu BMP zakładają rów-
nież dwie inne wartości: BI _ JPEG (4)
oraz BI _ PNG (5) . Różne rodzaje ko-
dowanie BMP są omówione w kolej-
nych podpunktach.
Następnym polem jest biSizeIma-
ge określające całkowitą wielkość bit-
mapy po ewentualnej dekompresji
(jeżeli bitmapa nie jest kompresowa-
na, to pole może być ustawione na 0).
Listing 1. Niebezpieczny kod wczytujący bitmapę
void * ReadBMPtoMemory ( const char * name , unsigned int * size )
{
char * data = NULL ;
BITMAPFILEHEADER bmfh ;
FILE * f = NULL ;
size_t ret = 0 ;
/* Otwórz 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 ));
/* Powrót */
fclose ( f );
return data ;
/* Obsluga bledow */
err :
if ( f ) fclose ( f );
if ( data ) free ( data );
return NULL ;
}
W przypadku tego pola pułapka wy-
gląda bardzo podobnie jak w przy-
padku pola bfSize z BITMAPFILEHE-
ADER , zaleca się więc zignorowanie
wartości tego pola. Nieostrożne uży-
cie wartości biSizeImage przy aloka-
cji pamięci, a następnie brak kontro-
li pozycji wskaźnika zapisu przy de-
kompresji może prowadzić do prze-
pełnienia bufora.
Dwa kolejne pola – biXPelsPerMe-
ter oraz biYPelsPerMeter – mówią o
poziomej i pionowej ilości pikseli przy-
padających na metr (informacja ana-
logiczna do DPI, ang. Dots Per Inch ).
Informacje te są potrzebne głównie w
przypadku drukowania danej bitma-
py. Pojawia się tutaj pewna groźba w
przypadku implementacji drukowania
bitmap – rozdzielczość ta może przy-
jąć bardzo małą wartość (na przykład
1), i wtedy nawet mała bitmapa może
zająć kilkanaście kartek A4, lub bar-
dzo dużą wartość, przez co cała bit-
mapa będzie wielkości milimetr na mi-
limetr. To pole może zostać wykorzy-
stane również do przechowania pew-
nej informacji (64 bity łącznie), szcze-
gólnie jeśli nie zależy nam na popraw-
ności rozdzielczości drukowanej.
Przedostatnim polem jest biClrU-
sed które mówi o ilości kolorów w pa-
lecie barw. Jeżeli to pole jest wyzero-
wane, przyjmuje się że ilość kolorów
w palecie jest równa liczbie 2 podnie-
sionej do potęgi biBitCount (do 8 bi-
tów włącznie), czyli na przykład w
przypadku 8-bitowej bitmapy przyj-
muje się że paleta ma 256 kolorów.
Co ciekawe, programiści mają ten-
dencje ufać temu polu i zakładać że
jeżeli biClrUser wynosi na przykład 1,
to w bitmapie pojawi się jedynie pierw-
szy z kolei kolor, czyli 00. Jeżeli w bit-
mapie pojawi się więcej kolorów pra-
widłowym działaniem powinno być al-
bo wyświetlanie pozostałych kolorów
jako czarny (czyli wyzerowanie pozo-
Tabela 3. Struktura RGBQUAD
Typ i nazwa pola
Opis
BYTE rgbBlue
Wartość barwy niebieskiej
BYTE rgbGreen
Wartość barwy zielonej
BYTE rgbRed
Wartość barwy czerwonej
BYTE rgbReserved
Zarezerwowane
www.hakin9.org
hakin9 Nr 2/2008
5
 
171785861.011.png 171785861.012.png 171785861.013.png 171785861.014.png
 
Atak
stałej części palety), albo wykonanie
operacji modulo ( wyświetlony _ kolor
= kolor % biClrUsed ). Tak zachowu-
ją się MSPaint, Internet Explorer, czy
Paint Shop Pro. Bardzo dużo progra-
mów jednak rysuje bitmapę na swój
własny sposób, czego przykład jest
przedstawiony na Rysunku 4. W tym
miejscu należało by się zaintereso-
wać czemu tak się dzieje, oraz skąd
się biorą pozostałe kolory – ponie-
waż w palecie w pliku BMP zadekla-
rowany został tylko jeden. Odpowiedź
na to drugie pytanie jest dość prosta
– najwyraźniej programy alokują pa-
mięć na pełną paletę kolorów (256 ko-
lorów), po czym wczytują z pliku ca-
łą tam zawartą paletę (1 kolor). Resz-
ta palety, jako że nie była wyzerowa-
na, zawiera w takim przypadku dane
które znajdowały się wcześniej w pa-
mięci, a konkretniej na stogu (ang. he-
ap ). Drugą możliwa odpowiedź jest ta-
ka że program alokuje paletę o wielko-
ści biClrUsed , a kolory powyżej biCl-
rUsed po prostu korzystają z pamię-
ci po za paletą tak jak by to był dalszy
ciąg palety (tzw. boundary condition
error ). W obu przypadkach kolory któ-
re według pola biClrUsed nie powinny
być używane, są opisane przez dane
znajdujące się w pamięci. Idąc o krok
dalej, można stworzyć BMP o wielko-
ści 256x1 w której dane obrazu bę-
dą kolejnymi kolorami, od 00 do FFh ,
dzięki temu wyświetlona bitmapa bę-
dzie praktycznie rzecz biorąc skopio-
waną paletą kolorów, czyli na ekranie
pojawią się, w postaci kolorowych pik-
seli, dane z pamięci. Czy jednak moż-
na w jakiś sposób przesłać automa-
tycznie przesłać tą bitmapę do jakie-
goś zdalnego serwera? Okazuje się
że w przypadku Firefox 2.0.0.11 oraz
Opera 9.50 beta jest to możliwe. Obie
Rysunek 2. Wykorzystanie ignorowania pola bfOffBits
te przeglądarki obsługują wprowadzo-
ny w HTML 5 tag <canvas> , który umoż-
liwia rysowanie po płótnie , kopiowa-
nie bitmap z tagów <img> na płótno,
oraz odczyt wartości kolorów z płótna .
Możliwe jest więc stworzenie skryptu
który wyświetli odpowiednio sprepa-
rowany plik BMP a następnie skopiuje
go na canvas, odczyta wartości kolo-
rów i prześle je na zdalny serwer. Wg.
badań przeprowadzonych przez au-
tora dane przesyłane na zdalny ser-
wer mogą zawierać fragmenty innych
stron, fragmenty ulubionych, fragmen-
ty historii oraz inne informacje. W mo-
mencie pisania tego artykułu powyż-
sza, znaleziona przez autora, luka,
klasyikowana jako Remote Informa-
tion Disclosure , nie została jeszcze
poprawiona.
Ostatnim polem tego nagłówka
jest biClrImportant – mówiące o ilości
istotnych kolorów w bitmapie. Stanow-
cza większość aplikacji ignoruje jed-
nak to pole, dzięki czemu może ono
zostać użyte do przechowania 32 bi-
tów danych niezwiązanych z bitmapą.
Podsumowując, w nagłówku BIT-
MAPINFOHEADER znajduje się wie-
le pól które nieuważny programista
może potraktować ze zbytnim zaufa-
niem narażając tym samym użytkow-
nika na wyciek informacji a nawet wy-
konanie kodu. Dodatkowo w tym na-
główku można ukryć kolejne bajty
informacji dodatkowych, niezwiąza-
nych z bitmapą.
Paleta barw
Paleta barw jest tablicą struktur
RGBQUAD (patrz Tabela 3) które
opisują wartość barw, kolejno niebie-
skiej, zielonej i czerwonej, danego ko-
loru. Dodatkowo każda struktura do-
pełniona jest jedno bajtowym po-
lem rgbReserved, dzięki czemu cała
struktura ma wielkość 32 bitów (4 baj-
tów). Standard nakazuje aby to ostat-
nie pole było wyzerowane, jednak w
rzeczywistości aplikacje nie spraw-
dzają tego. To pole może zostać uży-
te do ukrycia dodatkowych informacji,
lub do zapisania kanału alfa (w przy-
padku bitmap 32 bitowych). Paleta
barw występuje w przypadku bitmap
1 (1 bitowa bitmapa wcale nie musi
być czarno-biała!), 4 oraz 8 bitowych
(patrz pole biBitCount z BITMAPIN-
FOHEADER ). W przypadku tych bit-
map, jeśli pole biClrUsed nie mówi in-
aczej, paleta zawiera kolejno 2, 16 lub
256 struktur RGBQUAD .
Dane obrazu – BI_RGB
Dane obrazu w przypadku BI_RGB
należy rozważać w dwóch katego-
riach – faktycznych kolorów RGB (bit-
mapa 24 bitowa), oraz numerów kolo-
rów w palecie barw (1 bitowe, 4 bitowe
lub 8 bitowe bitmapy). Niemniej jed-
nak kilka rzeczy jest wspólne. Pierw-
szą z nich jest zapis bitmapy do gó-
ry nogami , czyli pierwsze w pliku znaj-
dują się wiersze które traią na dół bit-
mapy, a kolejne zawierają informa-
cje o wierszach znajdujących się co-
Listing 2. Niebezpieczny kod alokujący pamięć i wczytujący 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 );
6
hakin9 Nr 2/2008
www.hakin9.org
171785861.015.png
 
171785861.016.png
 
171785861.017.png
 
171785861.018.png 171785861.019.png 171785861.020.png
 
171785861.021.png
 
Zgłoś jeśli naruszono regulamin