phpinfo() 页面本身不提供目录遍历功能。防止这个函数只是目录把 PHP 的配置信息、环境变量、遍历模块加载情况一股脑地输出到浏览器上。防止但问题恰恰出在“一股脑”这三个字上——它泄露的目录信息量足够一个老练的攻击者拼凑出服务器的目录结构。
举个例子。遍历phpinfo() 页面里有一项叫
DOCUMENT_ROOT,防止直接告诉你网站根目录的目录绝对路径。还有SCRIPT_FILENAME,遍历当前脚本的防止完整路径。更别提include_path、目录open_basedir这些配置项,遍历它们把 PHP 能访问哪些目录、防止优先从哪加载文件都写得明明白白。目录这些信息单独看没什么,遍历组合在一起,攻击者就能推断出文件系统的组织方式。比如看到/var/www/html和/var/www/html/admin,再配合一个上传功能没做好过滤的漏洞,目录遍历就成了顺水推舟的事。我见过一个真实案例。某台测试服务器开着
display_errors,phpinfo() 也没关。攻击者先通过 phpinfo() 得知session.save_path是/tmp,然后利用一个文件包含漏洞,尝试用../../../../tmp/sess_xxx的路径去读取会话文件。因为路径信息是现成的,连盲猜都省了。最后会话文件里的序列化数据被提取出来,直接伪造了管理员身份。你说这算不算 phpinfo() 间接促成的目录遍历?严格说漏洞在文件包含,但 phpinfo() 把地图画好了。要防这个,最直接的办法就是生产环境关掉 phpinfo()。在 PHP 配置文件里设置
expose_php = Off,再用disable_functions把phpinfo加入黑名单。这是两层保险,第一层不让 HTTP 头暴露 PHP 版本,第二层就算有人找到入口也调不到这个函数。但光这样还不够。真正的风险在于那些间接泄露路径的配置项。比如
open_basedir如果设置得太宽,攻击者看到后就知道你能访问哪些目录。建议把它收紧到项目根目录,别图省事用/。还有doc_root和user_dir,如果没用到就保持默认,别改成什么/home之类的敏感位置。这些细节你平时不会注意,但 phpinfo() 会一字不落地展示出去。另外有个小技巧,很多人不知道。phpinfo() 的输出里包含
_SERVER["REQUEST_URI"]和_GET变量。如果你在 URL 里加个参数,比如?file=../../etc/passwd,phpinfo() 会原样回显这个路径。虽然它不会真的去读取文件,但攻击者可以借此测试服务器是否对特殊字符做了过滤。如果回显里出现..且没有被编码或拦截,那就说明你的 Web 层对路径穿越的防护是缺失的。这个细节我是在一次渗透测试里发现的,当时就觉得这玩意儿比目录列表还危险。最后说个实操层面的建议。别只在生产环境关 phpinfo(),开发环境也尽量别开。很多程序员觉得本地调试方便就开着,结果代码上线时忘了改配置。更稳妥的做法是写个启动脚本,检测到环境变量是 production 就直接禁用。或者用 PHP 的
auto_prepend_file在脚本执行前检查一下,如果发现是 phpinfo() 的调用就强制退出。虽然有点粗暴,但总比裸奔强。说到底,phpinfo() 不是漏洞,它是个信息泄露放大器。你真正的防御重点不是堵住这个函数本身,而是确保即使它泄露了路径,攻击者也找不到可以利用的入口。目录遍历的根因永远是输入过滤不严和路径拼接不规范,phpinfo() 只是让这些错误更容易被定位。所以,修好你的文件操作代码,别把希望全押在关掉一个函数上。
顶: 2踩: 9845






评论专区