Maison > Article > développement back-end > Sécurité PHP - Attaque par force brute
L'attaque par force brute est une méthode d'attaque qui épuise toutes les possibilités sans utiliser de moyens particuliers. Son nom plus formel est une attaque exhaustive – une attaque qui épuise toutes les possibilités.
Pour le contrôle d’accès, une attaque par force brute typique implique un attaquant essayant de se connecter au système via un grand nombre de tentatives. Dans la plupart des cas, le nom d’utilisateur est connu et il suffit de deviner le mot de passe.
Bien qu'il n'y ait aucune compétence dans les attaques par force brute, il semble y avoir une certaine compétence dans les attaques par dictionnaire. La plus grande différence réside dans l’intelligence nécessaire pour faire des suppositions. Les attaques par dictionnaire n’épuisent que la liste des situations les plus probables, plutôt que d’épuiser toutes les situations possibles comme les attaques par force brute.
Empêcher les tentatives de vérification ou limiter le nombre d'erreurs autorisées est une mesure de sécurité relativement efficace, mais le dilemme est de savoir comment identifier et bloquer les attaquants sans affecter les utilisateurs légitimes.
Dans ce cas, une détermination de cohérence peut vous aider à différencier les deux. Cette méthode est très similaire à la méthode de prévention du détournement de session décrite au chapitre 4, mais la différence est que vous souhaitez identifier un attaquant plutôt qu'un utilisateur légitime.
Considérez le formulaire HTML suivant :
CODE: <form action="http://example.org/login.php" method="POST"> <p>Username: <input type="text" name="username" /></p> <p>Password: <input type="password" name="password" /></p> <p><input type="submit" /></p> </form>
L'attaquant sera vérifiez ce formulaire et créez un script pour POSTER les données légales sur http://www.php.cn/ :
CODE: <?php $username = 'victim'; $password = 'guess'; $content = "username=$username&password=$password"; $content_length = strlen($content); $http_request = ''; $http_response = ''; $http_request .= "POST /login.php HTTP/1.1\r\n"; $http_request .= "Host: example.org\r\n"; $http_request .= "Content-Type: application/x-www-form-urlencoded\r\n"; $http_request .= "Content-Length: $content_length\r\n"; $http_request .= "Connection: close\r\n"; $http_request .= "\r\n"; $http_request .= $content; if ($handle = fsockopen('example.org', 80)) { fputs($handle, $http_request); while (!feof($handle)) { $http_response .= fgets($handle, 1024); } fclose($handle); /* Check Response */ } else { /* Error */ } ?>
Avec ce script, l'attaquant peut aussi simplement ajouter une boucle pour continuer à essayer différents mots de passe et vérifier la variable $http_response après chaque tentative. Une fois la variable $http_response modifiée, on peut considérer que le bon mot de passe a été deviné.
Il existe de nombreuses mesures de sécurité que vous pouvez prendre pour empêcher ce type d'attaque. Nous avons remarqué que lors d’une attaque par force brute, chaque requête HTTP est exactement la même à l’exception du mot de passe, qui est très précieux.
Bien que le gel temporaire des comptes après un certain nombre de tentatives infructueuses constitue une défense efficace, vous souhaiterez peut-être envisager une approche plus déterministe du gel des comptes afin que les attaquants aient moins de capacité à affecter l'accès des utilisateurs légitimes à votre application.
Il existe également des processus qui peuvent rendre une attaque par force brute plus difficile, la rendant ainsi moins susceptible de réussir. Un simple mécanisme de confinement peut le faire efficacement :
CODE: <?php /* mysql_connect() */ /* mysql_select_db() */ $clean = array(); $mysql = array(); $now = time(); $max = $now - 15; $salt = 'SHIFLETT'; if (ctype_alnum($_POST['username'])) { $clean['username'] = $_POST['username']; } else { /* ... */ } $clean['password'] = md5($salt . md5($_POST['password'] . $salt)); $mysql['username'] = mysql_real_escape_string($clean['username']); $sql = "SELECT last_failure, password FROM users WHERE username = '{$mysql['username']}'"; if ($result = mysql_query($sql)) { if (mysql_num_rows($result)) { $record = mysql_fetch_assoc($result); if ($record['last_failure']> $max) { /* Less than 15 seconds since last failure */ } elseif ($record['password'] == $clean['password']) { /* Successful Login */ } else { /* Failed Login */ $sql = "UPDATE users SET last_failure = '$now' WHERE username = '{$mysql['username']}'"; mysql_query($sql); } } else { /* Invalid Username */ } } else { /* Error */ } ?>
Limiter la dernière réunion ordinaire à la dernière fois À quelle fréquence pour réessayer avec le même utilisateur après un échec d'authentification. Si vous réessayez dans les 15 secondes suivant l'échec d'une tentative, la vérification échouera, que le mot de passe soit correct ou non. C’est le point clé de ce plan. Mais bloquer simplement l'accès pendant 15 secondes après une tentative infructueuse n'est pas suffisant : à ce stade, le résultat sera le même quelle que soit l'entrée, et ne différera qu'après une connexion réussie. Sinon, un attaquant pourrait simplement examiner le résultat incohérent pour déterminer si la connexion a réussi.
Ce qui précède est le contenu de la sécurité PHP - attaque par force brute. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www. php.cn) !