Maison >développement back-end >tutoriel php >Implémentation d'une conversion de type faible en php

Implémentation d'une conversion de type faible en php

不言
不言original
2018-07-24 11:51:412061parcourir

Le contenu partagé avec vous dans cet article concerne la conversion de type faible en php. Le contenu a une grande valeur de référence. J'espère qu'il pourra aider les amis dans le besoin.

1 Préface

Lors du récent concours CTF, la question des types PHP faibles est apparue plus d'une fois. Je voudrais résumer les types PHP faibles et comment les contourner

<.>2 Introduction aux connaissances

Il y a deux symboles de comparaison en php == et ===

1 <?php
2 $a = $b ;
3 $a===$b ;
4 ?>
=== Lors de la comparaison, il déterminera d'abord si les types des deux chaînes sont égaux. , puis comparez

== Lors de la comparaison, le type de chaîne sera d'abord converti en le même, puis comparé

如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行

Il est clairement indiqué ici que si une valeur et un caractère Lorsque les chaînes sont comparées, les chaînes seront converties en valeurs numériques

1 <?php
2 var_dump("admin"==0);  //true
3 var_dump("1admin"==1); //true
4 var_dump("admin1"==1) //false
5 var_dump("admin1"==0) //true
6 var_dump("0e123456"=="0e4456789"); //true 
7 ?>  //上述代码可自行测试
1 Observez le code ci-dessus, "admin"==0 Lors de la comparaison, l'administrateur le fera être converti en valeurs numériques, conversion forcée, Puisque admin est une chaîne, le résultat de la conversion est 0, ce qui est naturellement égal à 0

2 "1admin"==1 Lors de la comparaison, 1admin sera converti en valeur numérique, et le résultat est 1, mais "admin1"==1 est égal à une erreur, c'est-à-dire que "admin1" est converti en 0, pourquoi ? ? 3 "0e123456"=="0e456789" Lorsqu'elles sont comparées les unes aux autres, les chaînes telles que 0e seront reconnues comme des nombres en vertu de la loi scientifique et technologique. Quel que soit le nombre de puissances de 0, c'est zéro, elles sont donc égales
.

Pour le problème ci-dessus, j'ai vérifié le manuel PHP

Lorsqu'une chaîne est traitée comme une valeur numérique, le résultat et le type sont les suivants : Si la chaîne le fait ne contient pas '.', 'e', ​​'E' et sa valeur numérique est comprise dans la plage d'un entier

La chaîne est traitée comme un int Dans tous les autres cas, elle est traitée comme un float La partie de départ. de la chaîne est déterminée. Sa valeur est utilisée si la chaîne commence par une valeur numérique légale, sinon sa valeur est 0.

1 <?php
2 $test=1 + "10.5"; // $test=11.5(float)
3 $test=1+"-1.3e3"; //$test=-1299(float)
4 $test=1+"bob-1.3e3";//$test=1(int)
5 $test=1+"2admin";//$test=3(int)
6 $test=1+"admin2";//$test=1(int)
7 ?>
Cela explique donc la raison pour laquelle "admin1"==1 =>False

3 Combat pratique

