查看题目,点击intersting challenge发现源码
然后就是源码审计
首先url经过的函数是
function check_inner_ip($url)
{
//正则匹配
$match_result=preg_match('/^(http|https)?:\/\/.*(\/)?.*$/',$url);
if (!$match_result)
{
die('url fomat error');
}
try
{ //解析url,详细见下
$url_parse=parse_url($url);
}
catch(Exception $e)
{
die('url fomat error');
return false;
}
$hostname=$url_parse['host'];
$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;
}
对整个url进行解析
然后解析之后只取了host的内容
接着往下分析
host经过gethostbyname函数
如果能解析的话就是返回IP地址
不能解析的话就是返回原来的字符串
最后判断ip是不是私有地址
绕过这个函数只需要把它的host字段改成不是以127,10,172.16,192.168,开头的私有ip
我在本地执行代码报错
因为curl是php的一个扩展
这段的话就是通过curl去访问一个url得到响应的数据
$ch = curl_init();
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);
有一个问题卡了我好久
payload:http://a:@127.0.0.1:80@baidu.com
这里它取到的host为baidu.com
可以绕过gethostbyname函数
那这个payload又是怎么绕过safe_request_url函数的
搭个环境自己测试一下
1.php源代码
<?php
function safe_request_url($url)
{
$ch = curl_init();
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);
echo $result_info["url"];
echo "<br>";
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);
}
正常情况下可以打出this is flag!
可是换成了本题的payload
发现它不会并打出flag.php里的内容