Jaki jest najlepszy środek zaradczy rozproszonej brutalnej siły?

151

Najpierw trochę tła: Nie jest tajemnicą, że wdrażam system auth + auth dla CodeIgniter i póki co wygrywam (że tak powiem). Ale napotkałem dość nietrywialne wyzwanie (takie, którego większość bibliotek auth całkowicie tęskni, ale nalegam, aby sobie z nim poradzić): jak inteligentnie radzić sobie z atakami brutalnej siły na dużą skalę, rozproszonymi i zmiennymi nazwami użytkownika .

Znam wszystkie zwykłe sztuczki:

  1. Ograniczenie liczby nieudanych prób na adres IP / host i odmowa dostępu przestępcom (np. Fail2Ban) - co już nie działa, ponieważ botnety stały się inteligentniejsze
  2. Połączenie powyższego z czarną listą znanych „złych” adresów IP / hostów (np. DenyHosts) - która polega na tym, że botnety zajmują pierwsze miejsce, czego coraz częściej nie
  3. Białe listy adresów IP / hostów w połączeniu z tradycyjnym uwierzytelnianiem (niestety bezużyteczne w przypadku dynamicznych użytkowników adresów IP i dużej rezygnacji z większości witryn internetowych)
  4. Ustawienie limitu dla całej witryny na liczbę nieudanych prób w ciągu N minut / godziny i ograniczanie (zawieszanie) wszystkich kolejnych prób logowania na kilka minut / godzin (z problemem polegającym na tym, że atakowanie Cię przez DoS staje się dziecinnie proste)
  5. Obowiązkowe podpisy cyfrowe (certyfikaty klucza publicznego) lub tokeny sprzętowe RSA dla wszystkich użytkowników bez opcji logowania / hasła (bez wątpienia solidne rozwiązanie, ale praktyczne tylko dla zamkniętych, dedykowanych usług)
  6. Wymuszone bardzo silne schematy haseł (np.> 25 nonsensownych znaków z symbolami - znowu zbyt niepraktyczne dla zwykłych użytkowników)
  7. I wreszcie CAPTCHA (które mogą działać w większości przypadków, ale są irytujące dla użytkowników i praktycznie bezużyteczne dla zdeterminowanego, zaradnego napastnika )

To tylko teoretycznie wykonalne pomysły. Istnieje wiele bzdurnych pomysłów, które rozsadzają witrynę (np. Trywialne ataki DoS). Chcę czegoś lepszego. A przez lepsze mam na myśli:

  • Musi być zabezpieczony (+) przed atakami DoS i brutalną siłą i nie wprowadzać żadnych nowych luk, które mogłyby pozwolić nieco bardziej podstępnemu botowi na dalsze działanie pod radarem

  • To musi być zautomatyzowane. Jeśli wymaga, aby operator weryfikował każde logowanie lub monitorował podejrzaną aktywność, nie zadziała w prawdziwym scenariuszu

  • Musi być wykonalne dla głównego nurtu korzystania z sieci (tj. Duża liczba rezygnacji, duża liczba i otwarta rejestracja, którą mogą przeprowadzić osoby nie będące programistami)

  • Nie może utrudniać doświadczenia użytkownika do tego stopnia, że ​​zwykli użytkownicy będą zirytowani lub sfrustrowani (i potencjalnie opuszczą witrynę)

  • Nie może to dotyczyć kociąt, chyba że są naprawdę bezpiecznymi kociętami

(+) Przez „bezpieczne” rozumiem co najmniej tak samo bezpieczne, jak zdolność paranoicznego użytkownika do utrzymania swojego hasła w tajemnicy

A więc - posłuchajmy! Jak byś to zrobił ? Czy znasz najlepszą praktykę, o której nie wspomniałem (och, proszę, powiedz, że wiesz)? Przyznaję, że mam własny pomysł (łącząc pomysły z 3 i 4), ale pozwolę prawdziwym ekspertom mówić, zanim się zawstydzę ;-)

Jens Roland
źródło

Odpowiedzi:

68

W porządku, wystarczy przeciągać; oto co wymyśliłem do tej pory

(przepraszam, długi post. Bądź odważny, przyjacielu, podróż będzie tego warta)

Łączenie metod 3 i 4 z oryginalnego postu w rodzaj „rozmytej” lub dynamicznej białej listy, a następnie - i oto sztuczka - nie blokowanie adresów IP spoza białej listy, tylko dławienie ich do piekła i z powrotem .

Należy pamiętać, że ten środek ma na celu jedynie udaremnienie tego bardzo specyficznego rodzaju ataku. W praktyce oczywiście działałby w połączeniu z innymi najlepszymi sposobami podejścia do uwierzytelniania: ograniczanie stałej nazwy użytkownika, ograniczanie dla poszczególnych adresów IP, polityka silnych haseł wymuszana kodem, logowanie do niezakłóconych plików cookie, haszowanie wszystkich odpowiedników haseł przed ich zapisaniem, nigdy używanie pytań zabezpieczających itp.

Założenia dotyczące scenariusza ataku

Jeśli atakujący kieruje się na zmienne nazwy użytkowników, funkcja ograniczania przepustowości nazw użytkowników nie zostanie uruchomiona. Jeśli atakujący używa botnetu lub ma dostęp do dużego zakresu adresów IP, nasze dławienie adresów IP jest bezsilne. Jeśli osoba atakująca wstępnie zeskrobała naszą listę użytkowników (zwykle jest to możliwe w usługach internetowych z otwartą rejestracją), nie możemy wykryć trwającego ataku na podstawie liczby błędów „nie znaleziono użytkownika”. A jeśli wymusimy restrykcyjne dławienie w całym systemie (wszystkie nazwy użytkowników, wszystkie adresy IP), każdy taki atak spowoduje DoS całą naszą witrynę na czas trwania ataku plus okres ograniczania przepustowości.

Więc musimy zrobić coś innego.

Pierwsza część środka zaradczego: Biała lista

Możemy być całkiem pewni, że atakujący nie jest w stanie wykryć i dynamicznie sfałszować adresów IP kilku tysięcy naszych użytkowników (+). Co sprawia, że biała lista jest możliwa. Innymi słowy: dla każdego użytkownika przechowujemy listę (zahaszowanych) adresów IP, z których użytkownik wcześniej (ostatnio) się logował.

