Brute-Force

von DaBu, am 18.07

Das Internet ist ein vermeintlich anonymer Raum, dass denken zumindest viele. Mit etwas geschick kann man durchaus anonym bleiben. Selbst wenn man es nicht darauf abzielt fühlen sich viele sehr Anonym. Dies kann bei Hass auf Webseitenbetreiber schnell zu einem Problem werden. Aus diesem Grund widmen wir uns dem Thema Brute-Force.

Was ist Brute-Force

Fangen wir aber erst einmal mit einer allgemeinen Erklärung an. Beim Brute-Force handelt es sich um eine Methode in der Informatik, welche durch Ausprobieren aller Möglichkeiten versucht etwas zu lösen. Das ganze hört sich jetzt vielleicht etwas abstrakt an, schauen wir uns deswegen doch einfach einmal ein Beispiel an.

Mögliches Szenario

Einige Spiele bieten Gutscheincodes an. Zum einen können Spieler selbst Codes generieren und diese an andere Spieler verschenken und zum anderen werden Codes vom Spielebetreiber erstellt für Werbeaktionen.

Ein findiger Spieler denkt sich nun. Da müssten sicher auch Codes im System sein, welche durch ausprobieren herausgefunden werden können. Ohne Brute-Force Schutz kann der Spieler nun automatisiert Gutscheincodes durchtesten und einlösen.

Der Schaden könnte dabei möglicherweise beachtlich ausfallen. Zum einen erhalten die falschen Personen hier Credits oder ähnliches und zum anderen verliert man so Spieler.

Was muss geschützt werden?

Es gibt viele Möglichkeiten, wo Brute-Force angewandt werden kann. Beispielsweise die gerade erwähnten Gewinncodes. Gleiches gilt aber auch für Login, Registrierung und die “Passwort vergessen” Funktion. Jede Stelle wo durch vielfaches probieren Informationen abgreifbar werden die so nicht herausgegeben werden sollen.

Bei Login, Registrierung und “Passwort vergessen” könnte man gezielt versuchen E-Mailadressen heraus zu finden. Explizit beim Login könnte auch versucht werden mit einem bereits bekannten Benutzernamen das Passwort zu erkennen.

Wie schütze ich meine Seite?

Die eine Lösung gibt es hierbei nicht. Man kann in unterschiedlichen Szenarien unterschiedliche Dinge kombinieren, um dem ganzen den Wind aus den Segeln zu nehmen. Deswegen gibt es nun ein paar Tipps. Dabei muss allerdings auch immer beachtet werden, dass ein paar Mechanismen selbst wieder andere Angriffsvektoren eröffnen könnten.

Grobe Aussagen treffen

Oft sieht man bei einem fehlerhaften Loginversuch eine Meldung, dass entweder der Benutzername oder das Passwort falsch waren. Damit versucht der Betreiber die Nutzerkonten besser zu schützen. Wenn einem weder Nutzername noch Passwort bekannt sind, dann ist die Chance einer erfolgreichen Brute-Force Attacke nahezu Null.

Etwas ähnliches gilt für die “Passwort vergessen” Funktion. Dort ist es unheimlich wichtig keine genaue Aussage zu treffen ob nun wirklich ein Treffer erzielt wurde oder nicht. Das heißt, man zeigt immer eine Meldung an, welche wie folgt lauten könnte.

Falls deine E-Mailadresse richtig war, dann wurde gerade eine Mail an dich versendet.

Damit hat der Angreifer keinerlei Chance E-Mailadressen abzugreifen.

IP-Adresse

Eine Möglichkeit Brute-Force Angriffen entgegenzuwirken ist es sich die IP-Adressen der letzten Versuche zu merken und bei zu vielen Fehlversuchen die IP-Adresse zu sperren.

Hierbei muss der Mechanismus zum Speichern und Prüfen schnell und schlank entwickelt werden, sonst schießt man sich selbst in das eigene Knie.

Zudem muss beachtet werden, dass die Zugriffe einer IP-Adresse sehr unterschiedlich ausfallen können. Aus einer Firma oder einem Universitätsnetzwerk werden mehr natürliche Fehlversuche stattfinden, als von einem privaten Haushalt aus.

Proxys machen das ganze wiederum noch schwieriger. Zum einen können viele Leute einen Proxy nutzen und zum anderen könnte eine Person bewusst viele Proxys für einen Brute-Force Angriff nutzen.

Captcha

Eine sehr gute und schwer zu umgehende Methode für Brute-Force Angriffe sind Captchas. Viele Seitenbetreiber schrecken davor zurück sie einzusetzen, um mögliche Nutzer nicht zu vergraulen. Der Nutzen von Captchas ist bei gezieltem Einsatz aber immer sinnvoll.

Eine kleine Empfehlung ist da das reCAPTCHA von Google, da dieses zumindest bei den ersten Versuchen ziemlich angenehm zu benutzen ist und so weniger Leute abschreckt. Der entscheidende Nachteil ist der Datenschutz, da Google die Daten in die USA überträgt.

Alternativ können selbst gehostete Captchas genutzt werden.

Account sperren

Weiter gibt es die Möglichkeit bei einem Brute-Force Angriff auf einen Account diesen zu sperren, damit der Angreifer nicht doch noch irgendwie an den Account kommt. Es könnte durchaus sein, dass der Besitzer ein eher mäßiges Passwort gewählt hat.

Wenn der Account gesperrt ist, muss dies allerdings im Login sichtbar gemacht werden, falls sich der echte Nutzer versucht einzuloggen.

