[BUUCTF 2018]Online Tool
<?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);
}
对这个代码进行一下分析,它的功能是接收一个host
参数,然后用nmap命令对该主机进行端口扫描,并输出结果
-
首先,它检查了
$_SERVER['HTTP_X_FORWARDED_FOR']
变量,如果存在,就将$_SERVER['REMOTE_ADDR']
设置为该变量的值。这是一种获取用户真实IP地址的方法,因为有些用户可能使用了代理服务器或者负载均衡器,导致$_SERVER['REMOTE_ADDR']
变量不准确。 -
然后,它判断了
$_GET['host']
参数是否存在,如果不存在,就显示当前文件的源代码,这是一种常见的代码审计技巧,可以让用户看到后台的逻辑和漏洞。 -
如果
$_GET['host']
参数存在,就对其进行两次转义处理,分别是escapeshellarg()
和escapeshellcmd()
函数。这两个函数的作用是防止用户输入的参数中包含恶意的命令或者特殊字符,从而造成命令注入的风险。escapeshellarg()
函数会在参数两边加上单引号,escapeshellcmd()
函数会对参数中的元字符进行转义,例如|
,&
,;
等。 -
接下来,它使用
md5()
函数生成一个沙盒目录的名称,该名称由一个固定的字符串glzjin
和host拼接而成。然后,它在当前目录下创建这个沙盒目录,并切换到该目录。这是一种隔离用户的操作的方法,防止用户对其他目录或者文件造成影响。 -
最后,它使用
system()
函数执行nmap
命令,对用户输入的主机进行端口扫描,并将结果输出。nmap
命令的参数如下:-T5
表示使用最快的扫描速度,可能会导致一些端口被遗漏或者误报。-sT
表示使用TCP连接扫描,这种扫描方式比较可靠,但也比较容易被防火墙或者入侵检测系统发现。-Pn
表示不对主机进行存活性检测,直接进行端口扫描,这可以避免一些防御措施,例如ICMP过滤或者防止ping扫描。--host-timeout 2
表示对每个主机的扫描时间限制为2秒,如果超过这个时间,就放弃扫描,这可以提高扫描效率,但也可能导致一些端口被漏掉。-F
表示只扫描100个最常见的端口,这可以缩短扫描时间,但也可能错过一些不常见的端口。
接下来我们需要绕过escapeshellarg()
和escapeshellcmd()
函数。
escapeshellarg()和escapeshellcmd()函数的功能
escapeshellarg:
(PHP 4 >= 4.0.3, PHP 5, PHP 7)
把字符串转码为可以在 shell 命令里使用的参数
string escapeshellarg ( string $arg )
escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。shell 函数包含 exec(), system() 执行运算符
概述:
1.确保用户只传递一个参数给命令
2.用户不能指定更多的参数一个
3.用户不能执行不同的命令
escapeshellcmd:
(PHP 4, PHP 5, PHP 7)
shell 元字符转义
string escapeshellcmd ( string $command )
escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义;反斜线(\)会在以下字符之前插入: &#;`|*?~<>^()[]{}$, \x0A 和 \xFF;’ 和 " 仅在不配对儿的时候被转义;在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替
概述:
1.确保用户只执行一个命令
2.用户可以指定不限数量的参数
3.用户不能执行不同的命令
函数漏洞的利用
使用escapeshellcmd / escapeshellarg时不可能执行第二个命令,但是我们仍然可以将参数传递给第一个命令,这意味着我们也可以将新选项传递给命令,利用漏洞的能力取决于目标可执行文件,可以在下面找到一些已知可执行文件的列表,其中包含一些可能被滥用的特定选项
单独使用escapeshellarg
和escapeshellcmd
中任意一个都不会出现问题,或者先使用escapeshellcmd
再使用escapeshellarg
也不会出现问题,唯有题目中先escapeshellarg
再escapeshellcmd
会有漏洞
我们要rce,但是又不能拼接命令,就只能借用nmap参数,有-oG参数可以实现将命令和结果写到文件
payload:?host=' <?php echo phpinfo();?> -oG 1.php '