首页 体育 教育 财经 社会 娱乐 军事 国内 科技 互联网 房产 国际 女人 汽车 游戏

PHP序列化和反序列化语法差异问题

2020-01-17

官方文档中介绍PHP序列化和反序列化如下:

一切php里边的值都能够运用函数serialize来回来一个包含字节省的字符串来表明。unserialize函数能够从头把字符串变回php本来的值。 序列化一个目标将会保存目标的一切变量,可是不会保存目标的办法,只会保存类的姓名。 为了能够unserialize一个目标,这个目标的类有必要现已界说过。假如序列化类A的一个目标,将会回来一个跟类A相关,并且包含了目标一切变量值的字符串。

简单说序列化是目标转化字符串的进程,反序列化是字符串复原目标的进程。

文章中所述内容运用环境如下:

PHP7.3.1、SDK
VSCode
C++和C

在网上揭露参数反序列化履行流程现已十分具体,可是关于一些细节当地有一些缺乏,其中就包含序列化和反序列化之间的语法差异问题

差异问题

我们经过编译PHP内核源码剖析,发现PHP序列化在默许状况下在目标转化中参加:{和}用来拼接成字符串。

[var.c]
Line:882
static void php_var_serialize_intern
Line:896
if var_hash) == SUCCESS) {
 smart_str_appendl;
 smart_str_append_unsigned- name));
 smart_str_appendl;
 smart_str_append- name);
 smart_str_appendl;
 smart_str_append_unsigned;
 smart_str_appendl;
 smart_str_appendl serialized_data, serialized_length);
 smart_str_appendc;
Line:952
smart_str_appendl;
Line:995
smart_str_appendc;

我们来看上面这段代码,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  7) YYFILL;
 yych = *YYCURSOR;
 switch  {
 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

在进犯载荷中能够运用大多数字符替代{},然后导致规矩失效。

在红队进犯中能够运用PHP序列化和反序列化语法差异,然后到达绕过防护的意图。

在蓝队防护中主张考虑界说中所述不会保存目标的办法,只会保存类的姓名。,阻拦保存类的姓名,以及语法中相同的字符比方冒号进行防护。

*本文作者:米怀特,转载请注明来自FreeBuf.COM

在网上揭露参数反序列化履行流程现已十分具体,可是关于一些细节当地有一些缺乏,其中就包含序列化和反序列化之间的语法差异问题

我们经过编译PHP内核源码剖析,发现PHP序列化在默许状况下在目标转化中参加:{和}用来拼接成字符串。

[var.c]
Line:882
static void php_var_serialize_intern
Line:896
if var_hash) == SUCCESS) {
 smart_str_appendl;
 smart_str_append_unsigned- name));
 smart_str_appendl;
 smart_str_append- name);
 smart_str_appendl;
 smart_str_append_unsigned;
 smart_str_appendl;
 smart_str_appendl serialized_data, serialized_length);
 smart_str_appendc;
Line:952
smart_str_appendl;
Line:995
smart_str_appendc;

我们来看上面这段代码,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  7) YYFILL;
 yych = *YYCURSOR;
 switch  {
 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

在进犯载荷中能够运用大多数字符替代{},然后导致规矩失效。

在红队进犯中能够运用PHP序列化和反序列化语法差异,然后到达绕过防护的意图。

在蓝队防护中主张考虑界说中所述不会保存目标的办法,只会保存类的姓名。,阻拦保存类的姓名,以及语法中相同的字符比方冒号进行防护。

热门文章

随机推荐

推荐文章