Damit eröffnen wir direkt zwei neue Angriffsvektoren. Zum einen erkennt der Angreifer so, ob es einen Account wirklich gibt und zum anderen kann der Angreifer so jedes ihm bekannte Konto blockieren. Das funktioniert im übrigen super beim Onlinebanking.

Der Account kann wahlweise auf Zeit oder dauerhaft gesperrt werden, bis der Nutzer diesen per Mail wieder freischaltet.

UserAgent untersuchen

Eine viel zu offensichtliche Tatsache ist, dass viele Brute-Force Angriffe von irgendwelchen ahnungslosen ausgeführt werden. Diese laden sich irgendwo ein Script und legen dann los. Dabei passiert es immer wieder, dass im UserAgent etwas steht, was ein üblicher Nutzer nicht hat.

Oft findet man UserAgents wie “curl”, “Guzzle”, “Wget” oder “Google-HTTP-Java-Client”. Erkennt man einen von diesen UserAgents kann man den Aufruf verwerfen oder gezielt in die Irre leiten.

Cookie setzen

Das Setzen von Cookies sollte nicht unerwähnt bleiben, allerdings eher aus dem Grund, dass es wenig Sinnvoll ist dies als Schutz zu nutzen. Bei einem Brute-Force Angriff werden keinerlei Daten aus einem vorherigen Versuch übernommen. Es mag in ganz bestimmten Einzelfällen sein, trotzdem sollte man keine Zeit damit verschwenden.

Wartezeit

Brute-Force Angriffe lohnen sich meist nur in größeren Mengen. Setzt man etwa bei jedem Login Versuch aber eine Wartezeit von einer Sekunde, so wird der Angreifer erheblich ausgebremst.

usleep(500000); // 0,5 Sekunden warten
sleep(1); // Eine Sekunde warten

Diese Methode ist allerdings ein Spiel mit dem Feuer. Durch die Wartezeit können sich bei vielen Versuchen die Anfragen stauen. Da ein Webserver immer ein Limit an Anfragen abarbeiten kann, könnte man dies auch gegen die Seite ausspielen. Dann lässt der Angreifer vielleicht von einem Brute-Force Angriff ab und legt lieber die Seite auf Eis.

Durch eine Parallelisierung der Angriffe kann die Wartezeit schnell indirekt umgangen werden. Wenn die Anfrage immer eine Sekunde warten muss, schickt man stattdessen direkt tausend auf einmal.

Einen Mittelweg finden

Wir kennen jetzt einige Möglichkeiten mit Brute-Force Angriffen umzugehen. Am besten wählt man immer eine Kombination aus mehreren Dingen.

Möglicherweise zeigen wir Nutzern mit uns unbekannten UserAgents immer direkt ein Captcha an. Alle anderen sehen dieses erst, wenn sie über eine IP-Adresse 5 Fehlversuche hatten.

Alternativ könnte man bei zu vielen Fehlversuchen über eine IP-Adresse die gesamte Seite für die IP-Adresse für einige Minuten sperren. Die Anfrage einer gesperrten IP-Adresse würde direkt abgearbeitet werden und den Server nicht sehr belasten. Der Mögliche Brute-Force Angriff ist damit abgewendet.

Implementierung

Zum Beginn unseres Seitenaufrufes schreiben wir in dem Memcache die Information, dass nun eine Person mehr (+1) von der IP-Adresse aus zugreift. Am Ende unseres Scriptes reduzieren wir diese Zahl wieder.

Wichtig ist, dass wir dies mit einem Key-Value Store lösen. Zum Beispiel Memcache oder Redis. Diese sind zum einen extrem effizient und schnell und zum anderen ist es wichtig die Daten noch vor dem Hochfahren der eigentlichen Anwendung zu erheben.

Zu Beginn haben wir 2 Methoden, eine davon wird direkt aufgerufen. Die andere wird für das Herunterfahren angemeldet. Das heißt, diese wird immer beim Beenden des PHP Prozesses mit aufgerufen.

function startupBruteforceDetect()
{
    $uniqueKey = 'applicationname_bruteforce_blocking_';
    $ipAdress = $_SERVER['REMOTE_ADDR'];

    $memcache = new Memcache;
    $memcache->connect('memcache_host', 11211);

    $memcache_obj->increment($uniqueKey.$ipAdress, 1);
}

function shutdownBruteforceDetect()
{
    $uniqueKey = 'applicationname_bruteforce_blocking_';
    $ipAdress = $_SERVER['REMOTE_ADDR'];

    $memcache = new Memcache;
    $memcache->connect('memcache_host', 11211);
    $count = $memcache->decrement($uniqueKey.$ipAdress, 1);
}
startupBruteforceDetect();
register_shutdown_function('shutdownBruteforceDetect');

Das Auslesen des aktuellen Werts könnte wie folgt aussehen.

$uniqueKey = 'applicationname_bruteforce_blocking_';
$ipAdress = $_SERVER['REMOTE_ADDR'];

$memcache = new Memcache;
$memcache->connect('memcache_host', 11211);
$count = $memcache->get($uniqueKey.$ipAdress);

if(is_empty($count) || $count < 1) {
    $count = 0;
}

echo $count;

Es handelt sich hierbei um Beispielcode, welcher nicht abgesichert ist. Weder werden mögliche Fehler abgefangen noch werden externe Eingaben validiert und abgesichert.

Danke

Ich hoffe, jeder kann aus diesem Artikel etwas für die weitere Entwicklung seiner Anwendung mitnehmen. Zu Beginn ist es immer erst einmal wichtig sich bewusst zu werden, dass Brute-Force ein Problem sein kann und später muss entsprechend gehandelt werden.

Werbung