Heim  >  Artikel  >  Backend-Entwicklung  >  Implementierung einer schwachen Typkonvertierung in PHP

Implementierung einer schwachen Typkonvertierung in PHP

不言
不言Original
2018-07-24 11:51:412001Durchsuche

Der Inhalt, der in diesem Artikel mit Ihnen geteilt wird, handelt von der schwachen Typkonvertierung in PHP. Ich hoffe, er kann Freunden in Not helfen.

1 Vorwort

Im letzten CTF-Wettbewerb ist die Frage nach den schwachen PHP-Typen mehr als einmal aufgetaucht. Ich möchte die schwachen PHP-Typen und deren Umgehung zusammenfassen

2 Wissenseinführung

Es gibt zwei Vergleichssymbole == und === in PHP

1 <?php
2 $a = $b ;
3 $a===$b ;
4 ?>

=== Beim Vergleich wird zunächst ermittelt, ob es sich um die Typen der beiden Zeichenfolgen handelt gleich, und dann Vergleich

== Beim Vergleich wird der Zeichenfolgentyp zuerst in den gleichen umgewandelt und dann verglichen

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

Hier wird klar angegeben, ob ein Wert vorhanden ist mit einer Zeichenfolge verglichen. Beim Vergleich wird die Zeichenfolge in einen numerischen Wert umgewandelt.

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 Beachten Sie den obigen Code „admin“==0. Beim Vergleich wird admin in einen numerischen Wert umgewandelt. erzwungene Konvertierung, da admin eine Zeichenfolge ist. Das Ergebnis der Konvertierung ist, dass 0 natürlich gleich 0 ist
2 "1admin"==1 Beim Vergleich wird 1admin in einen numerischen Wert umgewandelt und das Ergebnis ist 1, aber „admin1“==1 ist gleich einem Fehler, das heißt, „admin1“ wird in 0 konvertiert, warum? ? 3 „0e123456“=="0e456789" Beim Vergleich miteinander werden Zeichenfolgen wie 0e nach dem Wissenschafts- und Technologiegesetz als Zahlen erkannt. Egal wie viele Potenzen von 0 es gibt, sie sind gleich.

Für das obige Problem habe ich das PHP-Handbuch überprüft

Wenn eine Zeichenfolge als numerischer Wert behandelt wird, lauten Ergebnis und Typ wie folgt: Wenn die Zeichenfolge dies tut enthält nicht „.“, „e“, „E“ und sein numerischer Wert liegt im Bereich einer Ganzzahl
Die Zeichenfolge wird als int behandelt, und in allen anderen Fällen wird sie als float behandelt Ein Teil der Zeichenfolge bestimmt, dass sein Wert verwendet wird, wenn die Zeichenfolge mit einem zulässigen numerischen Wert beginnt, andernfalls ist sein Wert 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 ?>

Das erklärt also den Grund, warum „admin1“==1 =>Falsch

3 Praktischer Kampf

MD5-Bypass (Hash-Vergleichsfehler)

 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 ?>

Die Hauptidee der Frage besteht darin, eine Zeichenfolge und einen numerischen Typ einzugeben, und ihre MD5-Werte sind gleich, und dann kann die nächste Anweisung erfolgreich ausgeführt werden

Einführung von a Batch von Strings, deren MD5 mit 0e beginnt, wie oben erwähnt. Ich war dort schon einmal. 0e wird beim Vergleich als wissenschaftliche Notation betrachtet. Egal, was nach 0e kommt, die Potenz von 0 ist immer noch 0. md5('240610708') == md5('QNKCDZO')Erfolgreich umgangen!

QNKCDZO
0e830400451993494058024219903391

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

json bypass

<?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 "~~~~";
 }
?>

Geben Sie eine JSON-Typzeichenfolge ein, json_decode. Die Funktion entschlüsselt in ein Array und bestimmt, ob der Wert von key im Array gleich dem Wert von $key ist, aber wir kennen den Wert von $key nicht. Aber wir können die Form 0=="admin" verwenden, um ihn zu umgehen

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 ?>

Das Obige habe ich selbst geschrieben, Beurteilen Sie zuerst, ob es sich um ein Array handelt, und durchlaufen Sie dann jeden Wert im Array, und jeder Wert im Array kann nicht gleich admin sein. Konvertieren Sie jeden Wert in den Typ int und bestimmen Sie dann, ob das eingehende Array admin enthält, wenn ja , Rückgabeflag

Nutzlasttest[]=0 kann umgangen werden

Das Folgende ist die Einführung von array_search im offiziellen Handbuch

mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] )

$needle, $haystack ist erforderlich, $ strict ist eine optionale Funktionsbeurteilung $ Der Wert in haystack existiert in $needle. Wenn er vorhanden ist, wird der Schlüsselwert des Werts zurückgegeben. Wenn er auf true gesetzt ist, wird eine strikte Filterung durchgeführt Die Funktion 🎜>array_search ähnelt ==, das heißt, $ a=="admin" ist natürlich $a=0. Wenn der dritte Parameter wahr ist, kann die Sicherheitslücke

strcmp natürlich nicht umgangen werden . Umgehen von php -v <5.3

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 ist Vergleichen Sie zwei Zeichenfolgen. Wenn str1 größer als str2 ist, geben Sie 0 zurück 🎜>

Wir kennen den Wert von $password nicht. Der akzeptierte Wert muss gleich $password sein. Was passiert, wenn ein Array wird übergeben?

Wir übergeben passwort[]=xxx und können aufgrund der Funktion umgangen werden. Wenn ein inkompatibler Typ empfangen wird, tritt ein Fehler auf, er wird jedoch weiterhin als gleich beurteilt

Nutzlast: Passwort[]=xxx

Schalterumgehungen

 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 ?>

Dieses Prinzip ist das gleiche wie das vorherige. Ähnlich, ich werde es nicht im Detail erklären

4 Zusammenfassung

Diese schwachen PHP-Typen sind nur die Spitze des Eisbergs. Das Obige hat die Bedeutung der Codeprüfung bestätigt

Verwandte Empfehlungen:

Verwendungsbeispiele von Schlüsselwort var in PHP

PHP-Warteschlangenverarbeitung: Implementierungsprinzip der PHP-Nachrichtenwarteschlange (Bild und Text)

Das obige ist der detaillierte Inhalt vonImplementierung einer schwachen Typkonvertierung in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn