文件包含漏洞--常见封装协议的利用

作者:yzc    发布于:

文件包含漏洞–常见封装协议的利用

0x01 php流input(allow_url_include=On)

php://input是一个只读信息流,当在POST请求(通常只针对POST,而不是其他的请求)下,且 enctype 不等于"multipart/form-data"时,使用php://input代替$HTTP_RAW_POST_DATA,因为php://input可以不依赖于特定的php.ini指令

form表单中的enctype属性指定将数据发回到服务器时浏览器使用的编码类型。enctype=”multipart/form-data” 的时候 php://input 是无效的。

php://input如果要使用,需要 allow_url_include=On

实例:

1
2
3
<?php
include($_GET['f']);
?>

0x02 php流filter

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

这句话的大体意思是:数据流在读取或写入资源之前会进行用户事先安排好的一些过滤操作,如对数据流进行base64编码或解码操作,对数据流进行rot13编码操作或去除HTML标签操作等。

但是php://filter存在文件包含漏洞,可以用来读取服务器上的文件内容,而且不需要开启allow_url_include,基本的读取文件格式如下:

php://filter/read=convert.base64-encode/resource=[文件路径]

这句话的意思是:将想要读取的文件经过base64加密读取出来

实例:

1
2
3
<?php
include($_GET['f']);
?>

还是相同的一个PHP文件,但是使用php://filter来实现读取文件,下面是我们需要读取的文件,名为phpfilter.php

1
<?php echo "php://filter"; ?>

是不是和代码一致?这样就通过php://filter读取了文件

下图是自己总结的关于php://filter的更具体的用法示意图,可以利用php://filter数据流绕过死亡exit,进而将webshell直接传到目标服务器上

将举几个例子来讲解

实例代码:

1
2
3
4
<?php
$content = '<?php exit; ?>';
$content .= $_POST['txt'];
file_put_contents($_POST['filename'], $content);

1.利用base64解码过滤器去除死亡exit

通过分析代码可知,在我们以POST方式上传txt之前,变量$content的前面会被加上<?php exit; ?>,这样就导致即使上传了webshell也无法成功的执行(实战中经常遇到),但是我们发现$_POST['filename']是可以控制协议的,于是就想到可以使用php://filter流进行绕过

那么具体怎么绕过呢?这里就需要用到php://filter流中的base64-decode方法了。

base64编码中只包含64个可打印字符,而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码。

这句话就是关键,base64解码时会将不在64个可打印字符中的符号去掉,<?php exit; ?><>?;几个符号均不在base64解码可打印的符号中,所以在解码的过程中会被去掉,这样一来经过base64-decode方法后<?php exit; ?>会变成phpexit总共七个字符,又因为base64算法解码时4个byte为一组,所以需要给phpexit加上一个字符,凑够8个字符,组成一个byte

需要注意的是如果以后需要使用这个方法进行绕过时,可能经过base64解码后的字符串有可能不是8的倍数,将字符串凑成8的倍数才能实现绕过

2.利用strip_tags函数 + base64-decode方法去除死亡exit

strip_tags函数:剥去字符串中的HTML标签

php://filter数据流支持使用这个方法,同时也支持多种方法同时使用,这样的话就可以利用这两种方法的组合去除死亡exit并实现webshell的写入,具体方法如下:

<?php exit; ?>在被strip_tags方法处理后会被去掉,但是如果我们要写入对方服务器的webshell文件的内容也是采用明文的话,同样也会被strip_tags方法去除掉,所以需要对写入对方服务器的webshell文件的内容进行base64编码,这样的话,写入对方服务器的webshell文件的内容就不存在HTML标签,也就不会被strip_tags方法处理,之后php://filter中使用base64-decode方法对其进行解码,成功的写入

3.利用rot13编码去除死亡exit

ROT13(回转13位,rotateby13places,有时中间加了个减号称作ROT-13)是一种简易的置换暗码。ROT13是它自己本身的逆反;也就是说,要还原ROT13,套用加密同样的算法即可得,故同样的操作可用再加密与解密。