W ten sposób nasz schemat białej listy będzie funkcjonował jako zamknięte „drzwi wejściowe”, w przypadku których użytkownik musi być połączony z jednym ze swoich uznanych „dobrych” adresów IP, aby w ogóle się zalogować. Atak siłowy na te „drzwi frontowe” byłby praktycznie niemożliwy (+).

(+) chyba, że ​​atakujący „jest właścicielem” serwera, wszystkich skrzynek naszych użytkowników lub samego połączenia - iw takich przypadkach nie mamy już problemu z „uwierzytelnianiem”, mamy prawdziwą wersję typu pull-the -plug sytuacja FUBAR

Druga część środka zaradczego: ograniczanie nierozpoznanych adresów IP w całym systemie

Aby biała lista działała dla usługi internetowej z otwartą rejestracją, w której użytkownicy często zmieniają komputery i / lub łączą się z dynamicznych adresów IP, musimy pozostawić „kocie drzwiczki” otwarte dla użytkowników łączących się z nierozpoznanych adresów IP. Sztuczka polega na takim zaprojektowaniu tych drzwi, aby botnety utknęły w miejscu, a legalnym użytkownikom jak najmniej przeszkadzano .

W moim schemacie osiąga się to poprzez ustawienie bardzo restrykcyjnej maksymalnej liczby nieudanych prób logowania przez niezatwierdzone adresy IP w okresie, powiedzmy 3 godzin (rozsądniej jest użyć krótszego lub dłuższego okresu w zależności od rodzaju usługi) oraz uczynienie tego ograniczenia globalnym , tj. dla wszystkich kont użytkowników.

Nawet powolna (1-2 minuty między próbami) brutalna siła byłaby wykryta i udaremniona szybko i skutecznie przy użyciu tej metody. Oczywiście naprawdę powolna brutalna siła może pozostać niezauważona, ale zbyt wolne prędkości pokonują cel ataku brutalnej siły.

Mam nadzieję, że dzięki temu mechanizmowi dławienia mam nadzieję, że po osiągnięciu maksymalnego limitu nasze `` drzwiczki dla kota '' zatrzaskują się na chwilę, ale nasze drzwi wejściowe pozostają otwarte dla legalnych użytkowników łączących się w zwykły sposób:

  • Albo przez połączenie z jednego z ich rozpoznanych adresów IP
  • Lub za pomocą trwałego pliku cookie logowania (z dowolnego miejsca)

Jedyni uprawnieni użytkownicy, którzy zostaliby dotknięci podczas ataku - tj. gdy dławienie zostało aktywowane - byliby to użytkownicy bez trwałych plików cookie logowania, którzy logowali się z nieznanej lokalizacji lub z dynamicznym adresem IP. Tacy użytkownicy nie mogliby się zalogować, dopóki dławienie nie ustąpi (co może zająć trochę czasu, jeśli atakujący utrzymałby swój botnet pomimo ograniczenia).

Aby pozwolić tej niewielkiej grupie użytkowników przecisnąć się przez inaczej zaplombowane drzwi dla kota, nawet gdy boty wciąż w nie walą, zastosowałbym „zapasowy” formularz logowania z CAPTCHA. Tak więc, kiedy wyświetli się komunikat „Przepraszamy, ale w tej chwili nie możesz zalogować się z tego adresu IP”, umieść link o treści „ bezpieczne logowanie kopii zapasowej - TYLKO LUDZIE ( boty: bez kłamstwa ) ”. Żartuj na bok, kiedy klikną ten link, przekaż im formularz logowania uwierzytelniony przez reCAPTCHA, który omija ograniczanie przepustowości w całej witrynie. W ten sposób, JEŻELI są ludźmi ORAZ znają poprawny login i hasło (i potrafią odczytać CAPTCHA), nigdy nie otrzymają odmowy usługi, nawet jeśli łączą się z nieznanego hosta i nie używają pliku cookie autologowania.

Aha, i tylko dla wyjaśnienia: ponieważ uważam, że CAPTCHA są ogólnie złe, opcja logowania „zapasowa” pojawiała się tylko wtedy, gdy dławienie było aktywne .

Nie można zaprzeczyć, że taki długotrwały atak nadal stanowiłby formę ataku DoS, ale z opisanym systemem wpłynąłby tylko na to, co podejrzewam, że jest niewielką podgrupą użytkowników, a mianowicie na osoby, które nie używają plik cookie „zapamiętaj mnie” ORAZ loguje się podczas ataku ORAZ nie loguje się z żadnego ze swoich zwykłych adresów IP ORAZ nie może odczytać CAPTCHA. Tylko ci, którzy mogą odmówić WSZYSTKIM z tych kryteriów - w szczególności botom i naprawdę pechowym osobom niepełnosprawnym - zostaną odrzuceni podczas ataku botów.

EDYCJA: Właściwie wymyśliłem sposób, aby pozwolić nawet użytkownikom z wyzwaniami CAPTCHA przejść przez `` blokadę '': zamiast lub jako dodatek do zapasowego loginu CAPTCHA, zapewnić użytkownikowi opcję jednorazowego użytku , specyficzny dla użytkownika kod blokujący wysłany na jego e-mail, którego może użyć do ominięcia ograniczania przepustowości. To zdecydowanie przekracza mój próg `` irytacji '', ale ponieważ jest używany tylko w ostateczności dla niewielkiej części użytkowników, a ponieważ nadal jest lepszy od zablokowania konta, byłoby to do przyjęcia.

(Zwróć również uwagę, że nic z tego się nie dzieje, jeśli atak jest mniej wyrafinowany niż paskudna wersja rozproszona, którą tutaj opisałem. Jeśli atak pochodzi z zaledwie kilku adresów IP lub dotyczy tylko kilku nazw użytkowników, zostanie udaremniony znacznie wcześniej i bez konsekwencji dla całej witryny)


Jest to więc środek zaradczy, który zaimplementuję w mojej bibliotece auth, kiedy będę przekonany, że to dźwięk i że nie ma prostszego rozwiązania, którego nie przegapiłem. Faktem jest, że istnieje tak wiele subtelnych sposobów robienia rzeczy źle w zakresie bezpieczeństwa, a ja nie jestem wolny od fałszywych założeń lub beznadziejnie błędnej logiki. Więc proszę, wszelkie opinie, krytyka i ulepszenia, subtelności itp. Są bardzo mile widziane.

