题目地址:http://ctf473831530.yulige.top:12345
Tips1: flag.php
Tips2: 常见端口
<?php
highlight_file(__FILE__);
function check_inner_ip($url)
{
$match_result=preg_match('/^(http|https|gopher|dict)?:\/\/.*(\/)?.*$/',$url); //preg_match()返回 pattern 的匹配次数
if (!$match_result)
{
die('url fomat error');
}
try
{
$url_parse=parse_url($url); //解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分。
}
catch(Exception $e)
{
die('url fomat error');
return false;
}
$hostname=$url_parse['host'];
$ip=gethostbyname($hostname); //本函数可返回某个机器名称 (Domain Name) 的 IP 网址 (IP Address)
$int_ip=ip2long($ip); //将IPv4地址转换成整型
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地址第一个字节是127或者10或者172或者192
}
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); //需要获取的URL地址,也可以在PHP的curl_init()函数中设置。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //如果成功只将结果返回,不自动输出任何内容。
如果失败返回FALSE
curl_setopt($ch, CURLOPT_HEADER, 0); //如果你想把一个头包含在输出中,设置这个选项为一个非零值。
$output = curl_exec($ch); // 执行一个cURL会话
$result_info = curl_getinfo($ch); //可以在请求 curl 会话中的相关信息
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);
}
?>
分析代码发现:check_inner_ip
通过 url_parse
检测是否为内网 ip
如果满足不是内网 ip ,通过 curl
请求 url 返回结果。
乍一看好像并没有利用点,跳转也做了处理,最终都要经过 check_inner_ip 函数检测。但是忽略了 php_url_parse 和 curl 同时处理 url 不同。
参考资料:https://blog.csdn.net/qq_39293438/article/details/84899550