因为国庆放假和最近一直在换系统的缘故有一段时间没有更新。这是我在ubuntu上写的第一篇文章;
打开题目得到如下源码:
1 php 2 3 if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 4 $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR']; 5 } 6 7 if(!isset($_GET['host'])) { 8 highlight_file(__FILE__); 9 } else { 10 $host = $_GET['host']; 11 $host = escapeshellarg($host); 12 $host = escapeshellcmd($host); 13 $sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']); 14 echo 'you are in sandbox '.$sandbox; 15 @mkdir($sandbox); 16 chdir($sandbox); 17 echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host); 18 } 19 ?>
可以看到在代码第11和12行的地方连续依次使用了escapeshellarg,escapeshellcmd 函数。对于我这种菜鸡来说没见过的函数那必然是这个题目的考点。百度之后可以找到一个很有名的叫做'PHP escapeshellarg()+escapeshellcmd() 之殇'的文章。这里提供了这道题的主要思路:
关于两个函数的介绍如下
escapeshellarg — 把字符串转码为可以在 shell 命令里使用的参数
功能 :escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,shell 函数包含 exec(), system() 执行运算符(反引号)
定义 :
string escapeshellarg ( string $arg )
escapeshellcmd — shell 元字符转义
功能:escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。
反斜线(\)会在以下字符之前插入: `|\?~<>^()[]{}$*, \x0A 和 \xFF*。 *’ 和 “ 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替。
定义 :
string escapeshellcmd ( string $command)
题目代码中要传入一个host的值,如果我们传入的参数是127.0.0.1' shellcode 那么先由escapeshellarg()处理成 '127.0.0.1'\'' shellcode'即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。再经过escapeshellcmd()处理后变成 '127.0.0.1'\\'' shellcode \'即escapeshellcmd对\以及最后那个不配对的单引号进行了转义。最后执行的命令是 curl '127.0.0.1'\\'' shellcode \'。由于中间的\\
被解释为\
而不再是转义字符,所以后面的'
没有被转义,与再后面的'
配对儿成了一个空白连接符。所以可以简化为curl 127.0.0.1\ shellcode'(相关知识:
Linux Shell 单引号 双引号 使用区别)
再回到本题,我们只需要构造参数进行闭合造成注入即可。nmap中有一个可以利用的参数-oG能够帮我们将字符串写入一个文件中:可以想到写入一句话木马连接shell获取flag:
我们需要linux服务器执行的命令为:nmap -T5 -sT -Pn --host-timeout 2 -F ' -oG 1.php'
于是我们根据上面的分析将payload构造成 ?host=' -oG hack.php ' 前面的127.0.0.1我们可以不写,然后在payload的最后面加上一个空格和单引号,单引号的目的是闭合处理后得到的最后那个单引号,如果不加空格的话文件最后面会变成
'\\'''
即文件最后面会多出来\\,加了空格之后会变成 hack.php \ ,不影响命令的执行。
写入之后会返回sandbox编号,之间蚁剑连接shell 到根目录下面cat flag就能读取到flag。
gg
参考:
- https://blog.csdn.net/qq_26406447/article/details/100711933
- https://www.dazhuanlan.com/2020/03/01/5e5aef3248649/?__cf_chl_jschl_tk__=abc8b79a01976e645edc673ee5981c12a400f0aa-1602337962-0-AX16Af1CNl7wtmryWDqZBU4qpbe_o9rEf-EFwqCE9EiBbbix_Izp_UuYurjG5vTe7An2jgzrCwjw0ypmbHcN1XYXqDsk2WAz7yA0lWMdtjSbJ8Ut_yOt1QBjzN2bcteQYX8UDwxCfSrS2wIijY7nmlneAwsXOE7lIw8HwbCoLuBawMpRKBX-T-45Q06HNia7h9JgoOM7CvQO2bBQXsSBpwqNPfFYgjnaYvY3yNmtZfJGQDlFBZcdD9y_tryUHNg-ATypJHiGNylUhA2A8oy7EDP92RkiyFvRVIOea-p7vveANGoJgDzrWKEN-zoIvsY2LQ
- https://paper.seebug.org/164/
escapeshellarg — 把字符串转码为可以在 shell 命令里使用的参数
功能 :escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,shell 函数包含 exec(), system() 执行运算符(反引号)
定义 :
string escapeshellarg ( string $arg )