[极客大挑战 2019]Secret File

查看网页源代码

发现有.php访问一下


bp抓包

返回的页面中有注释的.php
查看一下

访问flag.php

那审计一下代码

点击查看代码
<html>
    <title>secret</title>
    <meta charset="UTF-8">
<?php
    highlight_file(__FILE__);
    error_reporting(0);
    $file=$_GET['file'];
    if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
        echo "Oh no!";
        exit();
    }
    include($file); 
//flag放在了flag.php里
?>
</html>

这段代码展示了一个存在文件包含漏洞的 PHP 脚本,下面是详细解释:
代码功能
基本结构:这是一个 HTML 文件,包含 PHP 代码,设置了 UTF-8 编码。
显示源代码:highlight_file(FILE) 会高亮显示当前文件的源代码。
错误报告:error_reporting(0) 关闭所有错误报告。
文件包含功能:
从 GET 参数 file 获取文件名
对文件名进行一些安全检查
如果通过检查,则包含该文件
安全限制
代码尝试阻止某些危险的文件包含:
../ - 防止目录遍历
tp - 可能想阻止 "phar://" 等协议
input - 阻止 "php://input" 流
data - 阻止 "data://" 协议
漏洞点过滤不完整:
只检查了小写的 "tp",可以使用大写或混合大小写绕过
没有过滤其他危险协议如 php://filter
注释提示:注释明确说明 flag 在 flag.php 中,这提示攻击目标
潜在攻击方式
本地文件包含:如果过滤可以被绕过,可以读取 flag.php
例如:?file=flag.php
协议利用:如果允许,可以使用 php 包装器
例如:?file=php://filter/convert.base64-encode/resource=flag.php 读取 base64 编码的文件内容


解码后的到flag

注:
给定的 PHP 代码中,flag.php 的内容无法直接通过浏览器访问,而必须通过 ?file=php://filter/convert.base64-encode/resource=flag.php 这样的方式读取,原因如下:

  1. flag.php 可能没有直接输出内容
    假设 flag.php 的代码是:

php

直接访问 flag.php:由于没有 echo $flag;,浏览器会显示空白页面。

通过 include 包含:include($file) 只是执行代码,但如果没有输出,仍然看不到 $flag。

  1. include() 与直接访问的区别
    直接访问 flag.php:

服务器执行 flag.php,但如果没有输出语句(如 echo),浏览器看不到内容。

如果 flag.php 有敏感信息(如数据库密码),通常不会直接暴露。

通过 include 包含 flag.php:

代码会被合并到当前脚本(secret.php)中执行。

如果 flag.php 定义了变量(如 $flag),可以在 secret.php 中访问它(但原代码没有后续操作)。

  1. 为什么 php://filter 能读取源码?
    使用:

?file=php://filter/convert.base64-encode/resource=flag.php
php://filter 是一个 PHP 流包装器,它会:

读取 flag.php 的 原始文件内容(包括 PHP 代码)。

用 Base64 编码返回,避免 PHP 执行代码。

最终在页面上显示 Base64 编码的 flag.php 源码,而不是执行它。

  1. 原代码的安全限制
    php
    if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
    echo "Oh no!";
    exit();
    }
    黑名单过滤了:

../(目录遍历)

tp(阻止 phar:// 或 php://,但大小写不敏感,PHP:// 可绕过)

input(阻止 php://input)

data(阻止 data://)

但 php://filter 没有被完全阻止(因为只检测 tp,而 php:// 可以绕过)。

  1. 为什么不能直接 ?file=flag.php?
    即使尝试:

?file=flag.php
如果 flag.php 只有 ,include 执行后不会有输出。

如果 flag.php 包含 echo,可能会显示内容,但通常 CTF 题目会避免这种情况,强制使用 源码泄露 的方式(如 Base64 编码)。

  1. 总结
    访问方式 结果
    直接访问 flag.php 空白(无输出)
    ?file=flag.php 空白(include 但无输出)
    ?file=php://filter/convert.base64-encode/resource=flag.php 返回 Base64 编码的 flag.php 源码
posted on 2025-05-21 10:21  D10  阅读(12)  评论(0)    收藏  举报