contournement md5 (défaut de comparaison de hachage)

 1 <?php
 2 if (isset($_GET[&#39;Username&#39;]) && isset($_GET[&#39;password&#39;])) {
 3     $logined = true;
 4     $Username = $_GET[&#39;Username&#39;];
 5     $password = $_GET[&#39;password&#39;];
 6 
 7      if (!ctype_alpha($Username)) {$logined = false;}
 8      if (!is_numeric($password) ) {$logined = false;}
 9      if (md5($Username) != md5($password)) {$logined = false;}
10      if ($logined){
11     echo "successful";
12       }else{
13            echo "login failed!";
14         }
15     }
16 ?>
L'idée principale de la question est de saisir une chaîne et un type numérique, et leurs valeurs md5 sont égales, puis l'instruction suivante peut être exécutée avec succès

Présentation un lot de caractères md5 commençant par 0e Comme mentionné ci-dessus,

0e sera considéré comme une notation scientifique lors de la comparaison, donc peu importe ce qui vient après 0e, la puissance de 0 est toujours 0. md5('240610708') == md5('QNKCDZO')Contourné avec succès !

QNKCDZO
0e830400451993494058024219903391

s878926199a
0e545993274517709034328855841020
  
s155964671a
0e342768416822451524974117254469
  
s214587387a
0e848240448830537924465865611904
  
s214587387a
0e848240448830537924465865611904
  
s878926199a
0e545993274517709034328855841020
  
s1091221200a
0e940624217856561557816327384675
  
s1885207154a
0e509367213418206700842008763514
contournement json

<?php
if (isset($_POST[&#39;message&#39;])) {
    $message = json_decode($_POST[&#39;message&#39;]);
    $key ="*********";
    if ($message->key == $key) {
        echo "flag";
    } 
    else {
        echo "fail";
    }
 }
 else{
     echo "~~~~";
 }
?>
Entrez une chaîne de type json, json_decode la fonction le déchiffre dans un tableau et détermine si la valeur de la clé dans le tableau est égale à la valeur de $key, mais nous ne connaissons pas la valeur de $key,

mais nous pouvons utiliser la forme 0== "admin" à contourner

Final payload message={"key":0}

array_search is_array bypass

 1 <?php
 2 if(!is_array($_GET[&#39;test&#39;])){exit();}
 3 $test=$_GET[&#39;test&#39;];
 4 for($i=0;$i<count($test);$i++){
 5     if($test[$i]==="admin"){
 6         echo "error";
 7         exit();
 8     }
 9     $test[$i]=intval($test[$i]);
10 }
11 if(array_search("admin",$test)===0){
12     echo "flag";
13 }
14 else{
15     echo "false";
16 }
17 ?>
Le ci-dessus est celui que j'ai écrit, déterminez d'abord si le tableau entrant est un tableau, puis parcourez chaque valeur du tableau, et chaque valeur du tableau ne peut pas être égale à admin, et convertissez chaque valeur en un type int, puis déterminez si le tableau entrant a un administrateur, s'il renvoie un indicateur

payload test[]=0 peut être contourné

Ce qui suit est l'introduction de array_search dans le manuel officiel

mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] )
$needle, $haystack est obligatoire, $strict est facultatif. La fonction détermine si la valeur dans $haystack existe dans $needle. Si elle existe, elle renvoie la valeur clé de la valeur par défaut. défini sur true, un filtrage strict sera effectué

array_search est similaire à ==, c'est-à-dire $a=="admin", bien sûr $a=0. le troisième paramètre est vrai, vous ne pouvez pas contourner la vulnérabilité
1 <?php
2 $a=array(0,1);
3 var_dump(array_search("admin",$a)); // int(0) => 返回键值0
4 var_dump(array_seach("1admin",$a));  // int(1) ==>返回键值1
5 ?>

strcmp pour contourner php -v 0c19dde1fc3c29ed0bd2af1b299dc6f00. S'ils sont égaux, il renvoie 0

 1 <?php
 2     $password="***************"
 3      if(isset($_POST[&#39;password&#39;])){
 4 
 5         if (strcmp($_POST[&#39;password&#39;], $password) == 0) {
 6             echo "Right!!!login success";n
 7             exit();
 8         } else {
 9             echo "Wrong password..";
10         }
11 ?>

Nous ne le sommes pas. Si vous connaissez la valeur de $password, la question exige que la valeur acceptée jugée par strcmp soit égal à $password. Le type attendu transmis par strcmp est un type chaîne Que se passera-t-il si un tableau est transmis

Nous transmettons le mot de passe[]=xxx peut être contourné car la fonction reçoit un type incompatible ? et une erreur se produira, mais elle est toujours jugée égale

payload: password[]=xxx

switch bypass

Ce principe est similaire au le précédent, donc je ne l'expliquerai pas en détail
 1 <?php
 2 $a="4admin";
 3 switch ($a) {
 4     case 1:
 5         echo "fail1";
 6         break;
 7     case 2:
 8         echo "fail2";
 9         break;
10     case 3:
11         echo "fail3";
12         break;
13     case 4:
14         echo "sucess";  //结果输出success;
15         break;
16     default:
17         echo "failall";
18         break;
19 }
20 ?>

4 Résumé

Ces types PHP faibles ne sont que la pointe de l'iceberg Ce qui précède a vérifié l'importance de l'audit de code

Recommandations associées :

Exemples d'utilisation du mot-clé var en PHP

Traitement de la file d'attente php : principe d'implémentation de la file d'attente de messages PHP (texte de la figure)

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