这几天wordpress的那个反序列漏洞比较火,具体漏洞我就不做分析了,看这篇:http://drops.wooyun.org/papers/596,?
你也可以去看英文的原文:http://vagosec.org/2013/09/wordpress-php-object-injection/。?
wp官网打了补丁,我试图去bypass补丁,但让我自以为成功的时候,发现我天真了,并没有成功绕过wp的补丁,但却发现了unserialize的一个小特性,在此和大家分享一下。?
1.unserialize()函数相关源码:?if ((YYLIMIT - YYCURSOR) ????????yych = *YYCURSOR;?<br style="margin: 0px; padding: 0px;">????????switch (yych) {?<br style="margin: 0px; padding: 0px;">????????case 'C':?<br style="margin: 0px; padding: 0px;">????????case 'O':????????goto yy13;?<br style="margin: 0px; padding: 0px;">????????case 'N':????????goto yy5;?<br style="margin: 0px; padding: 0px;">????????case 'R':????????goto yy2;?<br style="margin: 0px; padding: 0px;">????????case 'S':????????goto yy10;?<br style="margin: 0px; padding: 0px;">????????case 'a':????????goto yy11;?<br style="margin: 0px; padding: 0px;">????????case 'b':????????goto yy6;?<br style="margin: 0px; padding: 0px;">????????case 'd':????????goto yy8;?<br style="margin: 0px; padding: 0px;">????????case 'i':????????goto yy7;?<br style="margin: 0px; padding: 0px;">????????case 'o':????????goto yy12;?<br style="margin: 0px; padding: 0px;">????????case 'r':????????goto yy4;?<br style="margin: 0px; padding: 0px;">????????case 's':????????goto yy9;?<br style="margin: 0px; padding: 0px;">????????case '}':????????goto yy14;?<br style="margin: 0px; padding: 0px;">????????default:????????goto yy16;?<br style="margin: 0px; padding: 0px;">????????}
上边这段代码是判断序列串的处理方式,如序列串O:4:"test":1:{s:1:"a";s:3:"aaa";},处理这个序列串,先获取字符串第一个字符为O,然后case 'O':??goto yy13?yy13:?<br style="margin: 0px; padding: 0px;">????????yych = *(YYMARKER = ++YYCURSOR);?<br style="margin: 0px; padding: 0px;">????????if (yych == ':') goto yy17;?<br style="margin: 0px; padding: 0px;">????????goto yy3;
从上边代码看出,指针移动一位指向第二个字符,判断字符是否为:,然后 goto yy17?yy17:?<br style="margin: 0px; padding: 0px;">????????yych = *++YYCURSOR;?<br style="margin: 0px; padding: 0px;">????????if (yybm[0+yych] & 128) {?<br style="margin: 0px; padding: 0px;">????????????????goto yy20;?<br style="margin: 0px; padding: 0px;">????????}?<br style="margin: 0px; padding: 0px;">????????if (yych == '+') goto yy19;?<br style="margin: 0px; padding: 0px;"><br style="margin: 0px; padding: 0px;">.......?<br style="margin: 0px; padding: 0px;"><br style="margin: 0px; padding: 0px;">yy19:?<br style="margin: 0px; padding: 0px;">????????yych = *++YYCURSOR;?<br style="margin: 0px; padding: 0px;">????????if (yybm[0+yych] & 128) {?<br style="margin: 0px; padding: 0px;">????????????????goto yy20;?<br style="margin: 0px; padding: 0px;">????????}?<br style="margin: 0px; padding: 0px;">????????goto yy18;
从上边代码看出,指针移动,判断下一位字符,如果字符是数字直接goto yy20,如果是'+'就goto yy19,而yy19中是对下一位字符判断,如果下一位字符是数字goto yy20,不是就goto yy18,yy18是直接退出序列处理,yy20是对object性的序列的处理,所以从上边可以看出:?O:+4:"test":1:{s:1:"a";s:3:"aaa";}?<br style="margin: 0px; padding: 0px;">O:4:"test":1:{s:1:"a";s:3:"aaa";}
都能够被unserialize反序列化,且结果相同。?
2.实际测试:?<?php ?<br style="margin: 0px; padding: 0px;">var_dump(unserialize('O:+4:"test":1:{s:1:"a";s:3:"aaa";}'));?<br style="margin: 0px; padding: 0px;">var_dump(unserialize('O:4:"test":1:{s:1:"a";s:3:"aaa";}'));?<br style="margin: 0px; padding: 0px;">?>
输出:?object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(4) "test" ["a"]=> string(3) "aaa" }?<br style="margin: 0px; padding: 0px;">object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(4) "test" ["a"]=> string(3) "aaa" }
其实,不光object类型处理可以多一个'+',其他类型也可以,具体测试不做过多描述。?
3.我们看下wp的补丁:?function is_serialized( $data, $strict = true ) {?<br style="margin: 0px; padding: 0px;">????????// if it isn't a string, it isn't serialized?<br style="margin: 0px; padding: 0px;">????????if ( ! is_string( $data ) )?<br style="margin: 0px; padding: 0px;">????????????????return false;?<br style="margin: 0px; padding: 0px;">????????$data = trim( $data );?<br style="margin: 0px; padding: 0px;">???????? if ( 'N;' == $data )?<br style="margin: 0px; padding: 0px;">????????????????return true;?<br style="margin: 0px; padding: 0px;">????????$length = strlen( $data );?<br style="margin: 0px; padding: 0px;">????????if ( $length ????????????????return false;?<br style="margin: 0px; padding: 0px;">????????if ( ':' !== $data[1] )?<br style="margin: 0px; padding: 0px;">????????????????return false;?<br style="margin: 0px; padding: 0px;">????????if ( $strict ) {//output?<br style="margin: 0px; padding: 0px;">????????????????$lastc = $data[ $length - 1 ];?<br style="margin: 0px; padding: 0px;">????????????????if ( ';' !== $lastc && '}' !== $lastc )?<br style="margin: 0px; padding: 0px;">????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????} else {//input?<br style="margin: 0px; padding: 0px;">????????????????$semicolon = strpos( $data, ';' );?<br style="margin: 0px; padding: 0px;">????????????????$brace???? = strpos( $data, '}' );?<br style="margin: 0px; padding: 0px;">????????????????// Either ; or } must exist.?<br style="margin: 0px; padding: 0px;">????????????????if ( false === $semicolon && false === $brace )?<br style="margin: 0px; padding: 0px;">????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????????????// But neither must be in the first X characters.?<br style="margin: 0px; padding: 0px;">????????????????if ( false !== $semicolon && $semicolon ????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????????????if ( false !== $brace && $brace ????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????}?<br style="margin: 0px; padding: 0px;">????????$token = $data[0];?<br style="margin: 0px; padding: 0px;">????????switch ( $token ) {?<br style="margin: 0px; padding: 0px;">????????????????case 's' :?<br style="margin: 0px; padding: 0px;">????????????????????????if ( $strict ) {?<br style="margin: 0px; padding: 0px;">????????????????????????????????if ( '"' !== $data[ $length - 2 ] )?<br style="margin: 0px; padding: 0px;">????????????????????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????????????????????} elseif ( false === strpos( $data, '"' ) ) {?<br style="margin: 0px; padding: 0px;">????????????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????????????????????}?<br style="margin: 0px; padding: 0px;">????????????????case 'a' :?<br style="margin: 0px; padding: 0px;">????????????????case 'O' :?<br style="margin: 0px; padding: 0px;">????????????????????????echo "a";?<br style="margin: 0px; padding: 0px;">????????????????????????return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );?<br style="margin: 0px; padding: 0px;">????????????????case 'b' :?<br style="margin: 0px; padding: 0px;">????????????????case 'i' :?<br style="margin: 0px; padding: 0px;">????????????????case 'd' :?<br style="margin: 0px; padding: 0px;">????????????????????????$end = $strict ? '$' : '';?<br style="margin: 0px; padding: 0px;">????????????????????????return (bool) preg_match( "/^{$token}:[0-9.E-]+;$end/", $data );?<br style="margin: 0px; padding: 0px;">????????}?<br style="margin: 0px; padding: 0px;">????????return false;?<br style="margin: 0px; padding: 0px;">}
补丁中的?return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
可以多一个'+'来绕过,虽然我们通过这个方法把序列值写入了数据库,但从数据库中提取数据,再次验证的时候却没法绕过了,我这个加号没能使数据进出数据库发生任何变化,我个人认为这个补丁绕过重点在于数据进出数据的前后变化。?
4.总结?
虽然没有绕过wp补丁,但这个unserialize()的小特性可能会被很多开发人员忽略,导致程序出现安全缺陷。?
以上的分析有什么错误请留言指出。?
5.参考?
《WordPress
http://vagosec.org/2013/09/wordpress-php-object-injection/?
《var_unserializer.c源码》?
https://github.com/php/php-src/blob/73cd2e0ab14d804c6bf0b689490bdd4fd6e969b1/ext/standard/var_unserializer.c?
《PHP string序列化与反序列化语法解析不一致带来的安全隐患》?
http://zone.wooyun.org/content/1664
php反序列unserialize的一个小特性

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

PHP可以轻松创建互动网页内容。1)通过嵌入HTML动态生成内容,根据用户输入或数据库数据实时展示。2)处理表单提交并生成动态输出,确保使用htmlspecialchars防XSS。3)结合MySQL创建用户注册系统,使用password_hash和预处理语句增强安全性。掌握这些技巧将提升Web开发效率。

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