Jens Roland
źródło
1
Może mógłbyś wygenerować „specjalne” hasło dla każdego użytkownika, które przydałoby się w trybie blokady (a oni łączą się z nowego adresu IP itp.), Ponieważ to specjalne hasło jest na tyle skomplikowane, że nie można go brutalnie wymusić?
Douglas Leeder
1
To może zadziałać, ale tylko wtedy, gdy użytkownicy pamiętają te hasła, nawet jeśli wcześniej ich nie używali (tego typu ataki nie są powszechne i żaden botmaster wart swojej soli nie zawracałby sobie głowy utrzymywaniem jednego działającego przez długi czas po dławieniu). Ryzyko jest zbyt duże, by po prostu nie pamiętali.
Jens Roland
1
Jednak jedną z metod, która z pewnością mogłaby zadziałać, jest udostępnienie linku „wyślij mi kod blokujący” tym użytkownikom, umożliwiając im otrzymanie wiadomości e-mail zawierającej jednorazowy, specyficzny dla użytkownika token, który pozwoliłby im się zalogować, z pominięciem dławienie.
Jens Roland
1
@Abtin: Dobry pomysł, poza tym, że byłby to „wyścig zbrojeń” - tj. rozpoczęcie „kto może przechytrzyć kogo” z ludźmi, którzy tworzą listy haseł do ataków słownikowych. Myślę, że lepszym rozwiązaniem byłoby, aby wymusić silnych zasad haseł, więc nie mają żadnych słabych haseł
Jens Roland
1
@OrestisP .: Brakuje Ci celu w ataku rozproszonym - liczba nieprawidłowych prób z każdego adresu IP jest minimalna, więc blokowanie poszczególnych adresów IP nie działa. Ponadto pytanie konkretnie opisuje zautomatyzowany atak brutalnej siły, więc 1) atakujący nie jest człowiekiem, ale raczej botnetem maszyn zombie (które nie mogą używać loginu captcha); oraz 2) brutalny charakter ataku wymaga bardzo dużej liczby prób logowania, aby zapewnić sukces, co oznacza, że ​​hodowanie captcha gdzieś do warsztatu jest niewykonalne (aczkolwiek możliwe, jeśli atakujący jest dobrze finansowany i zdeterminowany dość).
Jens Roland
17

Kilka prostych kroków:

Umieść na czarnej liście niektóre popularne nazwy użytkowników i używaj ich jako przynęty. Administrator, gość itp. Nie pozwól nikomu tworzyć kont o tych nazwach, więc jeśli ktoś spróbuje je zalogować, wiesz, że ktoś robi coś, czego nie powinien.

Upewnij się, że każdy, kto ma rzeczywistą władzę w witrynie, ma bezpieczne hasło. Wymagaj od administratorów / moderatorów dłuższych haseł składających się z liter, cyfr i symboli. Odrzuć banalnie proste hasła od zwykłych użytkowników z wyjaśnieniem.

Jedną z najprostszych rzeczy, które możesz zrobić, jest poinformowanie ludzi, że ktoś próbował zalogować się na ich konto i udostępnienie im linku do zgłoszenia incydentu, jeśli to nie oni. Prosta wiadomość, gdy się logują, np. „Ktoś próbował zalogować się na Twoje konto o 4:20 w środę bla, bla. Kliknij tutaj, jeśli to nie byłeś Ty”. Pozwala zachować statystyki dotyczące ataków. Możesz zintensyfikować monitorowanie i środki bezpieczeństwa, jeśli zauważysz nagły wzrost nieuczciwych dostępów.

patros
źródło
Dobre myśli. Zdecydowanie planowałem zaimplementować automatyczną politykę haseł, która zmienia się dynamicznie w zależności od poziomu uprawnień użytkownika. Pomysł na honeypot może zadziałać w przypadku niektórych typów ataku, ale jeśli atak jest rozproszony, blokowanie adresów IP, które do niego pasują, nie będzie skuteczne.
Jens Roland
Jeśli chodzi o „Czas ostatniej próby logowania”, jest to dobra strategia dla zaawansowanych użytkowników (założę się, że dlatego SO to robi), ale ma dwie słabości: (a) nie rozwiązuje problemu włamań, informuje tylko, że mogło się to wydarzyć, i (b) większość użytkowników po prostu nie pamięta / nie obchodzi
Jens Roland
1
Tak, honeypot i raportowanie użytkowników to raczej zbieranie informacji. Mogą dostarczyć cennych wskaźników, które pozwolą ci wiedzieć, czy / kiedy ma miejsce powolny atak brutalnej siły.
patros
2
Dla honeypot, nie traktując żadnej nieistniejącego użytkownika za podejrzaną być lepsze niż tylko za pomocą ustaloną listę znanych niebezpiecznych nazwy użytkownika? Chciałbyś uniknąć blokowania użytkowników, którzy błędnie wpisali swoją nazwę użytkownika i nie zauważyli literówki podczas kilkukrotnego ponawiania hasła, ale nadal uważam, że może to być cenne. Możesz nawet uniknąć niektórych „fałszywych alarmów”, tworząc duży filtr bloom lub podobną strukturę danych z wariantami prawidłowych nazw użytkowników, imion, nazwisk, nazw e-mail itp. W miarę dodawania użytkowników.
R .. GitHub PRZESTAŃ POMÓC W LODZIE
11

Jeśli dobrze rozumiem MO ataków siłowych, co najmniej jedna nazwa użytkownika jest sprawdzana w sposób ciągły.

Są dwie sugestie, których chyba jeszcze nie widziałem:

  • Zawsze myślałem, że standardową praktyką jest krótkie opóźnienie (około sekundy) po każdym błędnym logowaniu dla każdego użytkownika. To powstrzymuje brutalną siłę, ale nie wiem, jak długo sekundowe opóźnienie powstrzymałoby atak słownikowy. (słownik zawierający 10 000 słów == 10 000 sekund == około 3 godzin. Hmm. Za mało.)
  • zamiast spowolnienia całej witryny, czemu nie ograniczać nazw użytkowników. Przepustnica staje się coraz trudniejsza z każdą błędną próbą (chyba do pewnego limitu, więc prawdziwy użytkownik nadal może się zalogować)

