一:漏洞简介

PHP的00截断是5.2.x版本的一个漏洞,当用户输入的url参数包含%00经过浏览器自动转码后截断后面字符。

二:漏洞示例代码

例如url输入的文件名1.txt%00.jpg经过url转码后会变为1.txt\000.jpg,测试文件1.php如下
<?phpinclude "1.txt\000.jpg";
?>

测试文件1.txt如下

<?phpecho 'fireXXX';
?>

php5.2.x版本解析1.php时,会将1.txt\000.jpg解释为1.txt

三:漏洞源码分析

    php5.2.17代码分析:
调用php去解析1.php文件。
    主要的执行流程在Zend/zend.c的zend_execute_scripts函数中。该函数首先通过zend_compile_file获取1.php文件的内容,然后调用zend_execute解析读取到的文件内容。
zend_compile_file函数首先调用open_file_for_scanning去读取文件,然后通过zendparse去进行语法和词法解析,而zendparse是通过lex_scan去扫描出token并进行语法分析。可以通过调试器观察到include的文件名参数经过lex_scan后的数据:
因此实际上解析到的文件名是1.txt,长度为10(因为lex_scan扫描到了1.txt\000.jpg实际是10个字符)
zend_execute通过ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER函数来进行include的实际处理,即包含要包含的文件。首先通过compile_filename来读取要读取文件的内容,然后继续调用zend_execute去执行要包含文件的代码。针对include "1.txt";即读取1.txt的内容,然后执行echo 'fireXXX';代码。

四:修复代码分析

可以从php5.3.24代码中找到修复的方案。修复的代码位于ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER函数的开始处:
        if (Z_LVAL(opline->op2.u.constant) != ZEND_EVAL && strlen(Z_STRVAL_P(inc_filename)) != Z_STRLEN_P(inc_filename)) {if (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE || Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE) {zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);} else {zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename) TSRMLS_CC);}}

代码

strlen(Z_STRVAL_P(inc_filename)) != Z_STRLEN_P(inc_filename)

中, Z_STRVAL_P(inc_filename)即上图中的val,即"1.txt",strlen取得长度为5,而 Z_STRLEN_P(inc_filename)即上图中的len即10。

一旦出现%00截断,include的文件名经过url转码由"1.txt%00.jpg"变为"1.txt\000.jpg",进入php语法词法分析器解析后会将这个字符串解析成一个字符串,并使用zend_scan_escape_string进行字符串转码,如图,进入zend_scan_escape_string的内容为:
中间的\\000还被解析为4个字符,转码中会将他当作八进制数据转成一个字符\0,因此最终1.txt\000.jpg长度是10。
只要比较发现文件名的strlen长度和语法分析出来的长度不一样,就说明内部存在截断的字符,因此输出了打开文件失败的信息。

从源码级别了解PHP %00截断原理相关推荐

  1. 深度分析Java的ClassLoader机制(源码级别)

    转载自 深度分析Java的ClassLoader机制(源码级别) Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取 ...

  2. uni-app开发:(源码级别)uni-badge样式修改(自定义插槽)

    文章目录 uni-app开发:(源码级别)uni-badge样式修改(自定义插槽) 一.效果图需求说明: 二.源码 · 修改前后对比: 2.1. 修改前 2.2. 修改后 三.调用代码: 附件:uni ...

  3. Android源码级别开发

    Android源码级别开发 1.课程简介(3) 1.系统开发概述 2.系统编译简介 3.源码查看工具 4.系统启动流程 5.Handler消息机制 6.AsyncTask原理 系统架构的回顾(13) ...

  4. oauth2源码级别解析报错原因:There is no client authentication. Try adding an appropriate authentication filter

    请求地址:localhost:40150/oauth/token/?grant_type=mobile_password 请求头, Basic 是 client_id 和 client_secret ...

  5. CoreCLR源码探索(八) JIT的工作原理(详解篇)

    在上一篇 我们对CoreCLR中的JIT有了一个基础的了解,这一篇我们将更详细分析JIT的实现. JIT的实现代码主要在https://github.com/dotnet/coreclr/tree/m ...

  6. 第八课 k8s源码学习和二次开发原理篇-KubeBuilder使用和Controller-runtime原理

    第八课 k8s源码学习和二次开发原理篇-KubeBuilder使用和Controller-runtime原理 tags: k8s 源码学习 categories: 源码学习 二次开发 文章目录 第八课 ...

  7. vue 源码自问自答-响应式原理

    vue 源码自问自答-响应式原理 最近看了 Vue 源码和源码分析类的文章,感觉明白了很多,但是仔细想想却说不出个所以然. 所以打算把自己掌握的知识,试着组织成自己的语言表达出来 不打算平铺直叙的写清 ...

  8. fdct算法 java_ImageSharp源码详解之JPEG压缩原理(3)DCT变换

    DCT变换可谓是JPEG编码原理里面数学难度最高的一环,我也是因为DCT变换的算法才对JPEG编码感兴趣(真是不自量力).这一章我就把我对DCT的研究心得体会分享出来,希望各位大神也不吝赐教. 1.离 ...

  9. 第十四课 k8s源码学习和二次开发原理篇-调度器原理

    第十四课 k8s源码学习和二次开发原理篇-调度器原理 tags: k8s 源码学习 categories: 源码学习 二次开发 文章目录 第十四课 k8s源码学习和二次开发原理篇-调度器原理 第一节 ...

最新文章

  1. Python 常见的坑汇总
  2. PostgreSQL的德哥教程
  3. Linux图形界面与命令行模式切换
  4. Python3有哪几种数据类型?
  5. umask详解、cwd简介
  6. linux jdk环境变量配置
  7. SCI论文写作训练营笔记汇总03_科技论文写作(方法篇)
  8. bootstrap 栅栏布局中 col-xs-*、col-sm-*、col-md-*、col-lg-* 区别及使用方法
  9. 安卓system镜像分区_玩机爱好者想要的PT分区到底是什么?可以使现有的安卓系统更快!...
  10. 写个随笔解解闷-书签漫游
  11. 上达最高精度,下到最快速度,Scaled-YOLOv4:模型缩放显神威
  12. java 随机手机验证码_基于Java随机生成手机短信验证码的实例代码|chu
  13. android 数据库 字节数组,java - 如何使用活动的android序列化字节数组并将其存储到数据库中? - 堆栈内存溢出...
  14. c#学习笔记01——引用类
  15. python实现翻转给定列表中的元素
  16. 系统同传软件_语情快递 | 手语同传AI,你见过吗?
  17. 严把质量关、做好可靠性与环境试验,不做被车压塌的桥!
  18. 滑动门套滑动门css,CSS 实现滑动门的实例代码
  19. IOS视频播放器的使用(MPMoviePlayerController)
  20. python画一个心形照片墙怎么摆_这个七夕节,用Python为女友绘制一张爱心照片墙吧!...

热门文章

  1. MongoDB备份及恢复
  2. 牛牛的数字集合 (贪心
  3. 前端实现下载文件(包含压缩包下载)方式汇总
  4. Samba服务概述、配置、及其搭建
  5. 第八天 集合和字符串
  6. 一次jsp电商系统开发总结
  7. c++处理字符串string.find()与string::npos
  8. 小机房服务器最后的战役 - 战前动员
  9. Nginx配置负载均衡
  10. 判断字符串类型的几种方法