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.
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
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
MD5-Bypass (Hash-Vergleichsfehler)
1 <?php 2 if (isset($_GET['Username']) && isset($_GET['password'])) { 3 $logined = true; 4 $Username = $_GET['Username']; 5 $password = $_GET['password']; 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['message'])) { $message = json_decode($_POST['message']); $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['test'])){exit();} 3 $test=$_GET['test']; 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 beurteiltNutzlast: Passwort[]=xxxSchalterumgehungen
1 <?php 2 $password="***************" 3 if(isset($_POST['password'])){ 4 5 if (strcmp($_POST['password'], $password) == 0) { 6 echo "Right!!!login success";n 7 exit(); 8 } else { 9 echo "Wrong password.."; 10 } 11 ?>
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!