Edycja : w odpowiedzi na komentarze dotyczące ograniczenia nazwy użytkownika: jest to ograniczenie specyficzne dla nazwy użytkownika bez względu na źródło ataku.

Jeśli nazwa użytkownika jest ograniczona, przechwycony zostanie nawet skoordynowany atak na nazwę użytkownika (wiele adresów IP, jedno zgadywanie na IP, ta sama nazwa użytkownika). Poszczególne nazwy użytkowników są chronione przez przepustnicę, nawet jeśli atakujący mogą wypróbować innego użytkownika / przepustkę w określonym czasie.

Z punktu widzenia atakującego, w czasie przerwy możesz zgadnąć po raz pierwszy 100 haseł i szybko wykryć jedno błędne hasło na konto. Możesz być w stanie odgadnąć tylko 50 sekund w tym samym okresie.

Z punktu widzenia konta użytkownika, złamanie hasła wciąż wymaga takiej samej średniej liczby prób, nawet jeśli domysły pochodzą z wielu źródeł.

Dla atakujących w najlepszym przypadku będzie to taki sam wysiłek, aby złamać 100 kont, co w przypadku jednego konta, ale ponieważ nie ograniczasz przepustowości w całej witrynie, możesz dość szybko zwiększyć przepustnicę.

Dodatkowe udoskonalenia:

  • wykryj adresy IP, które zgadują wiele kont - 408 Limit czasu żądania
  • wykryć adresy IP, które odgadują to samo konto - 408 Limit czasu żądania po dużej (powiedzmy 100) liczbie prób.

Pomysły na interfejs użytkownika (mogą być nieodpowiednie w tym kontekście), które mogą również zawęzić powyższe:

  • jeśli masz kontrolę nad ustawieniem hasła, pokazanie użytkownikowi, jak silne jest jego hasło, zachęca go do wybrania lepszego.
  • jeśli kontrolujesz stronę logowania , po niewielkiej (powiedzmy 10) liczbie zgadnięć jednej nazwy użytkownika, zaproponuj CAPTCHA.
Jamesh
źródło
Ograniczenie nazwy użytkownika i ograniczenie liczby adresów IP jest w porządku w przypadku ataków z użyciem stałej nazwy użytkownika lub stałego adresu IP, a ponadto sprawia, że ​​tradycyjne ataki słownikowe są niewykonalne. Ale jeśli napastnik ciągle zmienia nazwy użytkownika, wymknie się temu bez wyzwalania przepustnicy nazwy użytkownika. To właśnie chcę kontrować
Jens Roland
2
Dzięki za edycję, James. Teraz rozmawiamy. Podoba mi się pomysł 408. Jednak nawet przy ścisłym ograniczaniu nazw użytkowników botnet atakujący wielu użytkowników nadal działałby. Sprawdzanie 5000 najpopularniejszych haseł dla jednego użytkownika jest MNIEJ prawdopodobne, niż sprawdzenie pierwszego hasła w przypadku 5000 użytkowników
Jens Roland
Nie ma to jak paradoks urodzinowy. W dużej grupie wiele osób będzie używać niezabezpieczonych haseł, a jeden prawdopodobnie użyje dowolnego popularnego. Będzie też sporo osób takich jak ja, których nie złapie taki atak.
David Thornley
2
Właściwie być może będę musiał ponownie sprawdzić matematykę na moim poprzednim oświadczeniu. Po wykluczeniu N najpopularniejszych haseł, prawdopodobieństwo posiadania przez użytkownika hasła # (N + 1) może wzrosnąć na tyle, aby zrównoważyć różnicę. Chociaż krzywa jest prawdopodobnie wystarczająco stroma, aby tak się nie stało
Jens Roland,
9

Istnieją trzy czynniki uwierzytelniania:

  1. Użytkownik coś wie (np. Hasło)
  2. Użytkownik ma coś (np. Brelok)
  3. Użytkownik jest czymś (np. Skan siatkówki)

Zwykle witryny internetowe egzekwują tylko zasadę nr 1. Nawet większość banków egzekwuje tylko politykę 1. Zamiast tego polegają na podejściu „wie coś innego” do uwierzytelniania dwuskładnikowego. (IE: użytkownik zna swoje hasło i nazwisko panieńskie matki). Jeśli możesz, sposób na dodanie drugiego czynnika uwierzytelniania nie jest zbyt trudny.

Jeśli możesz wygenerować około 256 znaków losowości, możesz ułożyć to w tabeli 16 × 16, a następnie poprosić użytkownika o podanie wartości na przykład w tabeli komórki A-14. Gdy użytkownik zarejestruje się lub zmieni hasło, przekaż mu tabelę i powiedz, aby ją wydrukowali i zapisali.

Trudność w takim podejściu polega na tym, że gdy użytkownik zapomni hasła, jak to zrobi, nie można po prostu zaoferować standardowego „odpowiedz na to pytanie i wprowadź nowe hasło”, ponieważ jest to również podatne na użycie siły. Nie możesz też go zresetować i wysłać mu nową pocztą e-mail, ponieważ ich e-mail może również zostać naruszony. (Zobacz: Makeuseof.com i ich skradziona domena).

Innym pomysłem (który dotyczy kociąt) jest to, co BOA nazywa SiteKey (wydaje mi się, że jest to znak towarowy). Krótko mówiąc, użytkownik przesyła obraz podczas rejestracji, a kiedy próbuje się zalogować, poproś go o wybranie obrazu z 8 lub 15 (lub więcej) losowych. Tak więc, jeśli użytkownik przesyła zdjęcie swojego kociaka, teoretycznie tylko on wie dokładnie, które zdjęcie jest jego zdjęciem spośród wszystkich pozostałych kociąt (lub kwiatów czy cokolwiek). Jedyną prawdziwą podatnością na to podejście jest atak typu man-in-the-middle.

Jeszcze jeden pomysł (ale bez kociąt) polega na śledzeniu adresów IP, z których użytkownicy uzyskują dostęp do systemu, i wymaganiu od nich dodatkowego uwierzytelnienia (captcha, wybierz kotka, wybierz klucz z tej tabeli), gdy logują się z adresu, którego nie mają Wcześniej. Podobnie jak w Gmailu, pozwala użytkownikowi zobaczyć, skąd się ostatnio logował.

Edycja, nowy pomysł:

