Heim > Betrieb und Instandhaltung > Sicherheit > Syntaxunterschiede zwischen PHP-Serialisierung und -Deserialisierung nutzen, um den Schutz zu umgehen

Syntaxunterschiede zwischen PHP-Serialisierung und -Deserialisierung nutzen, um den Schutz zu umgehen

王林
Freigeben: 2020-01-02 16:53:08
nach vorne
2194 Leute haben es durchsucht

Syntaxunterschiede zwischen PHP-Serialisierung und -Deserialisierung nutzen, um den Schutz zu umgehen

Einführung

Die offizielle Dokumentation führt die PHP-Serialisierung und -Deserialisierung wie folgt ein:

Alle Werte in PHP sind Sie kann die Funktion serialize() verwenden, um eine Zeichenfolge zurückzugeben, die einen Bytestream enthält. Die Funktion unserialize() kann den String wieder auf den ursprünglichen Wert von PHP zurücksetzen. Durch die Serialisierung eines Objekts werden alle Variablen des Objekts gespeichert, jedoch nicht die Methoden des Objekts, sondern nur der Klassenname. Um ein Objekt unserialisieren() zu können, muss die Klasse des Objekts definiert worden sein. Wenn Sie ein Objekt der Klasse A serialisieren, wird eine auf Klasse A bezogene Zeichenfolge zurückgegeben, die die Werte aller Variablen im Objekt enthält.

Einfach ausgedrückt ist Serialisierung der Prozess der Konvertierung von Objekten in Strings, und Deserialisierung ist der Prozess der Wiederherstellung von Objekten aus Strings.

Umgebung

Der im Artikel beschriebene Inhalt wird in der folgenden Umgebung verwendet:

PHP7.3.1, SDKVSCodeC++ und C

Der online offengelegte Prozess zur Ausführung der Parameter-Deserialisierung ist sehr detailliert, weist jedoch in einigen Details einige Mängel auf, einschließlich des Syntaxunterschieds zwischen Serialisierung und Deserialisierung.

Unterschiedsprobleme

1. Serialisierung

Wir analysieren, indem wir den PHP-Kernel-Quellcode kompilieren Es wurde festgestellt, dass die PHP-Serialisierung standardmäßig Folgendes zur Objektkonvertierung hinzufügt, um sie zu einer Zeichenfolge zu verketten.

[var.c]
Line:882
static void php_var_serialize_intern()
Line:896
if (ce->serialize(struc, &serialized_data, &serialized_length, (zend_serialize_data *)var_hash) == SUCCESS) {
                        smart_str_appendl(buf, "C:", 2);
                        smart_str_append_unsigned(buf, ZSTR_LEN(Z_OBJCE_P(struc)->name));
                        smart_str_appendl(buf, ":\"", 2);
                        smart_str_append(buf, Z_OBJCE_P(struc)->name);
                        smart_str_appendl(buf, "\":", 2);

                        smart_str_append_unsigned(buf, serialized_length);
                        smart_str_appendl(buf, ":{", 2);
                        smart_str_appendl(buf, (char *) serialized_data, serialized_length);
                        smart_str_appendc(buf, '}');
                    }
Line:952
smart_str_appendl(buf, ":{", 2);
Line:995
smart_str_appendc(buf, '}');
Nach dem Login kopieren

Schauen wir uns den obigen Code an. PHP verwendet smart_str_appendl, um die serialisierte Zeichenfolge vor und nach: {and} zu verbinden und die Serialisierungslogik ab Zeile 882 von var.c einzugeben. Das Serialisierungs-String-Spleißen wird in Zeile 896 durchgeführt, und die Zeilen 952 und 995 werden für Inline-Methoden gespleißt.

2. Deserialisierung

Bei der Deserialisierung wird die serialisierte Zeichenfolge gemäß bestimmten grammatikalischen Regeln konvertiert und wiederhergestellt.

[var_unserialize.c]
Line:655
static int php_var_unserialize_internal()

Line:674{
    YYCTYPE yych;    
    static const unsigned char yybm[] = {          
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
        128, 128, 128, 128, 128, 128, 128, 128, 
        128, 128,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
    };
    if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
    yych = *YYCURSOR;    
    switch (yych) {    
    case &#39;C&#39;:    
    case &#39;O&#39;:    goto yy4;    
    case &#39;N&#39;:    goto yy5;    
    case &#39;R&#39;:    goto yy6;    
    case &#39;S&#39;:    goto yy7;    
    case &#39;a&#39;:    goto yy8;    
    case &#39;b&#39;:    goto yy9;    
    case &#39;d&#39;:    goto yy10;    
    case &#39;i&#39;:    goto yy11;    
    case &#39;o&#39;:    goto yy12;    
    case &#39;r&#39;:    goto yy13;    
    case &#39;s&#39;:    goto yy14;    
    case &#39;}&#39;:    goto yy15;    
    default:    goto yy2;
    }

Line:776
yy15:
    ++YYCURSOR;
    {    /* this is the case where we have less data than planned */
    php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");    
return 0; /* not sure if it should be 0 or 1 here? */
}
Nach dem Login kopieren

Durch den Kernel-Code können Sie sehen, dass die Deserialisierung in Zeile 655 lexikalisches Scannen verwendet, um die entsprechenden Objekte jeder Symbolkonvertierung zu ermitteln. Es ist ersichtlich, dass } während der Deserialisierung verarbeitet wird. Während der Verarbeitung wird der Zähler nur um eins erhöht und es werden keine anderen Vorgänge ausgeführt.

Tatsächliche Auswirkung

Der Unterschied in der Deserialisierungssyntax hat einen großen Einfluss auf die Beurteilung der Deserialisierung durch die Sicherheitsschutzausrüstung. In Snort gibt es eine Regel wie folgt:

alert tcp any any -> any [80,8080,443] (uricontent:".php"; pcre:"/\{\w:.+?\}/"; sid:1; 
msg:php_serialize;)
Nach dem Login kopieren

Die meisten Zeichen können anstelle von {} in der Angriffsnutzlast verwendet werden, wodurch die Regel ungültig wird.

Zusammenfassung

Unterschiede in der PHP-Serialisierungs- und Deserialisierungssyntax können bei Red-Team-Angriffen ausgenutzt werden, um den Schutz zu umgehen.

Bei der Blue-Team-Verteidigung wird empfohlen, die in der Definition beschriebene Methode zu berücksichtigen, die nicht das Objekt, sondern nur den Namen der Klasse speichert. , fangen den Namen der gespeicherten Klasse und dieselben Zeichen in der Syntax ab, z. B. einen Doppelpunkt zur Verteidigung.

Teilen verwandter Artikel und Tutorials: Tutorial zur Website-Sicherheit

Das obige ist der detaillierte Inhalt vonSyntaxunterschiede zwischen PHP-Serialisierung und -Deserialisierung nutzen, um den Schutz zu umgehen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:freebuf.com
Erklärung dieser Website
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
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage