Zwiększona odporność na fałszowanie DNS przez kodowanie bitu 0x20
Napisał: Patryk Krawaczyński
21/03/2019 w Ataki Internetowe, Bezpieczeństwo Brak komentarzy. (artykuł nr 685, ilość słów: 1343)
D
zień jak codzień spoglądamy na dashboard z top zapytań DNS, aby widzieć jakie zapytania są kierowane z i do naszych serwerów. W zależności od używanych resolverów lub sposobu zbierania danych o zapytaniach DNS nagle możemy zacząć zastanawiać się, dlaczego niektóre nazwy zapytań wyglądają na zniekształcone. Kto normalny pyta o NfSeC.pL? Z pewnością jakiś skryptowy dzieciak się czymś bawi. Ale chwila tych domen jest znacznie więcej. Więc co tu się dzieje? Nowa forma ataku na DNS?
Rok 2008 był popularnym rokiem dla DNS, ponieważ był to rok tzw. “Ataku Kaminskiego“. Atak ten (który, jak warto zauważyć, był wcześniej opisywany przez innych badaczy – został nazwany na cześć Kaminskiego, ponieważ przedstawił przekonywujący sposób jego demonstrację) pozwala atakującemu na wstrzyknięcie fałszywej odpowiedzi na zapytanie DNS. Jak do tego dochodzi? Rekurencyjne resolvery DNS, które są publiczne zapamiętują na jakiś czas odpowiedzi na obsługiwane zapytania. Czyniąc to, znacznie przyśpieszają przetwarzanie popularnych domen: gdy Twój komputer / router przez większość czasu pyta o adres IP nfsec.pl to DNS twojego wyboru lub dostawcy usług internetowych (ISP) nie będzie musiał szukać odpowiedzi, ponieważ prawdopodobnie ktoś inny z Twojej sieci poprosił już o ten adres wcześniej, a serwer DNS zapamiętał go na określony czas. W połączeniu z mechanizmem komunikacyjnym DNS stwarza to pewien problem. Komunikacja DNS typu pytanie / odpowiedź używa protokołu UDP, co oznacza, że klient nie ustanawia “sesji” na serwerze. Po prostu wysyła zapytanie do internetu, a następnie ma nadzieję że nadejdzie odpowiedź. Gdy wreszcie nadchodzi – to zaufanie do niej przypomina trochę grę w zgadywanie.
Ważne jest, aby pamiętać, że serwery DNS akceptują tylko odpowiedzi na oczekujące zapytania. Jak serwer nazw wie, że oczekiwana jest odpowiedź i jakie kroki są podejmowane, aby zweryfikować tę odpowiedź?
- Po pierwsze zarówno żądanie, jak i odpowiedź zawierają identyfikator transakcji (ang. Transaction ID – TXID), ale jest to tylko 16 losowych bitów, co jest dość małą wartością i statystycznie łatwą do odgadnięcia (biorąc pod uwagę, że procesor Pentium 100 był w stanie wygenerować 100.000 odpowiedzi na sekundę, wysłanie pakietu z każdym możliwym identyfikatorem transakcji jest banalnym zadaniem dla nowoczesnego sprzętu). Dlatego moglibyśmy nieustannie bombardować klienta fałszywymi odpowiedziami na zapytania:
... 11:00:00.000 hej, IPv4 nfsec.pl to 127.0.0.1 [transactionId:0x42] 11:00:00.100 hej, IPv4 nfsec.pl to 127.0.0.1 [transactionId:0x156] 11:00:00.200 hej, IPv4 nfsec.pl to 127.0.0.1 [transactionId:0x1] 11:00:00.300 hej, IPv4 nfsec.pl to 127.0.0.1 [transactionId:0x5211] ...
w nadziei, że nasza odpowiedź (klient nie może ufać źródłowemu adresowi IP skąd przyszła odpowiedź, ponieważ może on zostać sfałszowany) dotrze dokładnie w momencie, gdy wysłano zapytanie o nfsec.pl, ale prawdziwa jeszcze nie dotarła. W ten sposób sprawiamy, że resolver zapamięta naszą złośliwą odpowiedź i poda ją swoim klientom (np. przeglądarce) – tak działa atak zatruwania pamięci podręcznej DNS. Widząc słabość tego systemu wprowadzono lepszy algorytm do generowania identyfikatorów transakcji.
- Po drugie odpowiedź powinna dotrzeć do systemu klienta na ten sam port, z którego zostało wysłane zapytanie, w przeciwnym razie zostanie odrzucone już na poziomie stosu sieciowego systemu operacyjnego. W przeszłości był to zawsze port 53. Widząc słabość tego mechanizmu została wprowadzona losowość portu, z którego następuje zapytanie, więc teraz atakujący musi dodać kolejną pozycję do listy obliczeń.
- Sprawdzanie baliwatu (ang. bailiwick checking) – rozważmy następującą analogię. Załóżmy, że podróżujemy autostradą, a nasz samochód się psuje. Proszę Cię o numer telefonu do lokalnego warsztatu, a Ty odpowiadasz: “Nie znam ich numeru telefonu, powinieneś do nich zadzwonić, aby się dowiedzieć.” Bez znajomości numeru telefonu warsztatu, jak mogę do nich zadzwonić, aby poznać ich numer telefonu? Teraz pomyślmy o podobnej sytuacji w DNS. Chcemy znaleźć adres nfsec.pl, więc pytamy główny serwer (ang. root) DNS o listę serwerów DNS dla strefy .pl. Serwer główny podaje nam listę serwerów DNS dla .pl, więc wybieramy jeden i pytamy go o listę serwerów DNS dla nfsec.pl. Jeśli serwer na poziomie .pl po prostu odpowiedział nam: ns1.nfsec.pl i ns2.nfsec.pl, utknęlibyśmy. Także próbujemy znaleźć informacje na temat domeny nfsec.pl i po drodze otrzymujemy polecenie, aby zapytać serwery DNS nfsec.pl o odpowiedź. Aby rozwiązać problem kury i jajka w dodatkowej sekcji znajdują się dwa rekordy typu: A, aby wypełnić brakujące ogniwo. Są to tak zwane rekordy GLUE:
agresor@darkstar:~$ dig @ns1.nfsec.pl nfsec.pl ; < <>> DiG 9.10.6 < <>> @ns1.nfsec.pl nfsec.pl ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER< <- opcode: QUERY, status: NOERROR, id: 6363 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 7 ;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;nfsec.pl. IN A ;; ANSWER SECTION: nfsec.pl. 300 IN A 37.187.104.217 ;; AUTHORITY SECTION: nfsec.pl. 300 IN NS ns2.nfsec.pl. nfsec.pl. 300 IN NS ns1.nfsec.pl. ;; ADDITIONAL SECTION: ns1.nfsec.pl. 300 IN A 37.187.104.217 ns2.nfsec.pl. 300 IN A 213.186.33.199 ns1.nfsec.pl. 300 IN AAAA 2001:41d0:a:38d9::1 ns2.nfsec.pl. 300 IN AAAA 2001:41d0:3:1c7::1 ns1.abuse.pl. 300 IN A 38.188.105.219 ;; Query time: 40 msec ;; SERVER: 37.187.104.217#53(37.187.104.217) ;; WHEN: Wed Mar 20 21:36:58 CET 2019 ;; MSG SIZE rcvd: 245
Widzimy dodatkową linię na końcu? Zadaliśmy pytanie o obiekty w domenie nfsec.pl, ale podstępny serwer odpowiedział nam również informacjami o ns1.abuse.pl. Czy ten serwer jest w ogóle upoważniony do odpowiadania na żądania DNS dotyczące nfsec.pl? Resolvery używają techniki zwanej sprawdzaniem baliwatu, aby określić, czy zaakceptować te dodatkowe rekordy. Oznacza to, że wszelkie rekordy, które nie należą do tej samej domeny, o którą pytaliśmy - są ignorowane. Jeśli poprosimy o informacje na temat ssh.nfsec.pl, zaakceptujemy tylko te informacje z dodatkowej sekcji, które powiązane są z nfsec.pl. Od około 1997 roku prawie wszystkie współczesne resolvery DNS używają sprawdzania baliwatu do ochrony przed tego typu atakiem zatrucia pamięci podręcznej.
Więc, co z tym wszystkim ma wspólnego zapytanie DNS nfSEC.pl? Otóż RFC 1034, sekcja 3.5 mówi o tym, że nazwy domen DNS dopasowywane są bez względu na ich formę pisowni. Dlatego wpisując NFsec.pl do przeglądarki internetowej lub kodując aplikację w celu wywołania API do WhatsApp.com – obie te nazwy DNS przetłumaczą się na adresy IP się bez problemu. W marcu 2008 roku przedstawiono projekt jako część grupy roboczej w celu zwiększenia operacji DNS. Celem tego projektu – “Use of Bit 0x20 in DNS Labels to Improve Transaction Identity” – było zwiększenie entropii poza randomizacją portu źródłowego poprzez randomizację wielkości liter zapytania. Zakładając teraz, że port pasuje – odpowiedź zostanie przekazana do procesu rozpoznawania nazw, który sprawdzi, czy odpowiedź jest zgodna z pierwotnie zadanym pytaniem. W tym przypadku użycie bitu 0x20 poprawi tożsamość transakcji, ponieważ ktoś kto spróbuje podrobić odpowiedź – oprócz przeszkód opisanych powyżej – musiałby wiedzieć, w jaki sposób nazwa domeny została losowo zapisana w zapytaniu. Zamiast więc prosić o www.nfsec.pl można wysyłać prośby o adres domeny WWW.NFSEC.PL, wWw.NFsec.pL, WwW.nfSEC.Pl itd. Im dłuższa nazwa domeny, tym większa entropia, ponieważ kodujemy jeden losowy bit na literę ASCII:
- nfsec.pl 11111 11 - NFSEC.PL 00000 00 - NFsec.PL 00111 00 - NfSeC.pL 01010 10
Google implementując tą technikę w swoich serwerach DNS zauważył, że niektóre serwery DNS nie zachowują się zgodnie z oczekiwanym zachowaniem tj. reagują na zapytania z pełną wrażliwością na wielkość liter (z naruszeniem standardów DNS): obsługują równoważne nazwy w różny sposób w zależności od przypadku pisowni w żądaniu, zwracają niepoprawne odpowiedzi NXDOMAIN albo nie odpowiadają w ogóle. Niemniej jednak 70% serwerów z ich ruchu sieciowego reaguje poprawnie z pełną niewrażliwością na wielkość lister w zapytaniu o domeny.
Bonus:Lata temu, kryptolog Daniel J. Bernstein analizował mechanizmy bezpieczeństwa DNS i wprowadził mechanizm losowości portu. Bernstein nie wiedział wtedy o ataku Kaminskiego, ale zdawał sobie sprawę z innych klas ataków na DNS dlatego uznał, że rozszerzenie to pomoże w dodatkowej obronie. W konsekwencji program DNS, który napisał w 2000 roku “djbdns” nie wymagał łatania – ponieważ był już odporny na atak Kaminskiego. Można powiedzieć, że tak wygląda dobrze zaprojektowane oprogramowanie. Broni nie tylko przez znanymi atakami, ale jeszcze przed tymi, których się nie zna, a które nadejdą.
Więcej informacji: Understanding Kaminsky’s DNS Bug, DNS-0x20, DNS and The Bit 0x20, Use of Bit 0x20 in DNS Labels