值得注意的是ROT13是它自己本身的逆反还原ROT13,套用加密同样的算法即可得,故同样的操作可用再加密与解密。,利用这个原理,可以先对我们要写入对方服务器的webshell文件的内容进行rot13编码,这样的话<?php exit; ?>在进行rot13解码时将会被解码成rot13编码的形式,这样的代码,PHP将无法识别,所以可以绕过死亡exit

0x03 data URLs(allow_url_include=On)

php 的 data:// 是一个数据流封装器,基本用法如下:

data://text/plain;base64,

其中data://为协议名,text/plain是需要封装的数据的格式,也可以封装图片文件;之后的base64是数据需要被进行base64编码;再之后就是需要封装的数据了。

可以利用这个协议的漏洞将文件包含漏洞变成代码执行漏洞,下面举实例演示:

1
2
3
<?php
include($_GET['f']);
?>

通过将<?php echo "data://text/plain;base64" ?> 这句代码进行base64编码过后,利用data://text/plain;base64,代码就可以执行该代码。

值得注意的是<?php echo "data://text/plain;base64" ?>这句代码?>前加了一个空格,如果没有这个空格,命令将无法执行,如果怕忘记这个规则,可以直接不加?>,代码也可以执行

0x04 zip协议

可以利用zip协议来读取文件,zip协议的格式是:

zip://zip文件目录/xxx.zip%23xxx.zip中的文件

这个协议的文件读取漏洞可以结合文件上传漏洞,先上传一个xxx.zip文件,这个压缩文件中包含我们想要读取的文件(比如webshell文件)

需要注意的是URL编码,也就是zip协议格式中的%23(#)#会与URL协议中的#冲突,所以在使用zip协议的时候需要把#转换成%23

还有一点就是可以把.zip后缀改成.jpg后缀,这样也可以成功,这个技巧有时可以绕过上传的限制,格式为:

zip://zip文件目录/xxx.jpg%23xxx.zip中的文件

下面是实例:

phpzip.php代码

1
<?php include('funct.php'); $file = $_GET['file']; $ext = get_extension($file); $bz = check_extension($ext); if($bz){ include($file); }else{ include($file . '.php'); } ?>

funct.php代码

1
<?php function get_extension($f){ return pathinfo($f, PATHINFO_EXTENSION); } function check_extension($f){ if($f == 'php'){ return true; }else{ return false; } } ?>

创建一个php文件,如1.php,之后对1.php进行压缩,压缩为1.zip

1.php代码

1
<?php echo "zip:// zipd'sir/xxx.zip%23xxx.zip'sfile"; ?>

.jpg形式:

0x05 phar协议

phar协议的作用是将php文件归档到一个文件包中,功能与zip协议类似。

若要使用此协议,PHP版本要大于5.3.0

创建phar归档文件包时,需要注意的是php.ini文件的phar.readonly参数要设置成Off(php.ini文件里有两个都需要设置成Off)

实例:

1.利用脚本生成phar归档文件包

phar.php源码:

1
<?php $p = new PharData(dirname(__FILE__).'/pharphar.aaa', 0,'pharphar',Phar::ZIP) ; $p->addFromString('phar.txt', '<?php echo dirname(__FILE__);?>'); ?>

也可以自己生成,即新建一个phar.txt文件,文件中写入需要执行的php代码,之后进行zip压缩,之后可以任意的修改后缀名,也可以生成一个归档文件包。

生成文件包的工作在本地完成,之后将归档文件包上传到目标机,之后利用phar协议执行归档文件包中的txt文件(以php文件的格式执行)

参考文章:
php://input,php://filter,data URI schema的那些事
文件包含漏洞小结
一道ctf场景还原&&防御攻破
谈一谈php://filter的妙用

format_list_numbered

(无)

  1. 1. 文件包含漏洞–常见封装协议的利用
    1. 1.0.1. 0x01 php流input(allow_url_include=On)
    2. 1.0.2. 0x02 php流filter
    3. 1.0.3. 0x03 data URLs(allow_url_include=On)
    4. 1.0.4. 0x04 zip协议
    5. 1.0.5. 0x05 phar协议
vertical_align_top

Copyright © 2017 yzc's blog

Powered by Hexo & Theme - Vateral