Anti bruteforce bij inloggen
Door Chris , 1 jaar geleden, 6.029x bekeken
Een veelgestelde vraag op het forum is hoe je het beste een anti bruteforce kan maken, zodat mensen niet meer door middel van brute kracht kunnen inloggen op bijvoorbeeld administratiesystemen.
Op de volgende pagina leg ik (in het kort) uit wat de beste manier hiervoor is.
Let op; dit is een korte tutorial en géén script. Je moet dit alsnog zélf implementeren in jouw systeem.
Er is overigens een kort onderzoek gedaan onder een aantal (grote) Nederlandse websites. Ik was namelijk erg nieuwsgierig hoe zij dit hadden opgelost. De resultaten: Onderzoek naar bruteforce op grote websites
Gesponsorde koppelingen
Inhoudsopgave
40 reacties op 'Anti bruteforce bij inloggen'
Gesponsorde koppelingen
Nu zou ik dus met een random set usernames en passwords alsnog miljoenen pogingen kunnen doen?
Verder nog wat grammaticale fouten.. "Dat betekend dus dat wanneer een bezoeker x aantal keer heeft geprobeerd om in te loggen" en "Dit betekend dat de gebruiker een flink arsenaal aan IP-adressen nodig heeft om in te loggen."
In beide gevallen schrijf je "betekend" met een t (betekent), tegenwoordige tijd :)
Verder nog wat grammaticale fouten.. "Dat betekend dus dat wanneer een bezoeker x aantal keer heeft geprobeerd om in te loggen" en "Dit betekend dat de gebruiker een flink arsenaal aan IP-adressen nodig heeft om in te loggen."
In beide gevallen schrijf je "betekend" met een t (betekent), tegenwoordige tijd :)
Goed plan! Alleen één klein probleem erbij:
Wat nou als ik gewoon wil inbreken en het me niet gaat om een bepaalde user?
Dan kan ik alsnog alle usernames af gaan met standaard wachtwoorden als 123456, password, trustno1 en geheim. Genoeg mensen die een van deze wachtwoorden heeft. (dit zei Mar cel ook al ongeveer)
Maar ik denk dat dit niet is tegen te gaan (tenzij je dus mensen gaat blokkeren als een type wachtwoord vaak gefaald heeft...). Wat dan wel weer kan betekenen dat ze een melding krijgen: probeer een beter wachtwoord te kiezen...
Wat nou als ik gewoon wil inbreken en het me niet gaat om een bepaalde user?
Dan kan ik alsnog alle usernames af gaan met standaard wachtwoorden als 123456, password, trustno1 en geheim. Genoeg mensen die een van deze wachtwoorden heeft. (dit zei Mar cel ook al ongeveer)
Maar ik denk dat dit niet is tegen te gaan (tenzij je dus mensen gaat blokkeren als een type wachtwoord vaak gefaald heeft...). Wat dan wel weer kan betekenen dat ze een melding krijgen: probeer een beter wachtwoord te kiezen...
Tja, ik heb zelf in een project een wachtwoord-rate-script gemaakt. Wachtwoorden hebben minimaal 6 karakters nodig (minder wordt niet geaccepteerd). Naast het veld staat vervolgens hoe sterk het wachtwoord is, op basis van het aantal tekens, het aantal cijfers, hoofdletters en symbolen. Verder is het goed mogelijk om, net als bijvoorbeeld twitter, makkelijk te raden wachtwoorden te blokkeren. Op die manier forceer je een gebruiker een fatsoenlijk wachtwoord te kiezen. Dat, in combinatie met het blokkeren van een account, werkt uitstekend :)
@chris,
Ik had een tweetal vragen m.b.t. tot dit alles in het 'beveiliging' topic gezet ik zal ze hier ook maar even stellen.
Ik heb je Bruteforce protectie tut gelezen, beste is dus de combo DB en IP checken.
Ik heb wel 2 vraagjes.
1) Hoe pak je dit slim aan als je inlog systeem op file basis is en er geen MySQL beschikbaar is?
2) Heb je een 'voorbeeld' script hoe een DB/IP checker eruit kan zien?
Ik had een tweetal vragen m.b.t. tot dit alles in het 'beveiliging' topic gezet ik zal ze hier ook maar even stellen.
Ik heb je Bruteforce protectie tut gelezen, beste is dus de combo DB en IP checken.
Ik heb wel 2 vraagjes.
1) Hoe pak je dit slim aan als je inlog systeem op file basis is en er geen MySQL beschikbaar is?
2) Heb je een 'voorbeeld' script hoe een DB/IP checker eruit kan zien?
Bruteforce succesvol ingebracht.
Als iemand vijf keer in 1 kwartier een verkeerd wachtwoord ingeeft, wordt het account geblokkeerd voor 15 minuten.
Als de gebruiker dan weer kan inloggen, krijgt hij een melding dat hij via 'ip' adres heeft proberen in te loggen. En ook dat dit een hack poging zou kunnen zijn.
Zou ik het ip-adres dan ook 15 minuten op non-actief plaatsen? Zodat hij de website niet kan bezoeken?
Dem
Als iemand vijf keer in 1 kwartier een verkeerd wachtwoord ingeeft, wordt het account geblokkeerd voor 15 minuten.
Als de gebruiker dan weer kan inloggen, krijgt hij een melding dat hij via 'ip' adres heeft proberen in te loggen. En ook dat dit een hack poging zou kunnen zijn.
Zou ik het ip-adres dan ook 15 minuten op non-actief plaatsen? Zodat hij de website niet kan bezoeken?
Dem
@Dem,
Is dat niet heel extreem? Wat nu als je een site voor een schilder hebt gemaakt en die weet zijn wachtwoord niet precies meer.
Dan zou hij dus ook gelijk zijn eigen site niet eens meer kunnen bezichtigen, lijkt me persoonlijk een beetje strikt niet?
Het gaat toch echter om een bruteforce op een inlog te verkomen?
Is dat niet heel extreem? Wat nu als je een site voor een schilder hebt gemaakt en die weet zijn wachtwoord niet precies meer.
Dan zou hij dus ook gelijk zijn eigen site niet eens meer kunnen bezichtigen, lijkt me persoonlijk een beetje strikt niet?
Het gaat toch echter om een bruteforce op een inlog te verkomen?
@Dem,
Klopt 15min om niet meer te mogen inloggen zodat je verkomt dat mensen gaan bruteforcen, toch niet dat mensen gelijk de hele site niet meer mogen zien (ongeacht het tijdsbestek)?
Wie vraagt er gelijk z'n wachtwoord op na de eerste, tweede of misschien wel derde mislukking? Dat zijn er heel weinig, de meeste proberen eerst een paar keer voordat ze een procedure moeten volgen om een ww te resetten of opvragen.
Echter dit is mijn persoonlijke mening, ik vind gelijk een ban van de hele site een beetje te, aangezien het een bruteforce protectie is.
Klopt 15min om niet meer te mogen inloggen zodat je verkomt dat mensen gaan bruteforcen, toch niet dat mensen gelijk de hele site niet meer mogen zien (ongeacht het tijdsbestek)?
Wie vraagt er gelijk z'n wachtwoord op na de eerste, tweede of misschien wel derde mislukking? Dat zijn er heel weinig, de meeste proberen eerst een paar keer voordat ze een procedure moeten volgen om een ww te resetten of opvragen.
Echter dit is mijn persoonlijke mening, ik vind gelijk een ban van de hele site een beetje te, aangezien het een bruteforce protectie is.
@Jan,
Dit is van Wiki
Dit is van Wiki
Quote:
Voorbeeld: We hebben de mogelijkheid om in een wachtwoord alleen cijfers en alle kleine letters van het alfabet te gebruiken (dus 26 + 10 = 36 verschillende karakters) en het wachtwoord is maximaal 6 posities lang. Dan duurt het circa 366/3000000 = 725,6 seconden voordat dit wachtwoord is geraden. Indien men uitgaat van de 95 (alle karakters op het toetsenbord) dan duurt het reeds 956/3000000 = 245.030 seconden, wat overeenkomt met 68 uur
Dus als je iemand wilt pesten, log dan een bepaald aantal keren fout in op het account dat je geblokkeerd wilt hebben. Dan komt de echte eigenaar er dus ook niet op zolang jij fout inlogt en dus steeds het account opnieuw blokkeert!
Het lijkt me dus nog steeds een niet waterdichte oplossing die in deze tutorial staat.
Het lijkt me dus nog steeds een niet waterdichte oplossing die in deze tutorial staat.
@Jan Terhuijzen
Daarop is het antwoord ja. Maar heb jij anders een waterdichte oplossing die wij zouden kunnen gebruiken?
Maar als jij (voorbeeld) altijd hetzelfde ip-adres gebruikt, kan een admin waarschijnlijk wel een ip-ban geven.
Wat je eventueel wel zou kunnen doen is een script bouwen die een link verstuurd naar de gebruiker om de teller terug op nul te zetten of om éénmalig te laten inloggen.
Daarop is het antwoord ja. Maar heb jij anders een waterdichte oplossing die wij zouden kunnen gebruiken?
Maar als jij (voorbeeld) altijd hetzelfde ip-adres gebruikt, kan een admin waarschijnlijk wel een ip-ban geven.
Wat je eventueel wel zou kunnen doen is een script bouwen die een link verstuurd naar de gebruiker om de teller terug op nul te zetten of om éénmalig te laten inloggen.
Een truucje dat ik standaard toepas in mijn scripts:
Dit resulteerd in 2 oplossingen:
1. Je kunt geen data anoniem (zonder SESSION) post'en, wat zorgt voor bescherming tegen de meeste bots.
2. De 'back'-knop in je browser 'flipt' nooit meer nadat je een formulier hebt gepost (je post niet de data opnieuw).
Code (php)
Dit resulteerd in 2 oplossingen:
1. Je kunt geen data anoniem (zonder SESSION) post'en, wat zorgt voor bescherming tegen de meeste bots.
2. De 'back'-knop in je browser 'flipt' nooit meer nadat je een formulier hebt gepost (je post niet de data opnieuw).
@Sander
Klopt, bij het versturen van POST data heb je altijd een extra page request.
De extra veiligheid weegt in mijn ogen wel op tegen deze extra request; ook omdat het post'en van data binnen een website maar een fractie van alle requests betreft (95%+ van de page request bevat geen post data, en de redirect vindt alleen plaats als de request post data bevat)
Klopt, bij het versturen van POST data heb je altijd een extra page request.
De extra veiligheid weegt in mijn ogen wel op tegen deze extra request; ook omdat het post'en van data binnen een website maar een fractie van alle requests betreft (95%+ van de page request bevat geen post data, en de redirect vindt alleen plaats als de request post data bevat)
@Chris NVT
De Wiki-pagina die je aanhaalde gaat ervan uit dat je 3 miljoen combinaties per seconde kunt testen. Als je de beschikking hebt over het gecrypte/gehashte wachtwoord dan lukt dat wel, maar als je het wachtwoord moet checken via een webserver dan is dat bij de meeste sites fysiek onmogelijk. En bij de sites waar het misschien wel mogelijk zou zijn (als die al bestaan) is het een logistieke prestatie.
Zelf zou ik bij elke inlogpoging een vertraging van een seconde inbouwen. Dat is voor een normale gebruiker acceptabel en een brute-force van een wachtwoord van 6 tekens kost tussen de 69 en 23000 jaar. Eventueel zou je na 3 mislukte inlogpogingen de vertraging met steeds een seconde kunnen verhogen (tot een maximum van 10 seconden of zo). Dat vertraagt zoveel dat brute-forcen niet interessant meer is.
De Wiki-pagina die je aanhaalde gaat ervan uit dat je 3 miljoen combinaties per seconde kunt testen. Als je de beschikking hebt over het gecrypte/gehashte wachtwoord dan lukt dat wel, maar als je het wachtwoord moet checken via een webserver dan is dat bij de meeste sites fysiek onmogelijk. En bij de sites waar het misschien wel mogelijk zou zijn (als die al bestaan) is het een logistieke prestatie.
Zelf zou ik bij elke inlogpoging een vertraging van een seconde inbouwen. Dat is voor een normale gebruiker acceptabel en een brute-force van een wachtwoord van 6 tekens kost tussen de 69 en 23000 jaar. Eventueel zou je na 3 mislukte inlogpogingen de vertraging met steeds een seconde kunnen verhogen (tot een maximum van 10 seconden of zo). Dat vertraagt zoveel dat brute-forcen niet interessant meer is.
@Willem,
Even een oude koe uit de sloot gevist? Haha, maar je zit er naast, een 6 karakter password doet er nooit van zijn leven minimaal 69 jaar over!
Voor alle 95 karakters op je toetsenbord en het wachtwoord is 6 karakters lang duurt het 68 uur.
Check de Wiki link maar even.
Tevens is dit niet onmogelijk, hackers en hackersgroepen gebruiken hiervoor botnets, dat zijn dus veel pc's van onwetende die gebruikt worden voor hun rekenkracht.
Tevens is brute force een andere naam voor een dictionary attack, er wordt gewoon als een gek wachwoorden losgelaten op het inlog gedeelte. Al die wachtwoorden komen uit een database. Hoe wil je dat anders doen? Met de hand het wachtwoord in typen? Dan haalt een A+ type cursist misschien 1 ww per seconden.
Even een oude koe uit de sloot gevist? Haha, maar je zit er naast, een 6 karakter password doet er nooit van zijn leven minimaal 69 jaar over!
Voor alle 95 karakters op je toetsenbord en het wachtwoord is 6 karakters lang duurt het 68 uur.
Check de Wiki link maar even.
Tevens is dit niet onmogelijk, hackers en hackersgroepen gebruiken hiervoor botnets, dat zijn dus veel pc's van onwetende die gebruikt worden voor hun rekenkracht.
Tevens is brute force een andere naam voor een dictionary attack, er wordt gewoon als een gek wachwoorden losgelaten op het inlog gedeelte. Al die wachtwoorden komen uit een database. Hoe wil je dat anders doen? Met de hand het wachtwoord in typen? Dan haalt een A+ type cursist misschien 1 ww per seconden.
@Chris,
Lees wat ik zeg. ;-) Als je een vertraging van een seconde inbouwt, doe je er bij een dictionary van 36 tekens 36^6 = 2176782336 seconden over. Dat delen door 86400 en nog eens door 365,25 geeft 68,9 jaar. Hetzelfde rekensommetje bij 95 karakters geeft 23293 jaar plus was cijfers achter de komma, maar die zijn dan niet meer zo relevant...
Die vertraging kun je het meest effectief realiseren door een timestamp op te slaan in je database. Als er in die seconde al een inlogpoging is gedaan => error of een seconde wachten en nog eens proberen. Botnet of geen botnet, meer dan 1 inlogpoging per seconde is dan gewoonweg niet mogelijk.
En betreffende het botnet: dat schaalt ook niet onbeperkt. Het botnet zelf schaalt in ieder geval beter dan de verwerkingscapaciteit van de webserver. Elke connectie naar je webserver geeft een worker-proces. Elk worker-proces kost geheugen en veroorzaakt een connectie naar de database.
Een goed getunede MySQL-server die een heleboel RAM heeft zou zo'n 10000 simultane connecties kunnen hebben, mits de belasting per connectie niet al te zwaar is (ik reken inloggen voor het gemak tot de lichte taken). Als die server 10000 inlogpogingen per minuut kan verwerken, zou je er tussen de 2,5 dag en 2,5 jaar over doen (echter, als je de truuk uitvoert die ik hierboven heb beschreven, werkt dat dus niet).
Laten we nog steeds even uitgaan van die 10000 connecties. MySQL kan dat hebben, maar dan hebben we ook nog Apache. Die zou dan 10000 worker threads moeten hebben. Dat vergt een gigantische puist RAM. Als die servers ook nog eens hun requests naar een logfile moeten schrijven gaat het mis. Er kan namelijk maar één worker tegelijk schrijven. De rest staat dan in de state 'waiting for disk access'. Er zit dus ergens een praktische limiet aan het aantal connecties, en ik verwacht die eerder bij de webserver dan bij de database. Om die 3 miljoen checks per seconde te halen heb je een serverpark à la Google of Facebook nodig. Bij de meeste andere webservers (en zeker wanneer het shared hosting betreft) wordt een brute force al snel een DDOS-attack. ;-)
Zelf merk in in de praktijk dat een dedicated Apache-server met 500 workers (die allemaal een db-query uitvoeren) er al moeite mee begint te krijgen om de requests binnen een seconde af te handelen.
Lees wat ik zeg. ;-) Als je een vertraging van een seconde inbouwt, doe je er bij een dictionary van 36 tekens 36^6 = 2176782336 seconden over. Dat delen door 86400 en nog eens door 365,25 geeft 68,9 jaar. Hetzelfde rekensommetje bij 95 karakters geeft 23293 jaar plus was cijfers achter de komma, maar die zijn dan niet meer zo relevant...
Die vertraging kun je het meest effectief realiseren door een timestamp op te slaan in je database. Als er in die seconde al een inlogpoging is gedaan => error of een seconde wachten en nog eens proberen. Botnet of geen botnet, meer dan 1 inlogpoging per seconde is dan gewoonweg niet mogelijk.
En betreffende het botnet: dat schaalt ook niet onbeperkt. Het botnet zelf schaalt in ieder geval beter dan de verwerkingscapaciteit van de webserver. Elke connectie naar je webserver geeft een worker-proces. Elk worker-proces kost geheugen en veroorzaakt een connectie naar de database.
Een goed getunede MySQL-server die een heleboel RAM heeft zou zo'n 10000 simultane connecties kunnen hebben, mits de belasting per connectie niet al te zwaar is (ik reken inloggen voor het gemak tot de lichte taken). Als die server 10000 inlogpogingen per minuut kan verwerken, zou je er tussen de 2,5 dag en 2,5 jaar over doen (echter, als je de truuk uitvoert die ik hierboven heb beschreven, werkt dat dus niet).
Laten we nog steeds even uitgaan van die 10000 connecties. MySQL kan dat hebben, maar dan hebben we ook nog Apache. Die zou dan 10000 worker threads moeten hebben. Dat vergt een gigantische puist RAM. Als die servers ook nog eens hun requests naar een logfile moeten schrijven gaat het mis. Er kan namelijk maar één worker tegelijk schrijven. De rest staat dan in de state 'waiting for disk access'. Er zit dus ergens een praktische limiet aan het aantal connecties, en ik verwacht die eerder bij de webserver dan bij de database. Om die 3 miljoen checks per seconde te halen heb je een serverpark à la Google of Facebook nodig. Bij de meeste andere webservers (en zeker wanneer het shared hosting betreft) wordt een brute force al snel een DDOS-attack. ;-)
Zelf merk in in de praktijk dat een dedicated Apache-server met 500 workers (die allemaal een db-query uitvoeren) er al moeite mee begint te krijgen om de requests binnen een seconde af te handelen.
Om te reageren heb je een account nodig en je moet ingelogd zijn.


PHP hulp
0 seconden vanaf nu