Innym sposobem weryfikacji prób logowania jest sprawdzenie, czy użytkownik przeszedł z Twojej strony logowania. Nie możesz sprawdzić stron odsyłających, ponieważ można je łatwo sfałszować. To, czego potrzebujesz, to ustawić klucz w zmiennej _SESSION, gdy użytkownik wyświetla stronę logowania, a następnie sprawdzić, czy klucz istnieje, gdy przesyłają swoje dane logowania. Jeśli bot nie przejdzie ze strony logowania, nie będzie mógł się zalogować. Możesz to również ułatwić, włączając w ten proces JavaScript, albo używając go do ustawienia pliku cookie, albo dodając pewne informacje do formularza po jego załadowaniu. Możesz też podzielić formularz na dwa różne przesłania (tj. Użytkownik wprowadza swoją nazwę użytkownika, przesyła, a następnie na nowej stronie wprowadza swoje hasło i przesyła ponownie).

Klucz w tym przypadku jest najważniejszy. Typową metodą ich generowania jest kombinacja danych użytkownika, jego adresu IP i czasu przesłania.

davethegr8
źródło
Jestem pewien, że jest w tym coś więcej, ale jeśli idea SiteKey jest dokładnie tym, o czym wspomniałeś, osoba atakująca nie musi być MITM, może po prostu uruchomić dwie lub trzy próby logowania dla tego użytkownika i wybrać obraz, który powtarza się wśród przypadkowych. Nawet jeśli zestaw 8-15 zdjęć jest statyczny dla użytkownika X,
Jens Roland
(ciąg dalszy) prawdopodobnie nie byłby zbyt trudny wybór właściwego, ponieważ ludzie zwykle wybierają przewidywalne typy obrazów (nawet obrazy z ich własnych albumów Flickr!)
Jens Roland
2
Tak, pomyślałem o tym, o czym wspomniałaś wczoraj wieczorem po moim powrocie do domu. Myślę, że sposobem na naprawienie tego jest: Kiedy użytkownik loguje się i podaje poprawne hasło, wyświetla jego obraz i kilka innych losowych. Jeśli nie podają poprawnego hasła, pokaż kilka losowych liczb
davethegr8
1
obrazy + 1, które mogą, ale nie muszą zawierać własnego obrazu. Miałem też inny pomysł, zobacz edycję w poście. Ale tak, te pomysły są trudne / skomplikowane.
davethegr8
1
To „mogłoby” zadziałać, ale widzę kilka problemów. Co się stanie, jeśli właściciel zdjęcia usunie zdjęcie? Jak możesz mieć pewność, że zwrócone obrazy nie będą obraźliwe dla Twojego użytkownika? W jaki sposób użytkownik zapamiętuje, gdzie kliknął? (Trudno to zapomnieć)
davethegr8
7

Wcześniej odpowiedziałem na bardzo podobne pytanie na temat Jak mogę ograniczyć próby logowania użytkownika w PHP . Powtórzę tutaj proponowane rozwiązanie, ponieważ uważam, że wielu z was uzna, że ​​zobaczenie rzeczywistego kodu będzie miało charakter informacyjny i użyteczny. Należy pamiętać, że użycie CAPTCHA może nie być najlepszym rozwiązaniem ze względu na coraz dokładniejsze algorytmy używane obecnie w busterach CAPTCHA:

Nie można po prostu zapobiec atakom DoS, ograniczając ograniczenie przepustowości do pojedynczego adresu IP lub nazwy użytkownika. Do diabła, nie możesz nawet naprawdę zapobiec szybkim próbom logowania przy użyciu tej metody.

Czemu? Ponieważ atak może obejmować wiele adresów IP i kont użytkowników w celu ominięcia prób ograniczenia przepustowości.

Widziałem opublikowane gdzie indziej, że najlepiej byłoby śledzić wszystkie nieudane próby logowania w witrynie i powiązać je z sygnaturą czasową, być może:

CREATE TABLE failed_logins(
    id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(16) NOT NULL,
    ip_address INT(11) UNSIGNED NOT NULL,
    attempted DATETIME NOT NULL
) engine=InnoDB charset=UTF8;

Decyduj o pewnych opóźnieniach na podstawie ogólnej liczby nieudanych logowań w danym czasie. Powinieneś oprzeć to na danych statystycznych pobranych z twojej failed_loginstabeli, ponieważ będą się one zmieniać w czasie w zależności od liczby użytkowników i liczby z nich może przypomnieć sobie (i wpisać) swoje hasło.


10 failed attempts = 1 second
20 failed attempts = 2 seconds
30 failed attempts = reCaptcha

Przeszukuj tabelę przy każdej nieudanej próbie logowania, aby znaleźć liczbę nieudanych logowań w danym okresie, powiedzmy 15 minut:


SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute);

Jeśli liczba prób w danym okresie przekracza Twój limit, wymuszaj ograniczanie lub zmuszaj wszystkich użytkowników do korzystania z captcha (tj. ReCaptcha), dopóki liczba nieudanych prób w danym okresie nie będzie mniejsza niż próg.

// array of throttling
$throttle = array(10 => 1, 20 => 2, 30 => 'recaptcha');

// assume query result of $sql is stored in $row
$sql = 'SELECT MAX(attempted) AS attempted FROM failed_logins';
$latest_attempt = (int) date('U', strtotime($row['attempted']));
// get the number of failed attempts
$sql = 'SELECT COUNT(1) AS failed FROM failed_logins WHERE attempted > DATE_SUB(NOW(), INTERVAL 15 minute)';
// assume the number of failed attempts was stored in $failed_attempts
krsort($throttle);
foreach ($throttle as $attempts => $delay) {
    if ($failed_attempts > $attempts) {
        // we need to throttle based on delay
        if (is_numeric($delay)) {
            $remaining_delay = time() - $latest_attempt - $delay;
            // output remaining delay
            echo 'You must wait ' . $remaining_delay . ' seconds before your next login attempt';
        } else {
            // code to display recaptcha on login form goes here
        }
        break;
    }
}

Korzystanie z reCaptcha na pewnym progu zapewniłoby zminimalizowanie ataku z wielu frontów, a zwykli użytkownicy witryny nie doświadczyliby znacznego opóźnienia w przypadku uzasadnionych nieudanych prób logowania. Nie mogę zagwarantować zapobiegania, ponieważ zostało już rozszerzone o to, że CAPTCHA można złamać. Istnieją alternatywne rozwiązania, być może wariant „Nazwij to zwierzę”, który może działać całkiem nieźle jako substytut.

