项目作者: mathewmarcus

项目描述 :
DNS-rebinding server
高级语言: C
项目地址: git://github.com/mathewmarcus/rebind.git
创建时间: 2021-03-20T17:02:08Z
项目社区:https://github.com/mathewmarcus/rebind

开源协议:

下载


rebind

DNS server for the discovery and testing of SSRF DNS rebinding vulnerabilities.

SSRF via DNS Rebinding

Imagine web application code - such as the following - intended to prevent SSRF:

  1. from flask import request
  2. import ipaddress
  3. import requests
  4. import socket
  5. import urllib.parse
  6. attributes = urllib.parse.urlparse(request.form['url'])
  7. host, port = socket.getaddrinfo(attributes.hostname, attributes.port, family=socket.AF_INET, type=socket.SOCK_STREAM)[0][-1]
  8. ip = ipaddress.IPv4Address(host)
  9. if ip.is_global:
  10. requests.get(request.form['url'])

Note that here there are 2 DNS lookups:

  1. DNS lookup to validate the URL
  2. DNS lookup as part of the HTTP request

The above logic creates a time-of-check to time-of-use (TOCTTOU) race condition which can potentially be exploited by a DNS server - such as this - which does the following:

  1. Returns a public A/AAAA/CNAME record with a low TTL (this is used in the URL validation)
  2. Returns a private/reserved/loopback/link_local A/AAAA/CNAME record (this is used in the actual HTTP request)

Build

  1. $ mkdir build
  2. $ cd build
  3. $ cmake ..
  4. $ cmake --build .

Installation

  1. $ sudo make install

Usage

Options

  • -t: DNS TTL (default 0)
  • -c: number of legitimate responses for each reserved response (default 1)
  • -6 (${HOST_IP} is an IPv6 address)
  • -a: public A record target (default 0.0.0.0)
  • -A: public AAAA record target (default ::)
  • -C: public CNAME record target
  • -p: alternative UDP port on which to listen for DNS requests (default 53)
  • -i: interface on which to listen (default is to listen on 0.0.0.0)

Running

  1. Create a CSV file of the form qtype,subdomain,reservedIP. An example of such a file is example.csv
  2. Run the DNS server
    1. $ rebind [-c ${VALID_RESPONSE_COUNT}] [-t ${TTL}] [-a ${PUBLIC_A}] [-A ${PUBLIC_AAAA}] [-C ${PUBLIC_CNAME}] [-6] [-p ${PORT}] ${DOMAIN_NAME} ${FILENAME} ${HOST_IP}

Reloading

Changes to the CSV file can be reloaded without restarting the server

  1. $ kill -s SIGHUP ${PID}

Example Usage

Server:

  1. $ cat ./example.csv
  2. A,one,127.0.0.1
  3. A,two,192.168.0.1
  4. A,three,169.254.169.254
  5. AAAA,four,::1
  6. A,five,127.0.0.2
  7. CNAME,six,admin.internal.corp
  8. $ rebind example.com ./example.csv 34.232.67.223

Client:

  1. $ dig +noall +answer one.example.com @127.0.0.1
  2. one.example.com. 0 IN A 0.0.0.0
  3. $ dig +noall +answer one.example.com @127.0.0.1
  4. one.example.com. 0 IN A 127.0.0.1