基本原理
后端编程人员一般会把重复使用的函数写到单个文件中,需要使用时再直接调用此文件即可,该过程也就被称为文件包含。文件包含的存在使得开发变得更加灵活和方便,但同时也带了安全问题,导致客户端可以远程调用文件,造成文件包含漏洞。这个漏洞在php中十分常见,其他语言也有。
几个常见的文件包含函数
- include()
- require()
- include_once()
- require_once()
include和require的区别只在于是否会在报错后继续执行脚本
php伪协议
1.常用伪协议
file:// | 访问本地文件系统 |
http:// | 访问https网站 |
php:// | 访问各个数据流 |
phar:// | php归档 |
zip:// | 压缩流 |
举个例子
?file=php://filter/read=convert.base64-encode/resource=index.php
这就是将index文件用base64翻译出来后打印,至于为什么要用base64,因为直接执行就会直接执行index.php就无法看到文件中的内容。
2.file://详解
用法:
file:// [文件的绝对路径和文件名]
比如
file:///var/www/html/index.php
file://一般不会单独使用,极有可能附带一些php://这类伪协议。
比如常见构造
?file=php://filter/read=convert.base64-encode/resource=index.php
以上用来以base64输出index.php的源码。
3.php://详解
1.php://filter
用来读取源码的伪协议,在题目中经常用到,一般不作为难点,但是还是防止背刺,在这里贴一个链接。
这里提到一题 比较经典的题目 [羊城杯 2020]easyphp2
它过滤了base64导致无法使用base64加密输出源码。所以需要用到其他过滤器。比如
convert.quoted-printable-encode & convert.quoted-printable-decode
最后出来的是可打印字符引用编码,但有点乱,这里贴上转换工具
还有一种思路是通过对base64二次url编码(可以只对b进行编码二次后是%25%36%32)
?file=php://filter/read=convert.%25%36%32ase64-encode/resource=GWHT.php
结果也可以出来。
看了大佬wp后还发现另外一种方法
?file=php://filter/read=convert.iconv.utf-8.utf-16be/resource=GWHT.php
确实是不知道这种过滤器
2.php://input
一个非常有用的伪协议,可以用来执行post的语句。
源码如下
<?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 ! ";
}
?>
4.总结
还有一些技巧下一次总结,以上基本包含了常用的协议,当然现在的题目感觉越出越怪,基础的知识可能用来解前几步,后面还是得看一些比较新的思路了。
希望自己不要这么菜吧 _(:з」∠)_ ----L1men2