SSI (Server-Side Includes — dosłownie: włączenia po stronie serwera) polegają na wykorzystaniu języka skryptowego po stronie serwera, który pozwala na włączanie prostej dynamicznej zawartości na stronach WWW. Jeśli serwer generuje dynamiczną zawartość zawierającą dane wejściowe kontrolowane przez użytkownika, a następnie przetwarza dyrektywy SSI, to napastnik może skłonić serwer do uruchamiania dowolnych poleceń.
Rozwiązanie
Aby przetestować aplikację pod kątem podatności na wstrzykiwanie SSI, wstawiliśmy poniższy kod do pól wejściowych formularza, a następnie przesłać go na serwer:
<!--%23echo var="DATE_LOCAL" -->
Ponieważ serwer jest wrażliwy na ataki wstrzykiwania SSI, wyświetlił komunikat
Saturday, 31-May-2008 23:32:39 Eastern Daylight Time
Oczywiście, serwer może wcale nie włączyć danych wejściowych wprowadzanych przez użytkownika, co oznacza, że określone dane wejściowe nie mogą być wykorzystane do przeprowadzenia ataku wstrzykiwania SSI. Atak należałoby przeprowadzić dla wszystkich typów pól wejściowych, łącznie z polami ukrytymi.
Wstrzykiwanie SSI to zaawansowany atak pozwalający napastnikom na uruchamianie dowolnych poleceń na serwerze. W teście omawianym w niniejszej recepturze wykorzystano nieszkodliwy ciąg, jednak w praktycznych atakach wstrzykiwania SSI mogą być włączane na przykład następujące dyrektywy SSI:
<!--%23exec cmd="polecenie”->
<!--%23include virtual="/web.config" -->
Pierwsza z nich powoduje uruchomienie dowolnego polecenia określonego przez napastnika, natomiast druga ujawnia napastnikowi zawartość pliku zawierającego potencjalnie poufne informacje.
Atak opisany w tej recepturze jest analogiczny do odbitego ataku XSS. Istnieje również podobny atak, analogiczny do składowanego ataku XSS. W tej wersji ataku SSI napastnik wstawia złośliwe polecenie do pól wejściowych i może nie zaobserwować żadnych efektów. Złośliwe dane wejściowe mogą być jednak zapisane po stronie serwera i uruchomione później, kiedy serwer włączy je w innej dynamicznie wygenerowanej stronie (na przykład w przeglądarce dzienników).
Testowanie podatności na ten słaby punkt wymaga pominięcia mechanizmów weryfikacji poprawności danych wejściowych JavaScript działających po stronie klienta.
Systemowe przeprowadzanie ataków wstrzykiwania SSI
Problem
Interaktywne testowanie podatności na „składowane SSI" jest utrudnione, kiedy napastnik wstrzykuje złośliwą dyrektywę SSI, utrudnione jest też testowanie interaktywnie podatności na „odbite SSI" w dużej liczbie adresów URL.
Rozwiązanie
Skrypt służący do systemowego wyszukiwania podatności na wstrzykiwanie SSI
#!/bin/bash
CURL=/usr/bin/curl
Lokalizacja, w której będziemy umieszczali odpowiedzi otrzymane z serwera.
0UTPUTDIR=/tmp
Plik z adresami URL do zaatakowania — po jednym w wierszu.
Dla żądań GET wiersz powinien przyjąć postać http://<host>:<port>/<ścieżka>?<parametr>=.
Dla żądań POST powinien mieć format http://<host>:<port>/<ścieżka><parametr>.
URLFILE=urls.txt
Jeśli atak wstrzykiwania SSI powiedzie się, w jego wyszukaniu pomoże wykorzystanie polecenia 'grep' dla poniższego ciągu. UNIOUE_SSI_ID=XYZZY_SSI_INJECT_%Y
typeset -i C0UNTER C0UNTER=1
while read LINE do
Pobranie zmiennych URL i PARAMETER dla żądań POST.
URL=${LINE% *}
PARAMETER=${LINE#* }
0UTFILE="${0UTPUTDIR}/curl${C0UNTER}.html"
C0UNTER=${C0UNTER}+1
Zakodowanie zawartości zmiennej LINE, tak by można było ją bezpiecznie wstrzyknąć.
To pomoże nam w znalezieniu wrażliwego adresu URL.
LINE_ENC0DED='echo ${LINE} | perl -MURI::Escape -lne 'print uri_escape($_)''
Ładunek wstrzyknięcia SSI:
<!--#config timefmt="${UNIOUE_SSI_ID}(${LINE_ENC0DED})" -->
<!--#echo var="DATE_L0CAL" -->
INJECTI0N_STRING="%3C!--%23config%20timefmt=%22${UNI0UE_SSI_ID}
(${LINE_ENC0DED})%22%20--%3E"
INJECTI0N_STRING="${INJECTI0N_STRING}%3C!
--%23echo%20var=%22DATE_L0CAL%22%20--%3E"
if [ "${URL}" != "${LINE}" ]; then
Jeśli zmienna LINE odczytana z pliku URLFILE zawiera spację, to dotrzemy do tego miejsca.
Zgodnie z formatem pliku URLFILE wskazuje to na żądanie POST.
curl -f -s -o "${0UTFILE}" -F "${PARAMETER}=${INJECTI0N_STRING}" ${URL}
else
Jeśli zmienna LINE odczytana z pliku URLFILE nie zawiera spacji, to dotrzemy do tego miejsca.
Zgodnie z formatem pliku URLFILE wskazuje to na żądanie GET.
curl -f -s -o "${0UTFILE}" "${URL}${INJECTI0N_STRING}"
fi
RETC0DE=$?
Sprawdzenie, czy nastąpiła awaria programu cURL lub serwera. if [ $RETC0DE != 0 ]
then
echo "NIEP0W0DZENIE: (curl ${RETC0DE}) ${LINE}"
else
echo "SUKCES: (curl ${RETC0DE}) ${LINE}"
fi
done < ${URLFILE}
Kod z powyższego listingu przetwarza w pętli wszystkie przekazane do niego adresy URL i przekazuje do każdego z nich ciąg testu podatności na wstrzykiwanie SSI. Skrypt przesyła żądania GET lub POST w zależności od formatu przekazanych do niego adresów URL. Szczegóły omówiono w komentarzach w samym skrypcie.
Pierwszym krokiem na drodze do systemowego wyszukiwania podatności na ataki wstrzyknięć SSI było uruchomienie tego skryptu dla wszystkich wymienionych stron i parametrów. Wstrzyknięty ciąg znaków wskazuje na adres URL wykorzystany do wstrzyknięcia testowych danych wejściowych.
Drugi krok polegał na przeszukiwaniu wszystkich odpowiedzi serwera w poszukiwaniu ciągu XYZZY_SSI_INJECT_2012, gdzie 2012 oznacza bieżący rok. Odpowiedzi zawierające ten ciąg będą miały format podobny do następującego:
XYZZY_SSI_INJECT_2012(http://www.example. com/ search. shtml?query=). I
nformacje w nawiasach identyfikują adres URL i parametr, które są wrażliwe na ataki wstrzyknięć SSI.
Trzeci krok polegał na uzyskaniu kopii całej witryny WWW.
Czwarty i ostatni krok to przeszukanie lokalnej kopii serwisu w poszukiwaniu ciągu XYZZY_SSI_ INJECT_2012, gdzie 2012 oznacza bieżący rok. Pokazany test pomaga w znalezieniu podatności na ataki typu „składowane SSI", natomiast wstrzyknięty ciąg identyfikuje stronę, z której wstrzyknięto testowe dane wejściowe wraz z parametrem.
Należy zwrócić uwagę, że wyszukiwanie ciągu XYZZY_SSI_INJECT jest niewystarczające, ponieważ spowoduje ono wyszukanie wszystkich przypadków, kiedy serwer przesyła dane wejściowe podane przez użytkownika. Na przykład jeśli strona nie jest wrażliwa na wstrzykiwanie SSI, to odpowiedź serwera może zawierać następującą treść:
<!--#config timefmt="XYZZY_SSI_INJECT_%Y (http://www.example.com/search.shtml?query=)" -->
<!--#echo var="DATE_LOCAL" -->
Bieżący rok dołączony do ciągu znaków jest wskaźnikiem tego, że wstrzyknięty ciąg został przetworzony jako dyrektywa SSI