# Vultr Domain Hijacking

TLDR: Vultr does not verify domain ownership when adding new domains. This allows the hijack of abandoned domains by pretty much anyone with an account and *verified payment method*

#### Disclosure Timeline <a href="#disclosuretimeline" id="disclosuretimeline"></a>

`2018/04/09`: Reported to Vultr to see if they will fix and accept under bug bounty program.\
`2018/04/13`: Won't fix at this time. System is *designed* to not require verification. This is just a *side effect*.

### Vultr DNS Service <a href="#vultrdnsservice" id="vultrdnsservice"></a>

Vultr's DNS service does not use DNS verification. This means that anyone can take management of the domain name that's pointing to ns\[02].vultr.com. Below shows some screenshots of the interface used to add new domains to your DNS service management section of Vultr.

![](/files/-LQ2m3_pvpoKGk0xF_A4)

No verification of the domain is needed to add it, as shown below:

![](/files/-LQ2m50DMHL5X6ahs1Tu)

A payment method is required before you can start using the DNS services, but you don't need to verify payment to be able to check if a domain exists already on the Vultr DNS system. The following screenshot shows a list of payment methods that are accepted, so you can verify payment using gift codes, and Bitcoin.

![](/files/-LQ2m8BhlDxNUbol-b35)

Great, but there's also an API available to automate adding new domains, and Vultr links to it nicely. See <https://www.vultr.com/docs/introduction-to-vultr-dns> and <https://www.vultr.com/api/#dns>

It was trivial to set up a parallel curl command to perform this but I decided to use Burp Intruder with 2 threads at 750 ms per request (+latency Vultr). There's a maximum of 2 requests a second. The following request will add a new domain to your account.

```
POST /v1/dns/create_domain HTTP/1.1
Host: api.vultr.com
API-Key: YOURVULTRAPIKEY
domain=$domain.com$&serverip=127.0.0.1
```

A possible addition will yield a response similar to the following:

```
HTTP/1.1 412 Request Failed
Server: nginx
Date: Mon, 09 Apr 2018 01:21:55 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
X-User: YOURVULTREMAILADDRESS
Content-Length: 80

Unable to create domain: To begin adding domains, please link a payment method!
```

I get the above error message because I used an account with no payment info attached. Once I got the domains, I decided to just add it on my main account.

An invalid attempt will yield the following response:

```
HTTP/1.1 412 Request Failed
Server: nginx
Date: Mon, 09 Apr 2018 01:13:50 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
X-User: YOURVULTREMAILADDRESS
Content-Length: 47

Unable to create domain: Domain already exists
```

By comparing response length in Burp, it is easy to see which domains are vulnerable:

![Intruder sorted by content length](/files/-LQ2mB5PaUf_klJjaCT6)

### Why would any domain ever be configured this way? <a href="#whywouldanydomaineverbeconfiguredthisway" id="whywouldanydomaineverbeconfiguredthisway"></a>

1. A Vultr customer decides to use their DNS services so they point their domain at their nameservers.
2. At this point, either they never added the domain name to their control panel in Vultr or they had later removed it after wanting to stop using their services.
3. Either way, the attacker could find that it's no longer registered on Vultr and add it to their Vultr DNS control panel.
4. Attacker now has control over records and hijacks the domain.

### Domains <a href="#domains" id="domains"></a>

So you have a way to add domains, and test if they're vulnerable based on response. How do you get the list of domains to try?

Remember that I released a tool called [DomLink](https://vincentyiu.co.uk/domlink-automating-domain-discovery/) a couple of days ago? I was also working on many other DNS tools. I found viewdns.info, which has reverse NS lookups. EXACTLY what want to find right? Old cached reverse NS lookups that may or may not be currently valid.<br>

![](/files/-LQ2mF37IbohWAAdNNyF)

Taking all of these domains, we go through a filtering process to find current domains pointing to ns1.vultr.com still. I used the following command:

```
cat vultr-ns1.txt | parallel -j 32 “dig {} +short ns | head -n 1 | sed -e ‘s/^/{}:/g’ | grep [vultr.com](http://vultr.com/) | tee -a vultr-go.txt”
```

Fantastic, now I had a list of about 10,000 domains.

### Example Hijacking <a href="#examplehijacking" id="examplehijacking"></a>

![](/files/-LQ2mI20pBoEfguQnEca)

![](/files/-LQ2mKCgraZxObKEFnOG)

### Results <a href="#results" id="results"></a>

As you'd expect, this isn't a particularly widespread issue. In fact, I had only found about **10 hijackable domains** and were mainly non-reputable in terms of proxy categorization and trust. The reputation issue is probably due to it being Vultr’s service and although my opinion is biased, has not yet attracted the bigger companies. More reputable companies use clouds such as Amazon, Azure, and Alibaba — probably due to their reputation. Nevertheless, it's still important that customers are aware and are cautious when using such services. For the general public, it's worth keeping track and maintain your DNS entries - whether these be NS records or CNAME records.

We can see that over the last few months, I and a few other researchers have begun to release our information on using services that do not validate domain ownership to hijack abandoned instances. It's definitely a trend and it's something that many cloud providers, small and large alike, across the board seem to be struggling with.

**Solution: Require another domain verification step before allowing the user to add their domain to your service, and take control of that domain.**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.vincentyiu.com/red-team/cloud-security/vultr-domain-hijacking.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
