题目
WRONG WAY!
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET["file1"]) && isset($_GET["file2"]))
{
$file1 = $_GET["file1"];
$file2 = $_GET["file2"];
if(!empty($file1) && !empty($file2))
{
if(file_get_contents($file2) === "hello ctf")
{
include($file1);
}
}
else
die("NONONO");
}
源码分析
-
include("flag.php");
- 这行代码包含了另一个 PHP 文件
flag.php
。通常,这样的包含用于共享函数、类或其他代码片段。在此上下文中,它可能包含一些标志或配置信息。
- 这行代码包含了另一个 PHP 文件
-
highlight_file(__FILE__);
- 这行代码将当前文件的源代码高亮显示。
__FILE__
是一个魔术常量,它包含当前文件的完整路径和文件名。highlight_file
函数会将文件的内容以语法高亮的 HTML 形式输出。
- 这行代码将当前文件的源代码高亮显示。
-
if(isset($_GET["file1"]) && isset($_GET["file2"]))
- 这行代码检查是否通过 GET 方法传递了
file1
和file2
这两个参数。如果两者都存在,代码会继续执行。 -
isset()
是一个语言构造器,用于检测变量是否已设置并且非 NULL。如果变量存在并且不是 NULL,isset()
将返回true
;否则,返回false
。使用
isset()
可以帮助避免在处理变量时遇到未定义或 NULL 的情况。这对于确保脚本的健壮性和安全性非常重要,因为尝试访问未定义的变量或 NULL 值可能会导致警告或错误。
- 这行代码检查是否通过 GET 方法传递了
-
$file1 = $_GET["file1"]; $file2 = $_GET["file2"];
- 这两行代码将 GET 方法传递的
file1
和file2
参数的值赋给变量$file1
和$file2
。
- 这两行代码将 GET 方法传递的
-
if(!empty($file1) && !empty($file2))
- 这行代码检查
$file1
和$file2
是否都不为空。如果它们都不为空,代码会继续执行。
- 这行代码检查
-
if(file_get_contents($file2) === "hello ctf")
- 这行代码读取
$file2
指向的文件的内容,并检查其内容是否完全等于字符串 "hello ctf"。如果是,则执行下面的include($file1);
。 file_get_contents
是 PHP 中的一个函数,用于将整个文件读入一个字符串中。这个函数非常有用,特别是当你需要读取文件内容并将其作为一个字符串进行操作时。-
基本语法
string file_get_contents ( string $filename [, int $flags = 0 [, resource $context = NUL
参数说明:
$filename
:必需。规定要读取的文件的路径。$flags
:可选。规定如何读取文件。可用的标志有FILE_USE_INCLUDE_PATH
、FILE_TEXT
和FILE_BINARY
,它们可以用|
运算符结合使用。默认是0
。$context
:可选。规定文件句柄的环境。$offset
:可选。规定在文件中开始读取的位置。默认是-1
,表示从文件的开头开始。$maxlen
:可选。规定读取的字节数。默认是NULL
,表示读取整个文件。-
file_get_contents
会返回文件的内容作为字符串,如果读取失败,则返回false
。 -
请注意,使用
file_get_contents
读取大文件可能会导致内存使用过高,因为它将整个文件内容加载到内存中。对于大文件,应该考虑使用其他方法,如逐行读取文件或使用流(stream)处理。此外,使用
file_get_contents
读取远程文件(如通过 HTTP 协议)也是可能的,但这样做可能会受到 PHP 的allow_url_fopen
配置选项的限制。如果allow_url_fopen
被禁用,你将无法使用file_get_contents
来读取远程文件。在这种情况下,你可以考虑使用curl
扩展或其他库来处理远程文件请求。
- 这行代码读取
-
include($file1);
- 如果
$file2
的内容等于 "hello ctf",这行代码将包含$file1
指向的 PHP 文件。这意味着$file1
所指向的 PHP 代码将在这个脚本的当前位置执行。
- 如果
-
else die("NONONO");
- 如果
$file1
或$file2
中的任何一个为空,则代码将输出 "NONONO" 并终止执行。
- 如果
playload构造:
这里第一时间想到用伪协议读取flag文件
ctf-web:PHP伪协议 - 学安全的小白 - 博客园 (cnblogs.com)
/?file1=php://filter/convert.iconv.UTF-8*.UTF-32LE*/resource=flag.php&file2=data://text/plain,hello%20ctf
直接拿到flag
file1中用php://filter流来读取flag.php文件,同时用convert.iconv[]过滤器将flag编码输出,没有用convert.base64-encode因为出来的会是一串base64字符串,还要解密。
php://filter的各种过滤器_php://filter过滤器种类-CSDN博客
file2中利用data://协议构造数据流,将hello ctf 当做php文件执行,直接传参行不通,因为file_get_contents是将文件中的数据提取我为字符串。这里不用php://input协议因为它要用post
数据。