Corey Ballou
źródło
6

Muszę zapytać, czy wykonałeś analizę kosztów i korzyści tego problemu; Wygląda na to, że próbujesz chronić się przed napastnikiem, który ma wystarczająco dużo obecności w sieci, aby odgadnąć liczbę haseł, wysyłając może 3-5 żądań na adres IP (ponieważ odrzuciłeś ograniczanie przepustowości IP). Ile (w przybliżeniu) kosztowałby ten rodzaj ataku? Czy jest droższa niż wartość kont, które próbujesz chronić? Ile gigantycznych botnetów chce tego, co masz?

Odpowiedź może brzmieć nie - ale jeśli tak, mam nadzieję, że otrzymujesz pomoc od jakiegoś specjalisty ds. Bezpieczeństwa; umiejętności programowania (i wynik StackOverflow) nie są silnie skorelowane z wiedzą o bezpieczeństwie.

ojrac
źródło
(Chcesz powiedzieć, że jeśli odpowiedź brzmi „nie” - tj. Że koszt ataku botnetu NIE jest zbyt wysoki w stosunku do kont)
Jens Roland
Ale w każdym razie poruszysz ważną kwestię. Na własne potrzeby nie spodziewam się, że jakikolwiek operator botnetu będzie się tym przejmował, ale udostępniam kod źródłowy każdemu, kto chciałby przyzwoicie zabezpieczyć swoją aplikację internetową i nie wiem, co inni mogą próbować chronić, lub kim są ich wrogowie
Jens Roland
Nie będzie strzegł narodowych tajemnic bez względu na wszystko (oficjalne systemy wymagają specjalnej certyfikacji i jestem prawie pewien, że nic zbudowanego w PHP nie może się kwalifikować), ale wszystkie aplikacje internetowe wymagają bezpiecznego uwierzytelniania, więc jeśli to wydam, to ” byłbym bardzo nie nieodpowiedzialne użycie najlepszych praktyk gdzie mogę
Jens Roland
1
Więc moja krótka odpowiedź brzmi: buduję to, ponieważ 99,9% witryn internetowych i aplikacji ma przerażające zabezpieczenia (nawet w dużych ligach: AOL, Twitter, Myspace były już wcześniej zagrożone), a w większości przypadków używając tandetnych bibliotek uwierzytelniania.
Jens Roland
Przeczytaj także artykuł „To Catch A Predator” autorstwa Nielsa Provosa i in. z postępowania USENIX w 2008 r. (link: usenix.org/events/sec08/tech/small.html ) Otwierają oczy: 2 miesiące, jeden miód: 368 000 ataków z prawie 30 000 różnych adresów IP pochodzących z ponad 5600 botnetów!
Jens Roland
5

Podsumowując schemat Jensa w pseudo-stanowym diagramie przejść / bazie reguł:

  1. użytkownik + hasło -> wpis
  2. użytkownik +! hasło -> odmowa
  3. użytkownik + znany_IP (użytkownik) -> drzwi frontowe, // never throttle
  4. użytkownik + nieznany adres IP (użytkownik) -> catflap
  5. (#denied> n) via catflaps (strona) -> throttle catflaps (strona) // slow the bots
  6. catflap + throttle + hasło + captcha -> wpis // humans still welcome
  7. catflap + throttle + hasło +! captcha -> denied // a correct guess from a bot

Obserwacje:

  • Nigdy nie blokuj przednich drzwi. Policja stanowa Elbonian ma twój komputer w twoim domu, ale nie może cię przesłuchać. Brute force to realne podejście z twojego komputera.
  • Jeśli podasz komunikat „Zapomniałeś hasła?” link, Twoje konto e-mail staje się częścią powierzchni ataku.

Te obserwacje dotyczą innego typu ataku niż te, którym próbujesz się przeciwstawić.

Jamesh
źródło
Oczywiście konto e-mail jest częścią powierzchni ataku. Mam zestaw górnych założeń dotyczących bezpieczeństwa, które zapewni moja strategia, a najniższym ograniczeniem jest bezpieczeństwo poczty elektronicznej użytkownika. Jeśli atakujący naruszy adres e-mail użytkownika, wszystkie zakłady zostaną anulowane.
Jens Roland
Myślę też, że twój diagram przejścia stanów wymaga kilku szczegółów: # 3 i # 4 powinny zawierać hasło; # 1 i # 2 powinny zawierać znane_IP (użytkownik), ponieważ login zawsze ma znany lub nieznany adres IP; a # 6 to „wejście pomimo gazu”
Jens Roland
4

Wygląda na to, że próbujesz się bronić przed powolną, rozproszoną brutalną siłą . Niewiele możesz z tym zrobić. Używamy PKI i nie logujemy się za pomocą hasła. To pomaga, ale jeśli Twoi klienci od czasu do czasu trafiają na stacje robocze, nie ma to zbyt dużego zastosowania.

Björn Raupach
źródło
Właściwie to też szybka brutalna siła. Miałem nadzieję, że będę nieco pobłażliwy w przypadku brutalnej siły ze stałym użytkownikiem (dławienie tylko przez 20 sekund), ale w witrynie z 50 tysiącami użytkowników, która umożliwiłaby szybką brutalną siłę użytkownika zmiennej (zakładając ponad 20 sekund na przełączanie się między użytkownikami). A to, jak mówią, byłoby do niczego…
Jens Roland
Cóż, szybka brutalna siła z jednego hosta, użyj iptables lub jakiejkolwiek zapory ogniowej, której używasz.
Björn Raupach
Miałem na myśli rozproszoną szybką brutalną siłę. To rzadkie, ale potencjalnie bardzo paskudne
Jens Roland
3

Zastrzeżenie: pracuję dla firmy dwuskładnikowej, ale nie jestem tutaj, aby to podłączyć. Oto kilka uwag.

Pliki cookie mogą zostać skradzione za pomocą XSS i wulgaryzmów przeglądarki. Użytkownicy często zmieniają przeglądarki lub usuwają pliki cookie.

Źródłowe adresy IP są jednocześnie dynamicznie zmienne i fałszywe.

Captcha jest przydatna, ale nie uwierzytelnia konkretnego człowieka.

Można z powodzeniem łączyć wiele metod, ale dobry smak z pewnością jest na porządku.

Złożoność haseł jest dobra, wszystko, co jest oparte na hasłach, zależy od haseł mających wystarczającą entropię. IMHO, silne hasło zapisane w bezpiecznej lokalizacji fizycznej jest lepsze niż słabe hasło w pamięci. Ludzie znacznie lepiej wiedzą, jak ocenić bezpieczeństwo dokumentów papierowych, niż potrafią obliczyć efektywną entropię w imieniu swojego psa, gdy jest ono używane jako hasło do trzech różnych witryn internetowych. Rozważ umożliwienie użytkownikom wydrukowania dużej lub małej strony pełnej jednorazowych kodów dostępu.

Pytania zabezpieczające, takie jak „jaka była twoja maskotka z liceum”, to przeważnie kolejna kiepska forma „czegoś, co znasz”. Większość z nich można łatwo odgadnąć lub są one ogólnie dostępne.

Jak zauważyłeś, ograniczanie nieudanych prób logowania jest kompromisem między zapobieganiem atakom brutalnej siły a łatwością DoSing konta. Agresywne zasady blokowania mogą odzwierciedlać brak zaufania do entropii hasła.

Osobiście i tak nie widzę korzyści z wymuszania wygaśnięcia hasła na stronie internetowej. Atakujący dostaje twoje hasło raz, może je potem zmienić i tak łatwo jak tylko możesz zastosować się do tej polityki. Być może jedną z korzyści jest to, że użytkownik może zauważyć wcześniej, jeśli osoba atakująca zmieni hasło do konta. Jeszcze lepiej byłoby, gdyby użytkownik został w jakiś sposób powiadomiony, zanim osoba atakująca uzyska dostęp. W tym względzie przydatne są komunikaty typu „N nieudanych prób od ostatniego logowania”.

Najlepsze bezpieczeństwo zapewnia drugi czynnik uwierzytelniania, który jest poza pasmem w stosunku do pierwszego. Jak powiedziałeś, tokeny sprzętowe w „czymś, co masz” są świetne, ale wiele (nie wszystkie) ma rzeczywiste koszty administracyjne związane z ich dystrybucją. Nie znam żadnych biometrycznych rozwiązań typu „coś, czym jesteś”, dobrych dla stron internetowych. Niektóre rozwiązania dwuskładnikowe współpracują z dostawcami OpenID, niektóre mają zestawy SDK PHP / Perl / Python.

Marsh Ray
źródło
Wszystkie doskonałe punkty - nie mogłem się bardziej zgodzić. Punkt dotyczący niepewności plików cookie jest bardzo ważny, ale bez drugiego składnika w postaci fizycznych tokenów lub haseł jednorazowych (rozsyłanych przez bezpieczną linię) naprawdę nie można chronić przed wrażliwym punktem końcowym. Jeśli skrzynka / przeglądarka użytkownika jest zagrożona, jego loginy również.
Jens Roland,
1

Moją najwyższą rekomendacją jest po prostu upewnienie się, że informujesz użytkowników o błędnych próbach logowania na ich konta - użytkownicy prawdopodobnie będą traktować siłę swojego hasła znacznie poważniej, jeśli zostaną przedstawione dowody, że ktoś faktycznie próbuje dostać się na ich konto .

Właściwie złapałem kogoś, kto włamał się na konto myspace mojego brata, ponieważ próbował dostać się na konto Gmail, które dla niego skonfigurowałem, i użył funkcji `` zresetuj moje hasło przez e-mail '' ... która trafiła do mojej skrzynki odbiorczej.

nvuono
źródło
1
  1. A co z wymaganiem hasła jednorazowego przed wprowadzeniem normalnego hasła? Czy to bardzo oczywiste, że ktoś atakował, zanim miał wiele okazji do odgadnięcia głównego hasła?

  2. Zachowaj globalną liczbę / wskaźnik nieudanych logowania - to wskaźnik ataku - podczas ataku bardziej rygorystycznie podchodź do błędów logowania, np. Szybciej blokuj adresy IP.

Douglas Leeder
źródło
1) Jak zaimplementowałbyś hasło jednorazowe na niezabezpieczonej, nieuwierzytelnionej linii? Innymi słowy, kiedy użytkownik ustawia te jednorazowe hasła? 2) Tak, to jest sedno # 4 na mojej liście, ogólnoświatowego limitu nieudanych prób. Wadą jest możliwość DoS, którą otwiera.
Jens Roland
0

Nie wierzę, że istnieje doskonała odpowiedź, ale byłbym skłonny podejść do niej na zasadzie próby zmylenia robotów w przypadku wykrycia ataku.

Nie mogę się doczekać:

Przełącz na alternatywny ekran logowania. Ma wiele pustych nazw użytkownika i haseł, które naprawdę się pojawiają, ale tylko jeden z nich jest we właściwym miejscu. Nazwy pól są RANDOM - klucz sesji jest wysyłany wraz z ekranem logowania, serwer może wtedy dowiedzieć się, jakie pola są jakie. Sukces lub porażka, jest następnie odrzucany, więc nie możesz spróbować powtórzyć ataku - jeśli odrzucisz hasło, otrzymają nowy identyfikator sesji.

Zakłada się, że każdy formularz, który zostanie przesłany z danymi w niewłaściwym polu, pochodzi od robota - logowanie nie powiodło się, kropka, a IP jest ograniczane. Upewnij się, że losowe nazwy pól nigdy nie pasują do prawidłowych nazw pól, aby ktoś, kto używa czegoś, co pamięta hasła, nie wprowadzał w błąd.

A co powiesz na inny rodzaj captcha: masz serię pytań, które nie spowodują problemów dla człowieka. Jednak NIE są one przypadkowe. Kiedy atak się rozpocznie, każdemu zadaje się pytanie # 1. Po godzinie pytanie nr 1 jest odrzucane i nigdy więcej nie może być użyte, a każdy otrzymuje pytanie nr 2 i tak dalej.

Atakujący nie może sondować w celu pobrania bazy danych, aby umieścić ją w swoim robocie z powodu jednorazowego charakteru pytań. Musi wysłać nowe instrukcje do swojego botnetu w ciągu godziny, aby móc cokolwiek zrobić.

