Maison >développement back-end >tutoriel php >Explication détaillée des résultats du contournement de la vulnérabilité due aux caractères décalés en PHP
Cet article vous présente principalement les informations pertinentes sur la vulnérabilité de contournement causée par la fonctionnalité de décalage de caractères dans PHP. L'article présente non seulement la formation de la vulnérabilité en détail, mais, plus important encore, présente la méthode de réparation, qui est de. certaine signification pour tout le monde. Pour une valeur d'apprentissage de référence, les amis qui en ont besoin peuvent jeter un œil ci-dessous.
Fonctionnalité de décalage de caractères en php
Il existe une fonctionnalité très intéressante dans les chaînes en php. Les chaînes en php peuvent aussi être comme des valeurs. sont obtenus de la même manière qu'un tableau.
$test = "hello world"; echo $test[0];
Le résultat final est h.
Cependant, la fonctionnalité ci-dessus a parfois des effets inattendus. Regardez le code suivant
$mystr = "hello world"; echo $mystr["pass"];
La sortie du code ci-dessus Le résultat. est h. Pourquoi est-ce ? En fait, c'est très simple, comme beaucoup d'autres langages, les chaînes en PHP peuvent utiliser des indices pour obtenir des valeurs, tout comme les tableaux. La passe dans $mystr["pass"]
sera implicitement convertie en 0, de sorte que le résultat de sortie de $mystr[0]
soit la lettre initiale h
De même, si vous essayez le code suivant :
<.>
$mystr = "hello world"; echo $mystr["1pass"];Le résultat de sortie est e. Parce que 1pass sera converti en 1 par type implicite, le résultat de sortie de
est la deuxième lettre e.$mystr[1]
Caractéristiques du personnage La vulnérabilité provoquée
Le code suivant est utilisé dans phpspy2006 pour déterminer le code utilisé lors de la connexion.$admin['check'] = "1"; $admin['pass'] = "angel"; ...... if($admin['check'] == "1") { .... }Une telle logique de vérification peut être facilement contournée si les fonctionnalités ci-dessus sont utilisées. $admin n'est pas initialement défini comme un type de tableau, donc lorsque nous le soumettons avec une chaîne
, PHP prendra le premier bit de la chaîne 1xxx, contournant avec succès le jugement conditionnel if. phpsyp.php?admin=1abc
<?php # GOAL: overwrite password for admin (id=1) # Try to login as admin # $yourInfo=array( //this is your user data in the db # 'id' => 8, # 'name' => 'jimbo18714', # 'pass' => 'MAYBECHANGED', # 'level' => 1 # ); require 'db.inc.php'; function mres($str) { return mysql_real_escape_string($str); } $userInfo = @unserialize($_GET['userInfo']); $query = 'SELECT * FROM users WHERE id = \'' . mres($userInfo['id']) . '\' AND pass = \'' . mres($userInfo['pass']) . '\';'; $result = mysql_query($query); if (!$result || mysql_num_rows($result) < 1) { die('Invalid password!'); } $row = mysql_fetch_assoc($result); foreach ($row as $key => $value) { $userInfo[$key] = $value; } $oldPass = @$_GET['oldPass']; $newPass = @$_GET['newPass']; if ($oldPass == $userInfo['pass']) { $userInfo['pass'] = $newPass; $query = 'UPDATE users SET pass = \'' . mres($newPass) . '\' WHERE id = \'' . mres($userInfo['id']) . '\';'; mysql_query($query); echo 'Password Changed.'; } else { echo 'Invalid old password entered.'; }En ligne ne donne qu'une réponse définitive à cette question, et les principes ne sont pas expliqués ou pas expliqués en détail. En fait, le principe réside dans les caractéristiques de caractère de PHP mentionnées ci-dessus.
Qu'est-ce qu'il y a dedans ligne de code Fonction, pourquoi ce type de code existe-t-il dans l'instruction de jugement if $userInfo['pass'] = $newPass;
pour changer l'ID en 1. $userInfo['pass'] = $newPass
, consiste à changer le mot de passe de l'utilisateur avec l'identifiant 8 en 8index.php?userInfo=a:2:{s:2:"id";i:8;s:4:"pass";s:12:"MAYBECHANGED";}&oldPass=MAYBECHANGED&newPass=8
, sérialise $userInfo et obtient la chaîne « 8 », qui est index.php?userInfo=s:1:"8";&oldPass=8&newPass=1
, afin que la vérification de la requête de base de données puisse réussir. La vérification if ultérieure peut également passer, par cette ligne de code $userInfo = ‘8'
, puisque la valeur de $newpass est 1, alors le code ci-dessus devient $userInfo['pass'] = $newPass;
, $userInfo['pass'] = 1;
en raison d'un type de chaîne, le résultat final est $userInfo
, Enfin, vous pouvez mettre à jour le mot de passe de l'utilisateur avec l'identifiant 1. $userInfo='1'
Méthode de réparation
La méthode de réparation de ce type de vulnérabilité est également très simple. Définissez le type de données à l'avance et vérifiez tout avant utilisation. it. Si le type de données utilisé est cohérent avec celui attendu. Sinon, les problèmes de contournement mentionnés ci-dessus se produiront. Dans le même temps, les entrées doivent être contrôlées et les données d'entrée doivent être vérifiées et non utilisées avec désinvolture.Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!