PHP序列化和反序列化语法差异问题-php教程

资源魔 17 0

民间文档中引见PHP序列化以及反序列化以下: (保举学习:PHP视频教程)

一切php外面的值均可以应用函数serialize()来前往一个蕴含字节省的字符串来示意。unserialize()函数可以从新把字符串变回php原来的值。序列化一个工具将会保留工具的一切变量,然而没有会保留工具的办法,只会保留类的名字。为了可以unserialize()一个工具,这个工具的类必需曾经界说过。假如序列化类A的一个工具,将会前往一个跟类A相干,并且蕴含了工具一切变量值的字符串。

简略说序列化是工具转化字符串的进程,反序列化是字符串复原工具的进程。

环境

文章中所述内容应用环境以下:

PHP7.3.一、SDK
VSCode
C++以及C

环境设置装备摆设倡议参考:《WINDOWS下用VSCODE调试PHP7源代码》

正在网上地下参数反序列化执行流程曾经十分具体,然而关于一些细节中央有一些有余,此中就包罗序列化以及反序列化之间的语法差别成绩

差别成绩

序列化

咱们经过编译PHP内核源码剖析,发现PHP序列化正在默许状况下正在工具转换中退出:{以及}用来拼接成字符串。

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

我们来看下面这段代码,PHP会应用smart_str_appendl为序列化字符串先后拼接:{以及},从var.c的第882行开端进入序列化逻辑。正在第896前进行序列化字符串拼接,第952行以及第995行,关于内嵌办法进行拼接。

反序列化

反序列化是将序列化的字符串,依照肯定语法例则进行转化复原。

[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 'C':
    case 'O':    goto yy4;
    case 'N':    goto yy5;
    case 'R':    goto yy6;
    case 'S':    goto yy7;
    case 'a':    goto yy8;
    case 'b':    goto yy9;
    case 'd':    goto yy10;
    case 'i':    goto yy11;
    case 'o':    goto yy12;
    case 'r':    goto yy13;
    case 's':    goto yy14;
    case '}':    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? */
}

经过内核代码可以看到第655前进入反序列化,反序列化是行使词法扫描,判别各项符号转换对应答象。可以看到反序列化中关于}进行了解决,解决中只是对计数器加一并无其余操作。

实际作用

反序列化语法的差别,关于平安防护设施判别反序列化孕育发生很年夜的影响。正在Snort中,有段规定以下:

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

正在攻打载荷中能够应用年夜少数字符替代{},从而招致规定生效。

总结

正在红队攻打中能够行使PHP序列化以及反序列化语法差别,从而达到绕过防护的目的。

正在蓝队进攻中倡议思考界说中所述没有会保留工具的办法,只会保留类的名字。,阻拦保留类的名字,和语法中相反的字符比方冒号进行进攻。

以上就是PHP序列化以及反序列化语法差别成绩的具体内容,更多请存眷资源魔其它相干文章!

标签: php php开发教程 php开发资料 php开发自学

抱歉,评论功能暂时关闭!