DNS 리바인딩 공격

Bye Bye~~ 이 문제를 풀면서 알게 된 새로운 공격법이 있어서 정리하려고 가져왔습니다.

DNS 리바인딩 공격

이 공격은 도메인 이름의 해상도를 조작하는 방법입니다.

일반적으로 악의적인 공격을 방지하려면 도메인 이름을 확인하고 DNS로 도메인의 IP를 확인합니다.

그런 다음 해당 URL에 액세스합니까??

그러나 도메인의 IP를 확인하는 요청 로직과 URL에 접근하는 로직이 다르기 때문에 악의적인 공격이 가능하다.

쓰다보면 느낌이 좋지않나요??

로컬에서 환경을 구축하고 보여드리겠습니다.


다음은 그 공격의 흐름입니다.


간단한 DNS 리바인딩 테스트를 구축했습니다.

// index.js
const express = require('express');
const path = require('path');
const dns = require('./dns');

const app = express();
const port = process.env.PORT || 10235;

app.get('/', async(req, res) => {
    return res.sendFile(path.join(__dirname + '/static/index.html'));
});

app.get('/send', async(req, res) => {
    return res.sendFile(path.join(__dirname + '/static/send.html'));
});

app.get('/proxy', async (req, res) => {
    const {url} = req.query;
    const result = await dns.dnsResolve(url);
    res.send(result);
})

app.listen(port, () => {
    console.log(`${port} is listening!`);
});
const dns = require("dns/promises");
const axios = require("axios");

dns.setServers((
    '1.1.1.1',
    '8.8.8.8',
));

async function dnsResolve(url) {
    const address = await dns.resolve4(url);
    console.log("IP is "+address);

    const res = await axios.get("http://"+url);
    console.log(res.data);
    return res.data;
}

module.exports = {
    dnsResolve,
};

index.js를 보면 /send 엔드포인트에 url이 입력되면 /proxy 엔드포인트로 이동하여 해당 url에 대한 get 요청을 보낸다.



dns.resolve4(url)의 IP는 http://example.com에서 IP 및 축.get(URL) URL로 보낸 get 요청의 응답 값이 출력됩니다.

https://lock.cmpxchg8b.com/rebinder.html

rbndr.us DNS 리바인딩 서비스

lock.cmpxchg8b.com

DNS 리바인딩 공격을 위한 URL을 생성하는 사이트입니다.


사이트에 진입한 후 A는 우회할 IP를 쓰고, B는 get 요청을 통해 접속할 IP를 씁니다.

그러면 아래에 URL이 나타납니다.


이렇게 127.0.0.1일 때도 있고 내가 입력한 10.37.21.12일 때도 있다.

이 문제는 서버가 매우 짧은 TTL로 응답할 때 발생합니다.

DNS 리바인딩 공격은 SSRF 공격의 일종으로 꽤 오래전에 나왔던 공격이지만 아직까지도 사용되고 있는 것으로 보인다.
오늘은 여기까지 포스팅하고 제가 심화한 부분들과 다양한 CVE들을 분석하면서 글을 추가하도록 하겠습니다.