The learning of php 文件包含
文件包含
概述
文件包含顾名思义, 通过某些函数来引入一些文件但传入的文件名没有经过合理的验证, 从而操作了预想之外的文件, 就可能导致意外的文件泄漏甚至恶意代码注入。
常见的文件包含函数
include()require()include_once()require_once()highlight_file()show_source()readfile()file_get_contents()fopen()file()
PHP伪协议
通常情况下有文件包含函数还不够, 需要搭配伪协议才能干更多的事情
| 协议 | PHP版本 | alow_url_fopen | allow_url_include | 用法示例 |
|---|---|---|---|---|
| file:// | >=5.2 | off/on | off/on | file://D:/soft/phpStudy/WWW/flag.txt |
| php://filter | >=5.2 | off/on | off/on | php://filter/read=convert.base64-encode/resource=./index.php |
| php://input | >=5.2 | off/on | on | php://input [post data]: <?php phpinfo() ?> |
| zip:// | >=5.2 | off/on | off/on | zip://D:/soft/phpStudy/WWW/file.zip%23flag.txt |
| compress.bzip2:// | >=5.2 | off/on | off/on | compress.bzip2://D:/soft/phpStudy/WWW/file.bz2 compress.bzip2://./file.bz2 |
| compress.zlib:// | >=5.2 | off/on | off/on | 同上 |
| data:// | >=5.2 | on | on | data://text/plain,<?php phpinfo()?>data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4= |
包含日志文件
Web服务器一般会将用户的访问记录保存在日志文件当中. 如果存在文件包含的函数, 而且知道日志文件的路径, 可以构造请求把PHP代码写进日志文件中并引入执行
寻找日志文件
日志文件的目录一般会被修改, 可以寻找httpd.conf,nginx,conf或者根据phpinfo()中的信息来得知日志文件目录
Apache:
Windows:
<Apache安装目录>\logs\access.log | error.logLinux:
/usr/local/apache/logs/access_log | error_log
Nginx:
/var/log/nginx
包含session.upload_progress
PHP版本: 5.4+
在php5.4以上添加了一个新的功能 session.upload_progress, 这个功能在客户端上传文件的时候会创建一个session文件, 默认路径应该是/tmp/tmp, 这个文件里存储的上传文件的进度.
不过, 要利用这个session.upload_progress, 还要依靠另外一个php.ini的默认选项session.use_strict_mode = 0, 当这个值为0的时候, 用户是可以自己定义Session ID的, 比如在Cookies中设置PHPSESSID = k1rit0, php将在服务器上创建一个tmp/tmp/sess_k1rit0, 并且自动初始化, 也就是会在里面写入
1 | session.upload_progress.prefix + session.upload_progress.name |
session.upload_progress.prefix是服务端设置的, 默认为upload_progress_session.upload_progress.name是用户POST的data: PHP_SESSION_UPLOAD_PROGRESS, 比如POST PHP_SESSION_UPLOAD_PROGRESS= <?php eval($_POST["cmd"]);?>
那么用户在上传文件的时候, 就会生成这么一个session文件
1 | upload_progress_ eval($_POST["cmd"]); | // 后面是上传进度 |
很显然这个文件如果被文件包含函数包含, 则可以执行一系列的命令
但是这个session文件将在文件上传完成之后自动删除.这里就需要利用条件竞争了, 不停的上传同样的文件, 使得session一直存在.