[Chapter 2 Web Advanced] SSRF Training 1

Open the environment at the beginning, you can see a link, open it and take a look.
Insert picture description here
Open is a code audit

<?php 
highlight_file(__FILE__);//用PHP高亮显示当前的文件
function check_inner_ip($url) //获取url的域名,将域名转为ip,然后再判断这个ip是否是私有地址
{
    
     
    $match_result=preg_match('/^(http|https)?:\/\/.*(\/)?.*$/',$url); 
  	//返回$url的匹配,值将是 0 次(不匹配)或 1 
    //^从开头开始匹配
   	//? 匹配0或1个正好在它之前的那个字符。注意:这个元字符不是所有的软件都支持的
    //( )标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)
    //.	匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 
    //*	匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*
    //$:从字符串末尾进行匹配
    if (!$match_result) 
    {
    
     
        die('url fomat error'); 
        //如果url不符合正则表达式
    } 
    try 
    {
    
     
        $url_parse=parse_url($url); 
        //分解出一个URL的各个部
        // $url_parse是一个数组
        
    } 
    catch(Exception $e) 
    {
    
     
        die('url fomat error'); 
        return false; 
    } 
    $hostname=$url_parse['host']; //hostname 为主机名,也就是域名
    $ip=gethostbyname($hostname); //通过域名获取IP地址
    $int_ip=ip2long($ip); //ip2long:将IPv4的ip地址(以小数点分隔形式)转换为int
    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; 
    //判断是否是私有地址,是则这个函数就返回1
} 

function safe_request_url($url) 
{
    
     
     
    if (check_inner_ip($url)) 
    //判断url是否是私有地址
    {
    
     
        echo $url.' is inner ip'; 
    } 
    else 
    {
    
    
        $ch = curl_init(); //初始化新的会话,返回 cURL 句柄,供curl_setopt()、 curl_exec() 和 curl_close() 函数使用
        curl_setopt($ch, CURLOPT_URL, $url); //访问的域名
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //
        curl_setopt($ch, CURLOPT_HEADER, 0); //
        //curl_setopt函数参数解释:https://www.cnblogs.com/lilyhomexl/p/6278921.html
        $output = curl_exec($ch); //抓取URL并把它传递给浏览器
        $result_info = curl_getinfo($ch); //php curl请求在curl_exec()函数执行之后,可以使用curl_getinfo()函数获取CURL请求输出的相关信息
        //[php curl curl_getinfo()返回参数详解](https://www.cnblogs.com/zqifa/p/php-curl-3.html)
        if ($result_info['redirect_url']) 
        {
    
     
            safe_request_url($result_info['redirect_url']); 
        } 
        curl_close($ch); // 关闭cURL资源,并且释放系统资源
        var_dump($output); //执行
    } 
     
} 

$url = $_GET['url']; 
if(!empty($url)){
    
       //判断url是否为空,不为空就执行
    safe_request_url($url); 
} 

First of all, we go through this functioncheck_inner_ip, The general meaning of this function is to filter some private ips, that is, ips that can access local files. First
Insert picture description here
look at what this function does. You can see that it is probably a regular match and then parse the url.
Insert picture description here
I won’t introduce more rules here. The source code above is very clear. I will mainly introduce the bypass of URL parsing. Let’s take a look at this article and analyze the various parts of a complete URL
here. Use a complete url to parse it and take a look first. The
Insert picture description here
result
Insert picture description here
can be found here that these are one-to-one correspondence, so we can change to the address we want to request in other locations.
The incoming URL is http://a:@127.0.0.1:[email protected], then the host retrieved by parse_url after entering safe_request_url detection is baidu.com.
Insert picture description here
In this way, the function can be detected, and curl gets 127.0.0.1:80, so it is realized that when the IP is detected, it is a normal website domain name, but when the actual curl request is made, it is constructed as 127.0.0.1.

Guess you like

Origin blog.csdn.net/qq_45951598/article/details/114387274