PHP仍然具有活力,其在现代编程领域中依然占据重要地位。1)PHP的简单易学和强大社区支持使其在Web开发中广泛应用;2)其灵活性和稳定性使其在处理Web表单、数据库操作和文件处理等方面表现出色;3)PHP不断进化和优化,适用于初学者和经验丰富的开发者。

PHP在现代Web开发中仍然重要,尤其在内容管理和电子商务平台。1)PHP拥有丰富的生态系统和强大框架支持,如Laravel和Symfony。2)性能优化可通过OPcache和Nginx实现。3)PHP8.0引入JIT编译器,提升性能。4)云原生应用通过Docker和Kubernetes部署,提高灵活性和可扩展性。

PHP适合web开发,特别是在快速开发和处理动态内容方面表现出色,但不擅长数据科学和企业级应用。与Python相比,PHP在web开发中更具优势,但在数据科学领域不如Python;与Java相比,PHP在企业级应用中表现较差,但在web开发中更灵活;与JavaScript相比,PHP在后端开发中更简洁,但在前端开发中不如JavaScript。

PHP和Python各有优势,适合不同场景。1.PHP适用于web开发,提供内置web服务器和丰富函数库。2.Python适合数据科学和机器学习,语法简洁且有强大标准库。选择时应根据项目需求决定。

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3汉化版
中文版,非常好用

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中