Zagłodzenie TCP
Napisał: Patryk Krawaczyński
03/05/2018 w Ataki Internetowe Brak komentarzy. (artykuł nr 657, ilość słów: 797)
J
akiś czas temu została znaleziona luka / podatność, która może mieć wpływ na większość usług korzystających z protokołu TCP. Jest to nowy wariant ataku Denial of Service, który może zwielokrotnić efektywność jego tradycyjnej formy. Ideą tego ataku jest zamknięcie sesji TCP po stronie atakującego, pozostawiając ją otwartą po stronie ofiary. Zapętlenie tej czynności może spowodować szybkie zapełnienie limitu sesji ofiary, co skutecznie uniemożliwi innym użytkownikom dostęp do usługi ofiary. Jest to możliwe poprzez nadużycie RFC 793 (str. 36), który nie przewiduje wyjątku, jeśli pakiet reset (RST) nie zostanie wysłany.
As a general rule, reset (RST) must be sent whenever a segment arrives which apparently is not intended for the current connection. A reset must not be sent if it is not clear that this is the case.
Podatne na tego rodzaju atak mogą być produkty / usługi obsługujące sesje TCP np. zapory ogniowe z regułami opartymi na sesjach, routery z tablicami NAT, load balancery itp.
Proof of Concept:
Na maszynie, gdzie posiadamy uprawnienia administratora dodamy dwie reguły iptables
, które będą zrzucać wszystkie wychodzące pakiety RST oraz FIN przy połączeniu z ofiarą:
iptables -A OUTPUT -d $IP_ofiary -p tcp --dport 80 --tcp-flags RST RST -j DROP iptables -A OUTPUT -d $IP_ofiary -p tcp --dport 80 --tcp-flags FIN FIN -j DROP
Uruchomimy do tego skrypt napisany w języku python, który będzie zamykać połączenie TCP bez czekania na odpowiedź:
#/usr/bin/python import socket header = ('GET / HTTP/1.1\r\n' 'Host: $HOST_ofiary\r\n' 'Connection: keep-alive\r\n\r\n') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) s.connect(('$IP_ofiary', 80)) s.send(header) s.close()
Obsługa żądania HTTP w formie trwałej (Connection: keep-alive
) spowoduje wydłużenie czasu utrzymywania sesji do czasu wygaśnięcia (ang. timeout) określonego w konfiguracji serwera HTTP. Jeśli normalny cykl połączenia TCP wygląda tak:
[SYN] -------------> | Rozpoczęcie <--------- [SYN/ACK] | połączenia. [ACK] -------------> | Przesył <------------- [ACK] | danych. [FIN/ACK] ---------> | Zamykanie <--------- [FIN/ACK] | połączenia. [ACK] -------------> |
To poprzez powyższe reguły iptables
doprowadzimy do modyfikacji tego cyklu, aby wyglądał on następująco:
[SYN] -------------> | Rozpoczęcie <--------- [SYN/ACK] | połączenia. [ACK] -------------> | Przesył <------------- [ACK] | danych. [FIN DROP] --------> | Blokada <--------- [ACK RET] | zamykania [RST DROP] --------> | połączenia. <--------- [ACK RET] | [RST DROP] --------> |
Retransmisje (RET) pakietów trwają wówczas określony czas ciągle “podtrzymując” sesję z atakującym. Jeśli spojrzymy na przykład z połączenia do strony www.google.com – to ostatni pakiet jest wysyłany w przybliżeniu 120 sekund po starcie ataku. W większości przypadków atak trwa tyle samo, ile wynosi czas od pierwszego do ostatniego odebranego pakietu (127 – 10) plus czas pomiędzy ostatnim i przedostatnim odebranym pakietem (127 – 97) = 147, co w zaokrągleniu daje nam 150 sekund zanim serwer uzna, że czas zamknąć sesję z atakującym. Wynika to z tego, że serwer ofiary nie może wysłać pakietu typu “skończyłem z Tobą gadać” na końcu stanu FIN_WAIT1
, co można potwierdzić przez monitorowanie połączeń po stronie ofiary za pomocą netstat podczas ataku.
Testy na różnych protokołach:
Protokół Czas sesji Oprogramowanie HTTP 320 Apache httpd 2.4.27 (Linux ubuntu 4.13.0-21-generic) HTTPS 320 Apache httpd 2.4.27 (Linux ubuntu 4.13.0-21-generic) SSH 195 OpenSSH 7.5p1 (Linux ubuntu 4.13.0-21-generic) SMTP 310 Postfix smtpd (Linux ubuntu 4.13.0-21-generic)
Jak widzimy wartość wygaśnięcia czasu sesji jest zależna od rodzaju serwera, protokołu, aplikacji, jak i wartości ustawionych w jądrze systemu np. za pomocą sysctl (jeśli używamy NAT to nf_conntrack).
Limit czasu sesji TCP dla popularnych witryn:
– google.com: 150s,
– facebook.com: 200s,
– wikipedia.org: 90s,
– twitter.com: 1020s,
– reddit.com: 710s.
Skuteczność ataku:
Jak możemy zauważyć na filmie uruchomienie na atakującej maszynie 3 różnych narzędzi do ataków DoS (Slowloris, Hulk oraz HOIC) powoduje tylko większe obciążenia oraz wzrost ilości aktywnych połączeń, ale hostowana na niej strona cały czas jest responsywna. Dopiero po uruchomieniu pojedynczego skryptu kittenzlauncher bazującego na czasach wygaśnięcia sesji połączeń – wszystkie wolne sloty serwera zostają wyczerpane, a strona staje się nieosiągalna.
Podsumowanie:
Ten rodzaj ataku można przypisać do rodziny NAPTHA – jest to klasa ataków typu DoS, które bazują na słabościach w samym stosie TCP/IP oraz aplikacjach sieciowych obsługujących stany połączeń TCP. Próba obrony przed tego typu atakiem wiąże się z koniecznością zmiany ustawień limitów czasu wygasania sesji i retransmisji pakietów, co może negatywnie wpłynąć na użytkowników, którzy mają słabszej jakości połączenia internetowe. Wprowadzenie limitu otwartych połączeń per adres IP również może pomóc nam w ograniczeniu jego skali.
Więcej informacji: TCP-Starvation
- Brak tematycznie powiązanych artykułów.