Heim  >  Artikel  >  Backend-Entwicklung  >  Unterschiede in der PHP-Serialisierungs- und Deserialisierungssyntax

Unterschiede in der PHP-Serialisierungs- und Deserialisierungssyntax

(*-*)浩
(*-*)浩Original
2019-11-21 10:40:122589Durchsuche

Unterschiede in der PHP-Serialisierungs- und Deserialisierungssyntax

In der offiziellen Dokumentation werden die Php -Serialisierung und Deserialisierung wie folgt eingeführt: 🎜> Einfach ausgedrückt, Serialisierung ist der Prozess des Umwandelns von Objekten in Zeichenfolgen und Deserialisierung ist der Prozess der Wiederherstellung von Objekten aus Zeichenfolgen.

Umgebung

Die Nutzungsumgebung für die im Artikel beschriebenen Inhalte ist wie folgt:

所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。unserialize()函数能够重新把字符串变回php原来的值。序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。为了能够unserialize()一个对象,这个对象的类必须已经定义过。如果序列化类A的一个对象,将会返回一个跟类A相关,而且包含了对象所有变量值的字符串。
Empfohlene Referenz für die Umgebung Konfiguration: „ Verwenden von VSCODE zum Debuggen von PHP7-Quellcode unter WINDOWS

Der Ausführungsprozess der Parameter-Deserialisierung ist im Internet sehr detailliert, es gibt jedoch einige Mängel in einigen Details, einschließlich Serialisierung und Deserialisierung . Das Syntaxunterschiedsproblem zwischen

Unterschiedsproblem

Serialisierung

Wir haben den PHP-Kernel-Quellcode kompiliert und analysiert und gefunden die PHP-Sequenz Standardmäßig werden { und } zu Objektkonvertierungen für die Verkettung in Strings hinzugefügt.

PHP7.3.1、SDK
VSCode
C++和C

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.

Deserialisierung

Deserialisierung besteht darin, die serialisierte Zeichenfolge gemäß bestimmten grammatikalischen Regeln zu konvertieren und wiederherzustellen.

[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, '}');

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:

[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? */
}

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.

Das obige ist der detaillierte Inhalt vonUnterschiede in der PHP-Serialisierungs- und Deserialisierungssyntax. 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