利用php序列化和反序列化的语法差异绕过防护
发布时间 - 2020-01-02 00:00:00 点击率:次介绍
官方文档中介绍php序列化和反序列化如下:
所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。unserialize()函数能够重新把字符串变回php原来的值。 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。 为了能够unserialize()一个对象,这个对象的类必须已经定义过。如果序列化类A的一个对象,将会返回一个跟类A相关,而且包含了对象所有变量值的字符串。
简单说序列化是对象转化字符串的过程,反序列化是字符串还原对象的过程。
环境
文章中所述内容使用环境如下:
PHP7.3.1、SDKVSCodeC++和C
在网上公开参数反序列化执行流程已经非常详细,但是对于一些细节地方有一些不足,其中就包括序列化和反序列化之间的语法差异问题。
差异问题
1、序列化
我们通过编译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行,对于内嵌方法进行拼接。
2、反序列化
反序列化是将序列化的字符串,按照一定语法规则进行转化还原。
[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
# 字符串
# var
# 对象
# 序列化
# 微软
# 将会
# 只会
# 可以使用
# 所述
# 这段
# 相关文章
# 可以利用
# 中就
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南
如何快速选择适合个人网站的云服务器配置?
小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像
文字头像制作网站推荐软件,醒图能自动配文字吗?
如何用AI帮你把自己的生活经历写成一个有趣的故事?
php8.4header发送头信息失败怎么办_php8.4header函数问题解决【解答】
,交易猫的商品怎么发布到网站上去?
Android GridView 滑动条设置一直显示状态(推荐)
HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】
高端网站建设与定制开发一站式解决方案 中企动力
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
如何实现建站之星域名转发设置?
Python文本处理实践_日志清洗解析【指导】
动图在线制作网站有哪些,滑动动图图集怎么做?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】
ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
如何实现javascript表单验证_正则表达式有哪些实用技巧
如何注册花生壳免费域名并搭建个人网站?
如何在云主机上快速搭建多站点网站?
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】
原生JS实现图片轮播切换效果
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
Laravel如何设置自定义的日志文件名_Laravel根据日期或用户ID生成动态日志【技巧】
大同网页,大同瑞慈医院官网?
iOS验证手机号的正则表达式
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】
想要更高端的建设网站,这些原则一定要坚持!
Laravel怎么使用Intervention Image库处理图片上传和缩放
javascript基于原型链的继承及call和apply函数用法分析
郑州企业网站制作公司,郑州招聘网站有哪些?
长沙做网站要多少钱,长沙国安网络怎么样?
如何用景安虚拟主机手机版绑定域名建站?
Laravel如何使用Livewire构建动态组件?(入门代码)
如何确认建站备案号应放置的具体位置?
详解Android图表 MPAndroidChart折线图
Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道
Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
如何选择可靠的免备案建站服务器?
如何快速生成专业多端适配建站电话?
Linux网络带宽限制_tc配置实践解析【教程】
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
js实现点击每个li节点,都弹出其文本值及修改
三星网站视频制作教程下载,三星w23网页如何全屏?
Linux后台任务运行方法_nohup与&使用技巧【技巧】


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