BUUCTF 2018 - Online Tool
tcl 看着有复现,于是记笔记,学习一下这道题:
<?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); }
这段代码意思是让我们输入一个ip然后对其利用nmap进行扫描,
因为最后执行system()函数,涉及到远程命令执行(RCE)漏洞。
实现RCE的思路就是nmap可以将记录导出为文件,而且文件的路径我们是知道的,所以就可以运行任意php代码。
8多说,首先第一部分:
<?php if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR']; }
获取ip。没什么说的。
第二部分,要传入一个host参数。
对其值先进行escapeshellarg()函数的处理,再调用函数escapeshellcmd()
escapeshellarg会首先在单引号前加反斜线,然后将单引号分割的几部分都用单引号括起来
escapeshellcmd会将`|*?~<>^()[]{}$\, \x0A 和 \xFF以及不配对的单/双引号转义
但是这两个函数配合使用就会导致多个参数的注入。
测试了一下:
<?php $a = "1'"; echo escapeshellcmd(escapeshellarg($a)); ?>
输出'1'\\''\'
中间的\\被解释为\而不再是转义字符。
又了解了nmap可以使用-oG参数将命令以及结果输出到文件。