Loren Pechtel
źródło
Szczerze mówiąc, alternatywny ekran logowania brzmi tak, jakby bardziej mylił ludzi niż maszyny. Zakładamy oczywiście, że atakujący wcześniej sprawdziłby nasze środki bezpieczeństwa. Mógł z łatwością dostosować swój skrobak, aby znaleźć prawidłowo ustawione pola.
Jens Roland
Pytania sprawdzające ludzi zostały już zrobione i nie są zbyt skuteczne. Dla ludzkiego operatora botnetu udzielanie odpowiedzi na jedno pytanie na godzinę (po którym nowa odpowiedź rozprzestrzeniłaby się do botów) podczas ataku byłoby całkiem wykonalne.
Jens Roland
Nie rozumiesz. Atakujący nie może sprawdzić z wyprzedzeniem, ponieważ pokazuje on tylko dodatkowe obrony, gdy pojawia się atak.
Loren Pechtel
Oczywiście, człowiek mógł zobaczyć, o co chodziło - ale musi to przekazać wszystkim swoim robotom. To ścieżka komunikacyjna, która ułatwia wyłączenie botnetu.
Loren Pechtel
Nie sądzę, żebym omijał sedno sprawy. Nie chodzi mi o to, że wcześniej przeprowadziłby atak, aby sprawdzić nasze środki bezpieczeństwa, chodzi mi o to, że przeczytałby ten wątek i sprawdził (otwarty) kod źródłowy, aby sprawdzić, czy nie ma wad :)
Jens Roland
0

Ponieważ kilka osób uwzględniło CAPTCHA jako awaryjny mechanizm ludzki, dodaję wcześniejsze pytanie StackOverflow i wątek na temat skuteczności CAPTCHA.

Czy reCaptcha został złamany / zhakowany / OCR / pokonany / uszkodzony?

Używanie CAPTCHA nie ogranicza ulepszeń związanych z dławieniem i innymi sugestiami, ale myślę, że liczba odpowiedzi, które zawierają CAPTCHA jako rezerwę, powinna uwzględniać metody oparte na ludziach dostępne dla osób, które chcą złamać zabezpieczenia.

Matthew Glidden
źródło
0

Możesz także ograniczyć przepustowość w oparciu o siłę hasła użytkownika.

Gdy użytkownik rejestruje lub zmienia swoje hasło, obliczasz jego siłę, powiedzmy od 1 do 10.

Coś w rodzaju „hasło” daje 1, podczas gdy „c6eqapRepe7et * Awr @ ch” może dać 9 lub 10, a im wyższy wynik, tym dłużej trwa dławienie.

Joseph W.
źródło
2
Rozumiem ten pomysł, ale pośrednio ujawniłoby to informacje o haśle, pozwalając napastnikowi wiedzieć, czy warto hakować hasło, czy nie. Może się to wydawać trochę teoretyczne, ale wielu użytkowników ponownie używa haseł, więc jeśli chcę włamać się do Strong_Throttling_Website.com, mogę po prostu zaatakować (uprzywilejowane) konta losowo, dopóki nie znajdę użytkownika `` Freddy '', który ma słabe hasło (tj. wczesne dławienie), a następnie przejdź do Less_Secure_Website.edu i wykonaj łatwy atak słownikowy na konto Freddy'ego. Jest to trochę skomplikowane, ale z pewnością wykonalne w praktyce.
Jens Roland
0

Pierwsza odpowiedź, jaką zwykle słyszę, zadając to pytanie, to zmiana portów, ale zapomnij o tym i po prostu wyłącz IPv4. Jeśli zezwolisz tylko klientom z sieci IPv6, nie będziesz już modlić się o proste skanowanie sieci, a atakujący będą uciekać się do wyszukiwań DNS. Nie uruchamiaj tego samego adresu co Twój Apache (AAAA) / Sendmail (MX-> AAAA) / co rozdałeś wszystkim (AAAA). Upewnij się, że twoja strefa nie może być xferd, czekaj, czy pozwolisz komuś na pobranie twojej strefy?

Jeśli boty wykryją, że twój serwer ustawia nowe nazwy hostów, po prostu dodaj jakiś bełkot do nazw hostów i zmień adres. Pozostaw stare nazwy, a nawet skonfiguruj ** honeypot names, aby bot net miał włączony limit czasu.

** Przetestuj swoje rekordy odwrotne (PTR) (w ip6.arpa.), Aby sprawdzić, czy można je wykorzystać do zerowania na / 4, które mają rekordy VS / 4, które ich nie mają. IE Zazwyczaj ip6.arpa miałby ~ 32 "." W adresie, ale próba z kilkoma brakującymi ostatnimi może ominąć bloki sieciowe, które mają rekordy, w przeciwieństwie do innych, które ich nie mają. Jeśli pójdziesz dalej, możliwe stanie się pominięcie dużych części przestrzeni adresowej.

W najgorszym przypadku użytkownicy będą musieli skonfigurować tunel IPv6, to nie jest tak, że musieliby posuwać się tak daleko, jak VPN do DMZ ... Chociaż można się zastanawiać, dlaczego nie jest to pierwsza opcja.

Również Kerberos jest fajny, ale IMHO LDAP wieje (Co jest technicznie nie tak z NISPlus? Czytałem, że Sun zdecydował, że użytkownicy chcą LDAP i przez to porzucili NIS +). Kerberos działa dobrze bez LDAP lub NIS, wystarczy zarządzać użytkownikami na hoście po hoście. Korzystanie z protokołu Kerberos zapewnia łatwy w użyciu, jeśli nie zautomatyzowany, PKI.

Mike Mestnik
źródło
0

Trochę późno tutaj, ale myślałem, zakładając trudny przypadek - atakujący używa wielu losowych adresów IP, losowych nazw użytkowników i losowego hasła wybranego z, powiedzmy, listy 10 000 najpopularniejszych.

Jedną rzeczą, którą możesz zrobić, zwłaszcza jeśli system wydaje się być atakowany, jest to, że w systemie jest wiele prób podania błędnego hasła, a zwłaszcza jeśli hasło ma niską entropię, to zadaj drugorzędne pytanie, na przykład jakie są imiona twoich rodziców . Jeśli atakujący trafi milion kont, próbując użyć hasła „password1”, istnieje duża szansa, że ​​dostanie dużo, ale ich szanse na uzyskanie prawidłowych nazw również dramatycznie zmniejszyłyby sukcesy.

Tychy 333
źródło