<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Patrik Hudak]]></title><description><![CDATA[Cybersecurity. Automation. Infinity.]]></description><link>https://0xpatrik.com/</link><image><url>https://0xpatrik.com/favicon.png</url><title>Patrik Hudak</title><link>https://0xpatrik.com/</link></image><generator>Ghost 3.0</generator><lastBuildDate>Fri, 10 Apr 2026 19:29:23 GMT</lastBuildDate><atom:link href="https://0xpatrik.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Subdomain Takeover: Going for High Impact]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>When I and other guys in the web application security started posting stuff around subdomain takeover, it has become increasingly hard to find new cases in the public bug bounty programs. There was more competition than ever, but also, cloud providers such as AWS or Heroku started to implement mitigations</p>]]></description><link>https://0xpatrik.com/subdomain-takeover-impact/</link><guid isPermaLink="false">5fd8b48b99dbd2662ae9e80b</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Tue, 15 Dec 2020 14:15:33 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2020/12/takeover-2.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2020/12/takeover-2.jpg" alt="Subdomain Takeover: Going for High Impact"><p>When I and other guys in the web application security started posting stuff around subdomain takeover, it has become increasingly hard to find new cases in the public bug bounty programs. There was more competition than ever, but also, cloud providers such as AWS or Heroku started to implement mitigations to prevent subdomain takeovers in the first place. At the same time, bug bounty programs begin to set clear rules for subdomain takeover reports, mostly falling into Medium severity.</p>
<p><img src="https://0xpatrik.com/content/images/2020/12/Screen-Shot-2020-12-15-at-14.45.00-1.png" alt="Subdomain Takeover: Going for High Impact"></p>
<p>For someone like me, who deeply explored the realms of takeovers as well as their implications, this bothered me a lot. Not the fact that I am unable to find more <em>&quot;low hanging fruit&quot;</em>, but rather that companies are taking a blindfolded view about the impact of subdomain takeovers in their infrastructure. I thus started to think about every possible escalation you can make to showcase the high impact this problem can have. This post explains my conclusions.</p>
<h2 id="cloudprovidermatter">Cloud Provider Matter</h2>
<p>Don't get me wrong. I still get a lot of subdomain takeover cases each month. However, as I explained above, most vulnerable cloud providers took a radical step and started to mitigate such problems in different ways:</p>
<ul>
<li>Disallowing to register a custom domain name under a different account. For instance, if a domain <em>takeover.example.com</em> was registered under <em>account1</em>, the provider doesn't allow to register it under <em>account2</em></li>
<li>Adding domain verification. In order to add a custom domain, you are required to provide proof that you actually own the domain. This usually takes form in adding TXT records to the DNS which of course you, unfortunately, don't have access to.</li>
<li>Adding entropy. Some services generate a random string that is a required part of the CNAME record in order to prevent takeovers. This is usually a strong enough defense since API rate limits won't allow you to brute force it (or the range of possibilities is really large). This is done for example in AWS ELB.</li>
</ul>
<p>You should refer to <a href="https://github.com/EdOverflow/can-i-take-over-xyz">https://github.com/EdOverflow/can-i-take-over-xyz</a> in order to verify whether some provider is vulnerable or not.</p>
<p>In order to plan the possible escalation paths, you also need to know what the cloud provider allows you to do with the takeover domain. Unless you are able to point the domain to your VPS instance, you will pretty much be limited with some functionality. For instance:</p>
<ul>
<li><strong>Amazon S3</strong> — Allows to host static content, but you won't be able to execute dynamic content such as Python scripts in the backend.</li>
<li><strong>Microsoft Azure CloudApp</strong> — Allows specifying dynamic container, however, you don't get the freedom of fully controlling the deployed environment.</li>
</ul>
<p>The best takeover you can hope for is Microsoft TrafficManager. This allows you to specify your own A records once the <em>victim</em> does a DNS resolution. Once you point it to your VPS instance, you are pretty much unrestricted.</p>
<p>It is important to think about obtaining a valid SSL certificate. When the domain points to your VPS instance, it is straightforward to just request a Let's Encrypt cert using <em>certbot</em> and the full process is done automatically. In cases such as Amazon Elasticbeanstalk, you are not able to install <em>certbot</em> in the environment. You are still able to obtain it manually by creating a valid HTTP endpoint with the specified string and signed nonce as requested by Let's Encrypt validation. Certificates will be an important part of the next sections.</p>
<p>Before going forward, I want to share a pretty interesting story I had when obtaining a certificate for a domain I just took over. The setting was just perfect: I was able to point the domain to my server and went for a high impact. The first thing I tried was obtaining a valid SSL certificate. However, the automatic <em>certbot</em> process failed without any indication of why. My manual effort for Let's Encrypt failed as well. Then I opted for a paid certificate using a provider that accepted HTTP validation. It failed as well. When I tried a third provider, that's where things started to get clear. My request for a certificate was denied with the message that the policy forbids to issue a new certificate for a domain ███.com. It was the first time I came across something like that. You know a company is taking web security seriously if they have this kind of defense-in-depth measures in place.</p>
<p>All of the following escalation paths pretty much go hand in hand. I would assume that the takeover we got is the most liberal (in other words, you are controlling the whole instance). Other restricted environments such as Elasticbeanstalk might require a couple of tweaks to work.</p>
<h2 id="xss">XSS</h2>
<p>My first use-case is to showcase a stored XSS on the domain that was taken. The proof-of-concept is as straightforward as creating a new HTML file and pasting the Javascript code in it. Sometimes, stored XSS are valued more than subdomain takeover. For the XSS payload itself, I usually go with <code>alert(document.cookie)</code>.</p>
<p>With the XSS possibility, you can also showcase a possible phishing scenario where you clone the login page of the targeted organization and place it in the domain you now &quot;own&quot;. I was able to take over a domain that had a form of <em>auth.example.com</em> which is the perfect candidate for phishing attacks.</p>
<h2 id="accounttakeover">Account Takeover</h2>
<p>Usually, a session cookie for the login session is set to have <em>secure</em> and <em>httpOnly</em>. The former means that you can access cookies only if the page has a valid SSL certificate and the latter says that it cannot be accessed using Javascript, only in HTTP requests to the backend server.</p>
<p>It is fairly common to bound a session cookie to a wildcard domain such as <code>*.example.com</code>. For instance, let's say there is a login gateway on <em>auth.example.com</em>, but there are multiple apps such as <em>customer.example.com</em>, <em>app.example.com</em> that want to be able to access the login session. An SSO solution thus tends to work on the wildcard domain. With the domain you have just taken over, you can access this session cookie easily.</p>
<p>To achieve a full account takeover, you need to force the victim into visiting the domain that was vulnerable to subdomain takeover. Then a simple backend script can retrieve the session cookie (note that this example simply reflects the value to the user but it can be easily modified to store the values):</p>
<pre><code>#python3

import Flask

app = flask.Flask(__name__)

@app.route('/')
def gimme_my_cookies():
    return flask.jsonify(flask.request.cookies)

if __name__ == '__main__':
    app.run(port=80)
</code></pre>
<p>Once you have the correct session token, you can change the cookie in the browser and access the victim's account (assuming there is no other security prevention).</p>
<h2 id="csrf">CSRF</h2>
<p>Similar to the examples above, CSRF can be sometimes done when the target application is assuming that the wildcard domain is <em>safe</em>. This is also true for inter-app communication using <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage">postMessage API</a> where the Javascript code is responsible for detecting the sender and based on that allowing the action. The regexes for this verification are usually set for <code>*.example.com</code>.</p>
<h2 id="authenticationbypass">Authentication Bypass</h2>
<p>Rather than explaining it on my own, I would point you to the <a href="https://hackerone.com/reports/219205">great report</a> submitted by <a href="https://twitter.com/arneswinnen">Arne Swinnen</a> on HackerOne. Although the attack complexity is pretty high, in some cases you can achieve the same behavior.</p>
<p>Hopefully, this shines a new light on how you can think of subdomain takeover bugs in the future. If you know about any other escalation path, I will be more than happy to update the post with the credits.</p>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Takeover: Going for High Impact" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Subdomain Enumeration: Filter Wildcard Domains]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>When doing <a href="https://0xpatrik.com/subdomain-enumeration-2019/">subdomain enumeration</a>, you are likely to encounter a domain that is a wildcard. Such domains respond to DNS queries with a record/records, which are not explicitly defined in the DNS zone. In other words, if the DNS zone does not hold a record for a particular subdomain,</p>]]></description><link>https://0xpatrik.com/wildcard-domains/</link><guid isPermaLink="false">5e9d59cb99dbd2662ae9e6b4</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Mon, 20 Apr 2020 17:51:39 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2020/04/filter-wildcards.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2020/04/filter-wildcards.jpg" alt="Subdomain Enumeration: Filter Wildcard Domains"><p>When doing <a href="https://0xpatrik.com/subdomain-enumeration-2019/">subdomain enumeration</a>, you are likely to encounter a domain that is a wildcard. Such domains respond to DNS queries with a record/records, which are not explicitly defined in the DNS zone. In other words, if the DNS zone does not hold a record for a particular subdomain, a fallback is made to its wildcard entry.</p>
<p><img src="https://0xpatrik.com/content/images/2020/04/zone.png" alt="Subdomain Enumeration: Filter Wildcard Domains"></p>
<p>In the example above, the <code>admin.0xpatrik.com</code> and <code>sub.0xpatrik.com</code> respond with <code>1.2.3.4</code> and <code>4.3.2.1</code> respectively, while any other subdomain would respond with <code>1.1.1.1</code>, not NXDOMAIN! This is a valid, yet obscure behavior of DNS servers.</p>
<p>Such a function can cause a lot of trouble because you will start enumerating targets, that doesn't even exist.</p>
<p>This post presents techniques to detect and filter the wildcard domains during subdomain enumeration.</p>
<h2 id="detection">Detection</h2>
<p>One of the simplest indicators of the wildcard domain is a large number of its valid subdomains. The simplest way to confirm this case is by running a DNS query on subdomains that you are certain that does not exist as such:</p>
<p><img src="https://0xpatrik.com/content/images/2020/04/totallynotexistent-1.png" alt="Subdomain Enumeration: Filter Wildcard Domains"></p>
<p>As you can see, this query resulted in valid results! This is the first hint that you are probably dealing with the wildcard domain. To verify that this is indeed a wildcard domain, you can run one more test to confirm it:</p>
<p><img src="https://0xpatrik.com/content/images/2020/04/wildcard-1.png" alt="Subdomain Enumeration: Filter Wildcard Domains"></p>
<p>Schema starting with a <code>*</code> (<code>*.example.com</code>) is used to denote wildcard entry. As you can see this resulted in another valid record set in the ANSWER section.</p>
<p>Perfect, you are now able to recognize wildcard domains. The real world is, however, a little more difficult than that. There is no rule, that the wildcard domain needs to be under the root domain. Take for example <code>*.amazonaws.com</code> and <code>*.s3.amazonaws.com</code>. As you will see after running the queries for these domains, only the latter responds with a valid record. Therefore, you need to recognize to which <em>root</em> or <em>subdomain</em> is a wildcard domain applied.</p>
<h2 id="filtration">Filtration</h2>
<p>We should be able to correctly filter out the non-existing domains from the existing ones. With that in our hands, we can continue with the recon and enumeration as there is no wildcard domain in the first place. However, this can't be done in all cases:</p>
<ul>
<li>Some configurations allow wildcard entries but do not respond to <code>*.example.com</code> query.</li>
<li>Some configurations allow all subdomains to resolve to one domain and different content is served based on <code>Host</code> HTTP header (like <code>*.herokuapp.com</code>).</li>
</ul>
<p>With this in mind, we can create a heuristic for filtering the non-existing subdomains under the root that allow wildcard entries like so:</p>
<ol>
<li>Given the domain (<code>something.sub.example.com</code>), obtain its records (like 1.1.1.1)</li>
<li>Replace the highest subdomain level with <code>*</code> and try to resolve it (<code>*.sub.example.com</code>)</li>
<li>If you get no results, continue until you reach the root domain (<code>*.example.com</code>)</li>
<li>If you end up with no results, there is no wildcard domain and the given domain in step one is likely valid.</li>
<li>If you get any response from wildcard queries, compare it to the results you got from 1. If these results equal, the domain is likely not valid.</li>
<li>If these do not equal, the domain is likely valid.</li>
</ol>
<p>It is important to compare the results with the wildcard results in higher domains. For instance, if both <code>*.sub.example.com</code> and <code>*.example.com</code> respond with valid results, you compare the results for <code>*.sub.example.com</code>.</p>
<p>I deliberately say records, because there are instances when wildcard queries respond with multiple records (e.g. <code>*.herokuapp.com</code>). When implementing automated filtering, you should compare <em>sets</em> instead of <em>lists</em> while many of the records can be unordered.</p>
<p>The last issue I want to talk about is anycast DNS. I have seen cases where the wildcard domain responds with multiple values, however, these are presented one at the time. In this case, automating the filtering is really tough as you need to enumerate all the possible values you would then compare against the potential subdomains.</p>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Enumeration: Filter Wildcard Domains" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Subdomain Enumeration: Doing it a Bit Smarter]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>My <a href="https://0xpatrik.com/subdomain-enumeration-2019/">last post</a> about subdomain enumeration received great feedback. In the meantime, I thought of some other improvements I could make to increase the chances of finding new assets. This post presents a new tool that resulted in several critical reports during the past weeks.</p>
<h2 id="currentstate">Current state</h2>
<p>When I use</p>]]></description><link>https://0xpatrik.com/subdomain-enumeration-smarter/</link><guid isPermaLink="false">5dd051c7140a9354e2f0164d</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Sun, 29 Sep 2019 16:17:46 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2019/09/dnsgen.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2019/09/dnsgen.jpg" alt="Subdomain Enumeration: Doing it a Bit Smarter"><p>My <a href="https://0xpatrik.com/subdomain-enumeration-2019/">last post</a> about subdomain enumeration received great feedback. In the meantime, I thought of some other improvements I could make to increase the chances of finding new assets. This post presents a new tool that resulted in several critical reports during the past weeks.</p>
<h2 id="currentstate">Current state</h2>
<p>When I use <a href="https://github.com/infosec-au/altdns">altdns</a>, I use it solely to generate possibilities. Even though it contains own DNS resolver, it is much wiser to use a faster approach such as <a href="https://github.com/blechschmidt/massdns">massdns</a>.</p>
<p>Firstly, let's explain what altdns does and why it works. Imagine having a list of active domain names that you found for the target:</p>
<pre><code>app1.example.com
customer.example.com
...
</code></pre>
<p>Developers usually test the application before going into production. From the experience, they usually use domain prefixes/suffixes such as <code>staging</code> or <code>test</code> to distinguish between testing and production environment. Thus, the <em>sibling domains</em> for the above examples might look like:</p>
<pre><code>app1-staging.example.com
test-customer.example.com
...
</code></pre>
<p>Altdns does exactly this: it generates the possible combinations of original domain with the <em>words</em> from the wordlist (<a href="https://github.com/infosec-au/altdns/blob/master/words.txt">example</a>). To make altdns generate possibilities, you simply run:</p>
<p><code>$ python altdns.py -i input_domains.txt -o ./output/path -w altdns/words.txt</code></p>
<p>This command generates a huge list of possible domain names for the target. I say <em>possible</em>, because most of them do not exist. To verify the existence of some domain, you need to run a DNS resolution.</p>
<p>When I looked under the hood of altdns, I noticed that it is missing one <strong>crucial</strong> thing. Targets may use custom words for their domain names. That's why you see many people in the community recommend to <em>&quot;look for patterns&quot;</em> during the recon phase. Unfortunately, this is a pretty vague statement. Also, there is no automated way to do it.</p>
<p>By custom words, I mean words that are not included in your fundamental wordlist. These words are usually unique to the target environment, such as the name of the company, the name of the application and so on. The domain names might look like:</p>
<pre><code>pkjapp-testing.example.com
customers-indiadatacenter.example.com
...
</code></pre>
<p>You see, <code>pkjapp</code> and <code>indiadatacenter</code> are not <em>words</em> that you would consider to include in your wordlist.</p>
<blockquote>
<p><strong>YOU CANNOT INCLUDE ALL THESE WORDS IN YOUR WORDLIST</strong>. It is much wiser to smartly extend your wordlist per target.</p>
</blockquote>
<h2 id="alternations">Alternations</h2>
<p>I created a tool that pretty much replaces the <code>altdns</code> functionality and adds several extra layers. It uses generic <a href="https://github.com/ProjectAnte/dnsgen/blob/master/dnsgen/words.txt">wordlist</a> which is automatically extended when needed.</p>
<blockquote>
<p>You can find the source code <a href="https://github.com/ProjectAnte/dnsgen">here</a>!</p>
</blockquote>
<p>Let's look into the techniques that happen behind the scenes:</p>
<p><em>(For demo purposes, let's say that wordlist contains just one word: <code>stage</code>)</em></p>
<ul>
<li>
<p><strong>Insert word on every index</strong> — Creates new subdomain levels by inserting the words between existing levels. <code>foo.example.com</code> -&gt; <code>stage.foo.example.com</code>, <code>foo.stage.example.com</code></p>
</li>
<li>
<p><strong>Insert num on every index</strong> — Creates new subdomain levels by inserting the numbers between existing levels. <code>foo.bar.example.com</code> -&gt; <code>1.foo.bar.example.com</code>, <code>foo.1.bar.example.com</code>, <code>01.foo.bar.example.com</code>, <code>...</code></p>
</li>
<li>
<p><strong>Increase/Decrease num found</strong> — If the number is found in an existing subdomain, increase/decrease this number without any other alteration. <code>foo01.example.com</code> -&gt; <code>foo02.example.com</code>, <code>foo03.example.com</code>, <code>...</code></p>
</li>
<li>
<p><strong>Prepend word on every index</strong> — On every subdomain level, prepend existing content with <code>WORD</code> and <code>WORD-</code>. <code>foo.example.com</code> -&gt; <code>stagefoo.example.com</code>, <code>stage-foo.example.com</code></p>
</li>
<li>
<p><strong>Append word on every index</strong> — On every subdomain level, append existing content with <code>WORD</code> and <code>WORD-</code>. <code>foo.example.com</code> -&gt; <code>foostage.example.com</code>, <code>foo-stage.example.com</code></p>
</li>
<li>
<p><strong>Replace the word with word</strong> — If word longer than 3 is found in an existing subdomain, replace it with other words from the wordlist. <em>(If we have more words than one in our wordlist)</em>. <code>stage.foo.example.com</code> -&gt; <code>otherword.foo.example.com</code>, <code>anotherword.foo.example.com</code>, <code>...</code></p>
</li>
<li>
<p><strong>Extract custom words</strong> — Extend the wordlist based on target's domain naming conventions. Such words are either whole subdomain levels, or <code>-</code> is used for a split on some subdomain level. For instance <code>mapp1-current.datastream.example.com</code> has <code>mapp1</code>, <code>current</code>, <code>datastream</code> words. To prevent the overflow, user-defined <em>word length</em> is used for word extraction. The default value is set to <strong>6</strong>. This means that only words strictly longer than <strong>5</strong> characters are included (from the previous example, <code>mapp1</code> does not satisfy this condition).</p>
</li>
</ul>
<p><img src="https://0xpatrik.com/content/images/2019/09/dnsgen-1.png" alt="Subdomain Enumeration: Doing it a Bit Smarter"></p>
<p>Refer to GitHub <a href="https://github.com/ProjectAnte/dnsgen">project's page</a> to learn more about installation and usage.</p>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Enumeration: Doing it a Bit Smarter" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Subdomain Enumeration: 2019 Workflow]]></title><description><![CDATA[After some heavy testing, I had improved my subdomain enumeration game significantly. In this post, I want to share my thoughts about how to do subdomain enumeration.]]></description><link>https://0xpatrik.com/subdomain-enumeration-2019/</link><guid isPermaLink="false">5dd051c7140a9354e2f0163f</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Thu, 06 Jun 2019 13:24:18 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2019/06/subdomain-enumeration.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2019/06/subdomain-enumeration.jpg" alt="Subdomain Enumeration: 2019 Workflow"><p>You are probably shaking your head that this is another post about subdomain enumeration. I have <a href="https://blog.sweepatic.com/art-of-subdomain-enumeration/">written</a> about it in the past, and so did much other security folks. But things have changed, and I noticed that the results I was getting were not optimal. Don't get me wrong; I inevitably got better results than most people. But there was a room for improvement. After some heavy testing, I had improved my subdomain enumeration game significantly. In this post, I want to share (some of) my thoughts about how to do subdomain enumeration.</p>
<p>Firstly, I am all about efficiency. I want to have the best results as soon as possible. I have glued together the best tools <em>&quot;on the market&quot;</em> to come up with an efficient solution that works. If you remember from the past, I want to have continuous reconnaissance process rather than one-time-shots. These are the tools/sources for it:</p>
<ul>
<li><a href="https://github.com/OWASP/Amass">Amass</a></li>
<li>Rapid7 <a href="https://opendata.rapid7.com/sonar.fdns_v2/">Forward DNS dataset</a></li>
<li><a href="https://github.com/assetnote/commonspeak2-wordlists">commonspeak2</a> wordlist</li>
<li><a href="https://github.com/blechschmidt/massdns">massdns</a></li>
<li><a href="https://github.com/infosec-au/altdns">altdns</a> (optional)</li>
</ul>
<p>This is the combination that brings the best results for the majority of the targets I have encountered. Now, let's bring the full process:</p>
<ol>
<li>Use <code>amass</code> to gather passive data</li>
<li>Retrieve subdomains from Rapid7 FDNS</li>
<li>Generate possibilities from <code>commonspeak2</code></li>
<li>Run <code>massdns</code> on input from step #1-#3</li>
<li>Run <code>altdns</code> on the result set</li>
<li>Run <code>massdns</code> on input from step #5</li>
</ol>
<p>Step #5 and #6 are optional and take most of the time. If you don't run it, you will still get great results.</p>
<p><img src="https://0xpatrik.com/content/images/2019/06/enumeration.png" alt="Subdomain Enumeration: 2019 Workflow"></p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="amass">Amass</h2>
<p>I've said it hundreds of times; amass is my goto tool for primary subdomain enumeration. Forget <a href="https://github.com/aboul3la/Sublist3r">Sublist3r</a> and <a href="https://github.com/michenriksen/aquatone">aquatone</a>. <a href="https://github.com/subfinder/subfinder">Subfinder</a> is a good alternative to amass, but I have two problems with it:</p>
<ul>
<li>It does not have that many sources as amass</li>
<li>It does things too <em>&quot;nicely&quot;</em>. In other words, you require API keys for many services.</li>
</ul>
<p>Why did I mention to use amass to get passive data? The built-in DNS resolver is just too slow. Amass should provide data from various sources; we have better tools for DNS resolution. (I have spoken about it with the <a href="https://twitter.com/jeff_foley">amass author</a>. The amass resolution capabilities might be improved in the future).</p>
<p>To retrieve a passive data using amass, simply run:</p>
<pre><code>amass enum --passive -d &lt;DOMAIN&gt;
</code></pre>
<!--kg-card-end: markdown--><h2 id="subdomains-from-rapid7-fdns">Subdomains from Rapid7 FDNS</h2><p>Nothing surprising here. FDNS dataset is just a great way to enhance the results that amass brings. You can now use <a href="https://blog.rapid7.com/2018/10/16/how-to-conduct-dns-reconnaissance-for-02-using-rapid7-open-data-and-aws/">AWS Athena</a> to query the FDNS.</p><figure class="kg-card kg-image-card"><img src="https://0xpatrik.com/content/images/2018/10/Domain_Infrastructure.jpg" class="kg-image" alt="Subdomain Enumeration: 2019 Workflow"></figure><p>(Source: <em>blog.rapid7.com</em>)</p><!--kg-card-begin: markdown--><p>Indeed, you don't need to use AWS to retrieve the subdomains, it is just much more convenient. You can definitely parse it on your own using the <a href="https://0xpatrik.com/project-sonar-guide/">guide</a> I have written in the past.</p>
<!--kg-card-end: markdown--><h2 id="possibilities-from-commonspeak2">Possibilities from commonspeak2</h2><p>I have to confess. I never liked traditional brute-force method for subdomain enumeration. However, for some reason, <a href="https://github.com/assetnote/commonspeak2-wordlists">commonspeak2</a> wordlist just works. To generate the possibilities, you can use this simple Python snippet:</p><pre><code>scope = '&lt;DOMAIN&gt;'
wordlist = open('./commonspeak2.txt').read().split('\n')

for word in wordlist:
    if not word.strip(): 
        continue
    print('{}.{}\n'.format(word.strip(), scope))
    </code></pre><h2 id="run-massdns">Run massdns</h2><p>At this stage, you have a huge list of <strong>potential</strong> subdomains for your target. The potential means that they might exist and they might not. To verify that, you need to run an active DNS resolution. For that, <em>massdns</em> is the perfect tool. It is up to you how you approach the automation, I like to do it using Python:</p><!--kg-card-begin: markdown--><pre><code>#python3

import json
import subprocess

RESOLVERS_PATH = '/path/to/resolvers.txt'

def _exec_and_readlines(cmd, domains):

    domains_str = bytes('\n'.join(domains), 'ascii')
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, stdin=subprocess.PIPE)
    stdout, stderr = proc.communicate(input=domains_str)

    return [j.decode('utf-8').strip() for j in stdout.splitlines() if j != b'\n']

def get_massdns(domains):
    massdns_cmd = [
        'massdns',
        '-s', '15000',
        '-t', 'A',
        '-o', 'J',
        '-r', RESOLVERS_PATH,
        '--flush'
    ]

    processed = []

    for line in _exec_and_readlines(massdns_cmd, domains):
        if not line:
            continue

        processed.append(json.loads(line.strip()))

    return processed

print(get_massdns(['example.com', 'sub.example.com']))
</code></pre>
<p>Using <code>-o J</code> flag, massdns outputs the results in so-called <a href="http://ndjson.org">ndjson format</a>. We then need to enumerate through lines and treat each line as valid JSON which we can easily parse.</p>
<h2 id="altdns">Altdns</h2>
<p>This is an optional tool in my workflow which might bring more fruit to the table (read, more subdomains found). It works by creating permutations for existing domain names. For instance, given the domain name <code>sub.example.com</code>, altdns might provide possible permutations in the form of:</p>
<ul>
<li><code>sub-dev.example.com</code></li>
<li><code>sub01.example.com</code></li>
<li>...</li>
</ul>
<p>You get the point. The idea is to generate such possibilities and then resolve them at once to get the possible hits. It is basically a smart way of doing brute force. There is a very nice <a href="https://www.foo.be/papers/sdbf.pdf">research paper</a> written about this topic. The paper, however, introduces much more advanced research in this area. These topics are not yet implemented in altdns, I am currently working on the alternative tool, stay tuned!</p>
<p>To start the altdns for our purposes, we can run:</p>
<pre><code>python altdns.py -i input_domains.txt -o ./output/path -w altdns/words.txt
</code></pre>
<p>Why do we run <code>massdns</code> twice? Altdns is a great tool for generating variations of domains names. It, however, returns a huge list of possibilities. Since the DNS resolutions take time, it is better to firstly resolve a smaller list of <em>active</em> domains after step #3. Altdns can then take only subdomains that are proven to be active, which results in a smaller list for resolution in step #6.</p>
<p>You might be wondering why I don't usually provide full scripts that are described in my articles. I think that for those of you who are willing to learn, it is better to try and glue these things together by yourself. Trust me, it is the best thing you can do if you are really serious about this stuff. You can always ask me questions on <a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw">Twitter</a>.</p>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Enumeration: 2019 Workflow" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Subdomain Takeover: Second Order Bugs]]></title><description><![CDATA[Subdomain takeover verification can be extended with second order bugs verification. This verification extends potential attack surface using subdomain takeover.]]></description><link>https://0xpatrik.com/second-order-bugs/</link><guid isPermaLink="false">5dd051c7140a9354e2f01645</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Thu, 20 Dec 2018 11:00:00 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/12/takeover.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/12/takeover.jpg" alt="Subdomain Takeover: Second Order Bugs"><p>Recently, I was trying to extend my <em>autonomous bug bounty finding engine</em>. My first thought was to incorporate second order bugs into the subdomain takeover scanning process. In this post, I describe how I approached this challenge and how this process can be automated efficiently. There is a <a href="https://edoverflow.com/2017/broken-link-hijacking/">great article</a> written by <a href="https://twitter.com/EdOverflow">EdOverflow</a>, but I feel there is a bit more to say about this topic.</p>
<p>Second order bugs happen when a website uses a <em>&quot;takeoverable domain&quot;</em> in the wrong place. Imagine a website that uses a Javascript file from the external domain. What happens when the domain is vulnerable to subdomain takeover? When the Javascript file is not available (e.g., <em>the domain expired</em>), the browser fails quietly. If this file is not extremely important to website functionality (e.g., <em>live chat plugin</em>), there is a possibility that website behavior remains unnoticed by administrators. We can register this domain and host our Javascript file, creating a very smooth XSS. It is a classic subdomain takeover example as I wrote about <a href="https://0xpatrik.com/subdomain-takeover-basics/">before</a>. The diagram below illustrates this idea.</p>
<p><img src="https://0xpatrik.com/content/images/2018/12/second-order-1.png" alt="Subdomain Takeover: Second Order Bugs"></p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Why exactly is this called second-order bug? Well, first-order subdomain takeover bugs are just subdomains of the target program that is vulnerable to subdomain takeover. Second-order makes it clear that we are extending the &quot;<em>reach</em>&quot; of our scans to domains which can make a significant impact.</p>
<p>There is at least one open-source tool for this scans available: <a href="https://github.com/mhmdiaa/second-order">second-order</a>. The problem is that it does not examine all the fields described in this post. It is, however, an excellent starting point. I just don't feel confident to extend its capabilities since it is written in Go.</p>
<p>Second order bugs are not limited to Javascript files. We can extend this idea to things like CORS. I recommend looking into this <a href="https://hackerone.com/reports/426165">HackerOne report</a> to see what I am talking about. The basic idea is this: We need to extract links and domains from places, where subdomain takeover would cause real trouble. What exactly are these places?</p>
<ul>
<li>script tags — impact: <em>XSS</em></li>
<li>a tags — impact: <em>social engineering</em></li>
<li>link tags — impact: <em>clickjacking</em></li>
<li>CORS response headers — impact: <em>data exfiltration</em></li>
</ul>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="implementation">Implementation</h2>
<p>Now, let's look at how to implement this using Python. The high-level process looks like this:</p>
<p><img src="https://0xpatrik.com/content/images/2018/12/second-order-2.png" alt="Subdomain Takeover: Second Order Bugs"></p>
<p>The first part consists of <em>crawling</em> in some shape or form. I will skip the technical details of this; it is up to you to decide what strategy to use. You may:</p>
<ul>
<li>Request only <code>/</code> for every subdomain found</li>
<li>Do a limited crawl (e.g., BFS tree with height 1)</li>
<li>Do a full crawl</li>
</ul>
<p>The HTML files resulting from any of these <em>crawls</em> (well, the first option is not a crawl by any means) are fed into the extraction machine.</p>
<p>The extraction process takes several steps to complete. I used single functions to take care of each step. Let's look at it more deeply:</p>
<pre><code>from bs4 import BeautifulSoup

def extract_javascript(domain, source_code):
    '''
    Extract and normalize external javascript files from HTML
    '''

    tree = BeautifulSoup(source_code, 'html.parser')
    scripts = [normalize_url(domain, s.get('src')) for s in tree.find_all('script') if s.get('src')]
    return list(set(scripts))
</code></pre>
<p>This piece of code extracts all links from script tags present in the HTML file. I used BeautifulSoup to do the HTML parsing for me. You might notice that there is a mysterious <code>normalize_url</code> function. I will explain it shortly.</p>
<pre><code>def extract_links(domain, source_code):
    '''
    Extract and normalize links in HTML file 
    '''

    tree = BeautifulSoup(source_code, 'html.parser')
    hrefs = [normalize_url(domain, s.get('href')) for s in tree.find_all('a') if s.get('href')]
    return list(set(hrefs))
</code></pre>
<pre><code>def extract_styles(domain, source_code):
    '''
    Extract and normalize CSS in HTML file 
    '''

    tree = BeautifulSoup(source_code, 'html.parser')
    hrefs = [normalize_url(domain, s.get('href')) for s in tree.find_all('link') if s.get('href')]
    return list(set(hrefs))
</code></pre>
<p>There should not be anything surprising; we are doing extraction analogously to script tags.</p>
<pre><code>import requests

def extract_cors(url):
    r = requests.get(url, timeout=5)
    if not r.headers.get('Access-Control-Allow-Origin'):
        return
    cors = r.headers['Access-Control-Allow-Origin'].split(',')
    if '*' in cors:
        # Use your imagination here
        return []
    return cors
</code></pre>
<p>This is something different, but shouldn't be difficult to understand. There are, however different ways to express multiple origin domains. I assumed that <em>','</em> is the delimiter. You can do research and make it more robust; there might be different ways to provide multiple origin domains (let me know if you find it).</p>
<pre><code>def normalize_url(domain, src):
	'''
	(Try to) Normalize URL to its absolute form
	'''

	src = src.strip()
	src = src.rstrip('/')

	# Protocol relative URL
	if src.startswith('//'):
		return 'http:{}'.format(src)
	
	# Relative URL with /
	if src.startswith('/'):
		return 'http://{}{}'.format(domain, src)

	# Relative URL with ?
	if src.startswith('?'):
		return 'http://{}/{}'.format(domain, src)

	# Relative URL with ./
	if src.startswith('./'):
		return 'http://{}{}'.format(domain, src[1:])

	# Absolute URL
	if src.startswith('https://') or src.startswith('http://'):
		return src

	# Else let's hope it is relative URL
	return 'http://{}/{}'.format(domain, src)
</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>This function tries to normalize the given URL into its absolute forms. As you may know, arguments to <em>src</em> or <em>href</em> HTML parameter can include relative addresses as well. The <em>normalize_url</em> function returns an URL in its absolute form, so we can easily extract the domain and other parts from it.</p>
<p>We only need to extract the domain name from our absolute URL. This is a pretty straightforward task in Python:</p>
<pre><code>from urllib.parse import urlparse
def extract_domain(url):
    '''Extracts domain name from given URL'''

    return urlparse(url).netloc
</code></pre>
<p>The extracted domains are now ready to be forwarded into a subdomain takeover verification engine. I talked about creating one <a href="https://0xpatrik.com/subdomain-takeover-candidates/">here</a>. This process should be enough to identify higher-order subdomain takeover bugs. You can view the full snippet <a href="https://gist.github.com/PatrikHudak/2006c50a694cc76ead705c91805df78b">on GitHub</a>.</p>
<p>These bugs are very rare. I came across only one in the past. However, since the process can be easily automated, there is no reason not to include it in your automation workflow. You might get lucky and get one in the future. <strong>Happy hunting.</strong></p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>Check out my other posts about subdomain takeovers:</p>
<ul>
<li><a href="https://0xpatrik.com/subdomain-takeover/">Subdomain Takeover: Thoughts on Risks</a></li>
<li><a href="https://0xpatrik.com/subdomain-takeover-basics/">Subdomain Takeover: Basics</a></li>
<li><a href="https://0xpatrik.com/takeover-proofs/">Subdomain Takeover: Proof Creation for Bug Bounties</a></li>
<li><a href="https://0xpatrik.com/subdomain-takeover-candidates/">Subdomain Takeover: Finding Candidates</a></li>
</ul>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Takeover: Second Order Bugs" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Subdomain Takeover: Identifying Providers]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Recently, I have come across an <a href="https://github.com/EdOverflow/can-i-take-over-xyz/issues/26">interesting list</a> of domain suffixes used by cloud providers which are vulnerable to <a href="https://0xpatrik.com/subdomain-takeover-basics/">subdomain takeover</a>. Although the list is pretty accurate, it is still a raw list that needs to be further processed. In this post, I will explain how to process this list</p>]]></description><link>https://0xpatrik.com/subdomain-takeover-providers/</link><guid isPermaLink="false">5dd051c7140a9354e2f0163e</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Wed, 19 Sep 2018 10:00:00 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/09/subdomain_takeover.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/09/subdomain_takeover.jpg" alt="Subdomain Takeover: Identifying Providers"><p>Recently, I have come across an <a href="https://github.com/EdOverflow/can-i-take-over-xyz/issues/26">interesting list</a> of domain suffixes used by cloud providers which are vulnerable to <a href="https://0xpatrik.com/subdomain-takeover-basics/">subdomain takeover</a>. Although the list is pretty accurate, it is still a raw list that needs to be further processed. In this post, I will explain how to process this list correctly and how to identify new vulnerable cloud services using simple methods.</p>
<p><img src="https://0xpatrik.com/content/images/2018/09/header-1.png" alt="Subdomain Takeover: Identifying Providers"></p>
<h2 id="architecture">Architecture</h2>
<p>Firstly, let's recap and begin by explaining how the usual cloud provider becomes vulnerable to subdomain takeover. When people create cloud resources, they want them to be accessible through their domain. After registering, for instance, a new Heroku app, the engine will give you subdomain in form <code>APP_NAME.herokudns.com</code>. Heroku recognizes that customers want such applications to be exposed through their domain (e.g. <code>herokuapp.example.com</code>) so they provide a way to set <em>custom domain</em> to their cloud resource.</p>
<p>Due to the technical simplicity, such architecture is often achieved through the use of virtual hosting. You can see the basic idea on the following diagram:</p>
<p><img src="https://0xpatrik.com/content/images/2018/09/heroku_vhost.png" alt="Subdomain Takeover: Identifying Providers"></p>
<p>The reason why virtual hosting is preferred is that providers like Heroku don't want to dedicate the whole instance to one application. This also means having dedicated IP address (A record) for each application on <code>*.herokudns.com</code>. It is easier for them to hide the content behind a couple of load balancers and let them decide what content to return based on <em>HTTP Host</em> header. You can confirm this by resolving two different <code>*.herokudns.com</code> domains and comparing the returned A records. They will be the same.</p>
<p>After the HTTP request arrives to load balancer, it determines what content to return based on HTTP Host header assignment:</p>
<p><img src="https://0xpatrik.com/content/images/2018/09/heroku_vhost_request.png" alt="Subdomain Takeover: Identifying Providers"></p>
<p>Custom domains provide a little problem in this architecture. We need to provide the name of custom domain beforehand, so the load balancer knows to which domain it corresponds to when the request arrives. This is the whole problem of subdomain takeover: <em>Having CNAME set to cloud provider domain, but not setting this custom domain in your cloud provider portal</em>.</p>
<p>Some cloud services that use virtual hosting setup:</p>
<ul>
<li>Amazon S3</li>
<li>Heroku</li>
<li>Shopify</li>
<li>Readme.io</li>
<li>...</li>
</ul>
<p>On the other hand, there are still some cloud providers that don't rely on virtual hosting but simply creates a dedicated instance (and thus IP address) for each cloud resource. We don't rely on Host header, and the target instance thus accepts any HTTP Host header provided. In other terms, this means that we don't need to specify our custom domain beforehand. Any domain with correct CNAME record will work. The prominent cloud provider in this category is <em>Microsoft Azure</em>.</p>
<h2 id="verification">Verification</h2>
<p>Based on this explanation, we can divide the cloud providers into two categories:</p>
<ul>
<li>
<p><strong>Virtual hosting oriented (VHO)</strong> — services that require to specify custom domain beforehand.</p>
</li>
<li>
<p><strong>Non-virtual hosting oriented (NVHO)</strong> — services that don't require to specify custom domain beforehand.</p>
</li>
</ul>
<p>As we know from the <a href="https://0xpatrik.com/subdomain-takeover-candidates/">previous post</a>, subdomain takeover monitoring is a continuous process. We should aim for creating the automation that provides a high success rate in finding potential takeovers. My approach is to create so-called <strong>signatures</strong> that technically explain each vulnerable cloud service, like so:</p>
<pre><code>{
    &quot;name&quot;: &quot;Ghost&quot;,
    &quot;formats&quot;: [&quot;*.ghost.io&quot;],
    &quot;responses&quot;: [
        &quot;403 Forbidden&quot;,
        &quot;The thing you were looking for is no longer here, or never was&quot;
    ],
    &quot;response_codes&quot;: [404, 403, 302, 200]
}
</code></pre>
<p>We have four main parts here:</p>
<ul>
<li><strong>Name</strong> — This is the identification of the cloud service</li>
<li><strong>Formats</strong> — List that describes various formats of domains that the cloud provider uses. These domains are then used in CNAME records.</li>
<li><strong>Responses</strong> — What <em>strings</em> are we looking for in HTTP responses of <strong>vulnerable</strong> domain.</li>
<li><em>(Optional)</em> <strong>Response Codes</strong> — What HTTP response codes are we looking for in <strong>vulnerable</strong> domain.</li>
</ul>
<p>These signatures are then used by a scanner that takes a list of domain names for verification and checks their HTTP responses against this signature list (this process was explained in the <a href="https://0xpatrik.com/subdomain-takeover-candidates/">previous post</a>). Indeed, <em>Ghost</em> is not the only vulnerable cloud provider out there. The next section describes how to identify whether the provider is vulnerable and how to write such signatures correctly.</p>
<h3 id="virtualhostingoriented">Virtual hosting oriented</h3>
<p>This is the majority of cloud providers out there. A common theme across these providers is the fact that they tend to respond with a predefined error page for HTTP Host header they don't recognize. Imagine this: You request a Heroku application via some <code>*.herokudns.com</code>, but you set the HTTP Host header to a value that is not set in Heroku portal. As I explained before, Heroku has no way of knowing to which application does this domain name relate to, unless explicitly specified in Heroku app settings. So how does Heroku respond to such request?</p>
<p><img src="https://0xpatrik.com/content/images/2018/09/appendix_heroku_error.png" alt="Subdomain Takeover: Identifying Providers"></p>
<p>We can use this to our advantage:</p>
<ol>
<li>Identify domains that have CNAME to <code>*.herokudns.com</code>.</li>
<li>Make HTTP request to it (with correct Host header)</li>
<li>Check if the known <em>error page</em> strings (e.g., <em>&quot;Build something amazing&quot;</em>) are present in HTTP Response body</li>
<li>If yes, there is a potential for subdomain takeover</li>
</ol>
<p>Now that we know the motivation behind these error messages let's look on how to create a signature. I always like to have fresh <a href="https://0xpatrik.com/project-sonar-guide/">FDNS dataset</a> handy during this task. If I want to check whether some provider is vulnerable, this is my usual workflow:</p>
<ol>
<li>Identify what domains they use. This can be simply checked using Google or creating the cloud resource on your own. Usually query like <code>&lt;cloud provider name&gt; custom domain</code> will do the job. For Heroku, it is <code>*.herokudns.com</code> and sometimes <code>*.herokuapp.com</code>. Documentation can be found <a href="https://devcenter.heroku.com/articles/custom-domains">here</a>. The <strong>Format</strong> part of the signature is now done.</li>
<li>Grep some CNAMEs of such domain from FDNS: <code>zcat fdns.gz | grep cname | grep herokudns.com</code>. You need at least three domains.</li>
<li>Do DNS (A) resolution for these three domains. If the A records match, you have confirmed virtual hosting setup.</li>
<li>Now it is time to identify what the error page looks like. This can be simply done by creating an HTTP request and forging Host header to something non-existing, like so: <code>http GET http://&lt;something&gt;.herokudns.com Host:totallynonexistingdomainhere.com</code>.</li>
<li>From the response, identify some unique strings that are used as error messages. <strong>Responses</strong> part of the signature is now done.</li>
<li>Now it's time to finish the signature with <strong>Name</strong> which is trivial.</li>
</ol>
<p>With that, you are pretty much done. What I also like to do is to register the free account in the cloud provider I am testing and go through the whole workflow of setting the custom domain name. In some cases, the cloud provider is doing domain verification (e.g., Squarespace) so the takeover is not possible whatsoever. In other cases, they require you to have exact CNAME set in your DNS records which are not always possible.</p>
<blockquote>
<p>This virtual hosting setup and technique are actually what <a href="https://blog.cobaltstrike.com/2017/02/06/high-reputation-redirectors-and-domain-fronting/">Domain Fronting</a> is all about.</p>
</blockquote>
<h3 id="nonvirtualhostingoriented">Non-virtual hosting oriented</h3>
<p>This category is pretty simple to check. When following the workflow described above, point #3 is what decides between VHO and NVHO. If you see that the A records of this domain don't match, there is a high chance that the provider is not using virtual hosting. Fortunately, checking these instances is very simple, all you need to do is check, whether the provider generated domain responds with <code>NXDOMAIN</code> or not. There is no need to write full signatures for NVHO providers; they should be check separately.</p>
<p><em>Microsoft Azure</em> is the best example of NVHO provider. They use several domains for their services:</p>
<pre><code>&quot;*.cloudapp.net&quot;
&quot;*.cloudapp.azure.com&quot;
&quot;*.azurewebsites.net&quot;
&quot;*.blob.core.windows.net&quot;
&quot;*.cloudapp.azure.com&quot;
&quot;*.azure-api.net&quot;
&quot;*.azurehdinsight.net&quot;
...
</code></pre>
<p>Now, when you see CNAME pointing to one of these domains, you need to check whether the CNAME domain is <code>NXDOMAIN</code> or not. That's it.</p>
<p>For VHO and NVHO, these are not the strict rules, and there are indeed exceptions. I provided the guidelines which work for the majority of cloud providers that I tested in the previous months.</p>
<blockquote>
<p>If you do your research in subdomain takeovers, consider contributing to an open-source project called <a href="https://github.com/EdOverflow/can-i-take-over-xyz">can-i-take-over-xyz</a>. I will be adding my research there.</p>
</blockquote>
<p>Check out my other posts about subdomain takeovers:</p>
<ul>
<li><a href="https://0xpatrik.com/subdomain-takeover/">Subdomain Takeover: Thoughts on Risks</a></li>
<li><a href="https://0xpatrik.com/subdomain-takeover-basics/">Subdomain Takeover: Basics</a></li>
<li><a href="https://0xpatrik.com/takeover-proofs/">Subdomain Takeover: Proof Creation for Bug Bounties</a></li>
<li><a href="https://0xpatrik.com/subdomain-takeover-candidates/">Subdomain Takeover: Finding Candidates</a></li>
<li><a href="https://0xpatrik.com/subdomain-takeover-ns/">Subdomain Takeover: Going beyond CNAME</a></li>
</ul>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Takeover: Identifying Providers" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Subdomain Takeover: Going beyond CNAME]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>After writing the last post, I started thinking that I pretty much covered all aspects of subdomain takeover. Recently, I realized that there are no in-depth posts about other than CNAME subdomain takeover. I briefly mentioned NS subdomain takeover in my other posts. The problem is that there are not</p>]]></description><link>https://0xpatrik.com/subdomain-takeover-ns/</link><guid isPermaLink="false">5dd051c7140a9354e2f0163d</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Tue, 28 Aug 2018 11:29:19 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/08/subdomain_takeover.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/08/subdomain_takeover.jpg" alt="Subdomain Takeover: Going beyond CNAME"><p>After writing the last post, I started thinking that I pretty much covered all aspects of subdomain takeover. Recently, I realized that there are no in-depth posts about other than CNAME subdomain takeover. I briefly mentioned NS subdomain takeover in my other posts. The problem is that there are not many known cases of successful subdomain takeover using NS records. I carefully used this wording, because NS subdomain takeover is indeed possible! This post covers all technical aspects so that you can extend takeover scans with other signatures. Note however that NS takeover is a little bit difficult to understand than normal CNAME takeover.</p>
<p>Let's start with explaining how NS takeover differs from traditional CNAME subdomain takeover. I assume you are well-informed about CNAME subdomain takeover (if not, continue <a href="https://0xpatrik.com/subdomain-takeover-basics/">here</a>). In NS subdomain takeover, we want to be able to control the whole DNS zone on (authoritative) DNS server. As you might know, DNS has a hierarchical structure, and each level can be served by different nameservers:</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://0xpatrik.com/content/images/2018/08/resolution.png" class="kg-image" alt="Subdomain Takeover: Going beyond CNAME"></figure><!--kg-card-begin: markdown--><p>To make things more clear, let's explain the whole scenario with a simple example. I own a domain called <code>wolframe.eu</code> which I used for testing purposes. These are the (authoritative) nameservers for this domain:</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://0xpatrik.com/content/images/2018/08/nameservers-1.png" class="kg-image" alt="Subdomain Takeover: Going beyond CNAME"></figure><!--kg-card-begin: markdown--><p>As you can see, the DNS zone is managed by AWS (more specifically AWS Route53). The result we got in <code>dig</code> is <em>non-authoritative answer</em>. Non-authoritative means that it was not returned by authoritative DNS servers (one of four AWS in this example), but rather by some middleman. This middleman is <code>8.8.8.8</code> recursive Google DNS server as indicated by <code>@8.8.8.8</code> in <code>dig</code> command. You can get <em>authoritative answer</em> by changing <code>@8.8.8.8</code> to one of four AWS server such as <code>@ns-1276.awsdns-31.org</code>. This distinction will be crucial in later sections.</p>
<p>This is my DNS zone inside the Route53 portal:</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://0xpatrik.com/content/images/2018/08/zone.png" class="kg-image" alt="Subdomain Takeover: Going beyond CNAME"></figure><!--kg-card-begin: markdown--><p>There is only one A record for <code>wolframe.eu</code> itself set to <code>1.1.1.1</code>.</p>
<p>Once DNS request is an issue for any of <code>*.wolframe.eu</code>, one of these four AWS nameservers is randomly selected, and DNS result is returned:</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://0xpatrik.com/content/images/2018/08/a_record-1.png" class="kg-image" alt="Subdomain Takeover: Going beyond CNAME"></figure><!--kg-card-begin: markdown--><p>Now imagine this. I delete my DNS zone in Route53, but I keep NS records pointing to AWS. Now I get:</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://0xpatrik.com/content/images/2018/08/servfail-1.png" class="kg-image" alt="Subdomain Takeover: Going beyond CNAME"></figure><!--kg-card-begin: markdown--><p>Oops, not good. Now, if an attacker simply creates the new DNS zone in Route53, he can return any DNS response. This is a basic premise of NS subdomain takeover. There are multiple caveats with the scenario I just explained. We cover these things in the next sections.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="customnameserverdomains">Custom nameserver domains</h2>
<p>DNS specification does no require nameservers to be on the same domain. Imagine that <code>example.com</code> is served by two nameservers:</p>
<pre><code>ns.gooddomain.com
ns.baddomain.com
</code></pre>
<p><em>If the base domain of canonical domain name of <strong>at least one NS record</strong> is available for registration, the hosted domain name is vulnerable to NS subdomain takeover.</em></p>
<p>In other words, if <code>baddomain.com</code> does not exist, an attacker can register that and have full control over <code>example.com</code> (and even its subdomains). The real question is, does this ever happen? I highly recommend reading <a href="https://thehackerblog.com/the-international-incident-gaining-control-of-a-int-domain-name-with-dns-trickery/index.html">post</a> by Matthew Bryant where he explained how he got a subdomain takeover using precisely this approach. I also highly recommend his project called <a href="https://github.com/mandatoryprogrammer/TrustTrees">TrustTrees</a>. It is used to generate delegation graphs for any domain. He was able to discover more similar problems using this tool.</p>
<p>From the automation perspective, the process is rather straightforward:</p>
<ol>
<li>Resolve all nameservers for the scanned domain</li>
<li>Check if any of the nameservers are available for registration</li>
<li>Alert based on the result from the previous step</li>
</ol>
<p>Checking the only status in DNS reply is not sufficient indicator. The problem is that multiple servers are authoritative for a given domain. If one nameserver is not working, you get <code>NOERROR</code> because the other server is working just fine. DNS resolution does this quietly in the background. That's why tools like <em>TrustTrees</em> come handy in these type of analysis.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="manageddns">Managed DNS</h2>
<p>For DNS zones which are hosted on third party providers like AWS, the story is a little bit different. The nameserver domains won't usually be available for registration. As I shown in the example above, there might be a case where NS records point to a hosted provider, but the DNS zone is not claimed in the portal. In 2016, Matthew Bryant <a href="https://thehackerblog.com/the-orphaned-internet-taking-over-120k-domains-via-a-dns-vulnerability-in-aws-google-cloud-rackspace-and-digital-ocean/index-2.html">managed to take over 120k domains</a> which had NS records set to one of the DNS providers, but not claimed inside it. I highly recommend reading that post.</p>
<p>From the automation perspective, the process is a little bit different. It also varies from provider to provider, because all of them can have different signatures for non-existing zones. Let's take for instance DigitalOcean. My site (<code>0xpatrik</code>) is not hosted on DigitalOcean. Let's try to query its nameservers for it.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://0xpatrik.com/content/images/2018/08/0xpatrik.png" class="kg-image" alt="Subdomain Takeover: Going beyond CNAME"></figure><!--kg-card-begin: markdown--><p>As we can see, DigitalOcean nameserver returns <code>REFUSED</code> DNS status. If the nameservers for <code>0xpatrik.com</code> would be set to <code>ns1.digitalocean.com</code>, subdomain takeover would be possible.</p>
<p>As described in Matthew's post, AWS generates a new set of nameservers for each DNS zone, so for successful PoC, you will need to brute force these nameservers (but it is possible).</p>
<p>I don't write signatures for each DNS provider. The cases for NS subdomain takeover are so rare (in scopes I am interested in) that I don't care about the few false positives each month. Let's now look at the automation process for hosted DNS:</p>
<ol>
<li>For domain, extract its nameservers</li>
<li>Iteratively resolve domain against each of these servers separately</li>
<li>Look for responses like <code>SERVFAIL</code> or <code>REFUSED</code> and alert based on it</li>
</ol>
<p>You can easily achieve this using <code>dnspython</code> and custom resolvers like so:</p>
<pre><code>import dns
import dns.rdatatype

for NAMESERVER_IP in NAMESERVER_IPS:
    custom_resolver = dns.resolver.Resolver()
    custom_resolver.nameservers = [NAMESERVER_IP]
    q = custom_resolver.query(DOMAIN, dns.rdatatype.A)
</code></pre>
<p>Overall, your automation should be extended with the following process:</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://0xpatrik.com/content/images/2018/08/ns_automation-2.png" class="kg-image" alt="Subdomain Takeover: Going beyond CNAME"></figure><!--kg-card-begin: markdown--><p>Check out my other posts about subdomain takeovers:</p>
<ul>
<li><a href="https://0xpatrik.com/subdomain-takeover/">Subdomain Takeover: Thoughts on Risks</a></li>
<li><a href="https://0xpatrik.com/subdomain-takeover-basics/">Subdomain Takeover: Basics</a></li>
<li><a href="https://0xpatrik.com/takeover-proofs/">Subdomain Takeover: Proof Creation for Bug Bounties</a></li>
<li><a href="https://0xpatrik.com/subdomain-takeover-candidates/">Subdomain Takeover: Finding Candidates</a></li>
</ul>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Takeover: Going beyond CNAME" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Subdomain Takeover: Finding Candidates]]></title><description><![CDATA[Subdomain takeover monitoring is a continuous process. People are often surprised by it. Domains are often working perfectly, but once the administrator removes ...]]></description><link>https://0xpatrik.com/subdomain-takeover-candidates/</link><guid isPermaLink="false">5dd051c7140a9354e2f0163b</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Tue, 21 Aug 2018 10:00:00 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/08/candidates.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/08/candidates.jpg" alt="Subdomain Takeover: Finding Candidates"><p>After my <a href="https://0xpatrik.com/subdomain-takeover-starbucks-ii/">last</a> <a href="https://0xpatrik.com/subdomain-takeover-starbucks/">posts</a>, many of you have asked me how I found the domains for Starbucks. Although I am not willing to give you exact resources, in this post, I want to describe at least the approach I overtake.</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/hacktivity-1.png" alt="Subdomain Takeover: Finding Candidates"></p>
<p>When I received the bounties for subdomain takeover, I was happy and excited, but also felt sorry in some way to other bounty hunters. Since I got automation in place, it usually takes just a few minutes to create PoC and write a report. I received $2,000 for that. Other bounty hunters spend countless hours trying to create a working exploit and receive the only fraction of that bounty. I still don't consider myself as a bug bounty hunter, but rather <strong>low-hanging fruit hunter</strong>.</p>
<p>The very first thing you need to understand is, that subdomain takeover monitoring is a continuous process. People are often surprised by it. Domains are often working perfectly, but once the administrator removes the resource where CNAME is pointing, the vulnerability is introduced. In my <a href="https://0xpatrik.com/subdomain-takeover-starbucks-ii/">second report</a>, the domain was fully working for several months. It became <em>&quot;vulnerable&quot;</em> at some point in time. 20 minutes after, I already got working PoC. If you want to find subdomain takeovers consistently, you need to create automation for yourself. No exceptions.</p>
<h1 id="process">Process</h1>
<p>As I said above, my code for automation won't be released to the public (yet). However, the process I am going to describe should be more than enough to replicate my automation and come close enough to its results. The process is divided into four main parts:</p>
<ol>
<li>Scope parsing</li>
<li>Subdomain enumeration</li>
<li>Subdomain takeover verification</li>
<li>Notifications</li>
</ol>
<p><img src="https://0xpatrik.com/content/images/2018/08/process.png" alt="Subdomain Takeover: Finding Candidates"></p>
<h2 id="scopeparsing">Scope Parsing</h2>
<p>You need to have a list of scopes for which you want to monitor subdomain takeovers. Bug bounty program specification/rules are your friend here. If we take <a href="https://hackerone.com/twitter">Twitter</a> for instance, they have clearly defined scope:</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/twitter.png" alt="Subdomain Takeover: Finding Candidates"></p>
<p>On the other case, for <a href="https://hackerone.com/intel">Intel</a> they excluded all report for <em>intel.com</em>:</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/intel.png" alt="Subdomain Takeover: Finding Candidates"></p>
<p>There is also a grey zone. Some programs like <a href="https://hackerone.com/starbucks">Starbucks</a>, don't have explicitly listed domain wildcards, but rather they specified it differently:</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/starbucks.png" alt="Subdomain Takeover: Finding Candidates"></p>
<p>It is up to you whether you want to create and automation for that. Keep also in mind that scopes also tend to change as acquisitions often happen and new programs are introduced. You can take inspiration from <a href="https://twitter.com/EdOverflow">EdOverflow's</a> <a href="https://github.com/EdOverflow/megplus/blob/master/fetch.php">script</a>. The output of this step should be the list of domains on which you want to perform subdomain enumeration, like this:</p>
<pre><code>twitter.com
vine.co
twimg.com
pscp.tv
periscope.tv
starbucks.com
starbucks.ca
...
</code></pre>
<p><img src="https://0xpatrik.com/content/images/2018/08/parsing.png" alt="Subdomain Takeover: Finding Candidates"></p>
<h2 id="subdomainenumeration">Subdomain Enumeration</h2>
<p>I have written several posts about subdomain enumeration. The only thing you need to do is to enumerate every domain from the previous step. Which tools and resources to use is the real <em>secret sauce</em>, however, and highly recommend starting with <a href="https://github.com/OWASP/Amass">amass</a>.</p>
<pre><code>amass -nodns -norecursive -noalts -d twitter.com
</code></pre>
<p>As you might know, many tools also provide domains which are no longer existing (e.g., NXDOMAIN, SERVFAIL, ...). Personally, <strong>I recommend NOT to filter domains</strong> and also keep the ones responding with another DNS status then NOERROR. I will explain why in the next section. The output of these sections should be a list of all subdomains of all domains from the previous step.</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/enumeration.png" alt="Subdomain Takeover: Finding Candidates"></p>
<h2 id="subdomaintakeoververification">Subdomain Takeover Verification</h2>
<p>Once having the full domain list, you need to monitor for subdomain takeover continuously. The easiest way is to setup <em>signatures</em> or <em>rules</em> for true positives. As I explained in <a href="https://0xpatrik.com/takeover-proofs/">this</a> post, every cloud provider has its error message. For CloudFront, it looks like this:</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/cloudfront.png" alt="Subdomain Takeover: Finding Candidates"></p>
<p>There is no need to inspect that visually. You can automate that by creating HTTP requests (with correct Host header!) to domains and then finding the unique string in HTTP response. Find some inspiration <a href="https://github.com/haccer/subjack/blob/master/subjack/subjack.go#L239">here</a>. You should also take into consideration that some cloud providers require just DNS status verification (such as Azure). There is no need to create HTTP requests there.</p>
<p>The reason why I said that you should NOT filter domains in the previous step is, that subdomain takeover verification does not end with CNAME subdomain takeover. As I briefly mentioned in <a href="https://0xpatrik.com/subdomain-takeover-basics/">subdomain takeover basics post</a>, there are also NS and MX subdomain takeovers. Long story short, when domain responds with NXDOMAIN, it might be a case of NS subdomain takeover. Many people forget about this possibility since there are not many cases of NS or MX subdomain takeover. That being said, there is at least <a href="https://thehackerblog.com/the-international-incident-gaining-control-of-a-int-domain-name-with-dns-trickery/index.html">one</a> documented. If you want to take subdomain takeover seriously, I highly recommend reading that post at least twice.</p>
<p>The diagram at the beginning of this post showed two independent loops. I recommend you similarly design your automation. The loop of subdomain enumeration is usually much slower than a loop of takeover verification. You want continuously run each loop and feed results from step two to step three without any intervention.</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/verification.png" alt="Subdomain Takeover: Finding Candidates"></p>
<h2 id="notifications">Notifications</h2>
<p>The last step, but still as important as others are notification. Once the subdomain takeover is discovered, you have to act on it as fast as possible. The field is becoming more competitive, and there might be a chance that the same domain was discovered by somebody else.  The rule the subdomain takeover says: Who creates a PoC first, wins. You want to ideally set up <a href="https://aws.amazon.com/sns/">push notifications</a>, even to your phone. There is also a possibility for creating automation that does PoC itself.</p>
<p>Check out my other posts about subdomain takeovers:</p>
<ul>
<li><a href="https://0xpatrik.com/subdomain-takeover/">Subdomain Takeover: Thoughts on Risks</a></li>
<li><a href="https://0xpatrik.com/subdomain-takeover-basics/">Subdomain Takeover: Basics</a></li>
<li><a href="https://0xpatrik.com/takeover-proofs/">Subdomain Takeover: Proof Creation for Bug Bounties</a></li>
</ul>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Takeover: Finding Candidates" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Subdomain Takeover: Yet another Starbucks case]]></title><description><![CDATA[Recently, I was repeatedly awarded $2,000 bounty for subdomain takeover on Starbucks. In this post, I explain the step-by-step process for the proof-of-concept.]]></description><link>https://0xpatrik.com/subdomain-takeover-starbucks-ii/</link><guid isPermaLink="false">5dd051c7140a9354e2f0163a</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Wed, 01 Aug 2018 10:00:00 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/08/subdomain-takeover.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/08/subdomain-takeover.jpg" alt="Subdomain Takeover: Yet another Starbucks case"><p>Recently, I was repeatedly <a href="https://hackerone.com/reports/388622">awarded</a> $2,000 bounty for subdomain takeover on <a href="https://hackerone.com/starbucks">Starbucks</a>. You may remember my <a href="https://0xpatrik.com/subdomain-takeover-starbucks/">post</a> about bug bounty report where I described how to subdomain takeover was possible using Azure. This case was pretty similar. However, I had to use another Azure service called <em>Traffic Manager</em>. In this post, I explain the step-by-step process for the proof of concept.</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/report.png" alt="Subdomain Takeover: Yet another Starbucks case"></p>
<p>On Monday evening, I noticed that <code>wfmnarptpc.starbucks.com</code> responds with <code>NXDOMAIN</code>. The more interesting fact was that it has CNAME set to <code>s00149tmppcrpt.trafficmanager.net</code>. From experience, I knew that this has a perfect chance of being a subdomain takeover. As you may remember, Azure mostly uses dedicated IP addresses, so when CNAME to Azure responds with <code>NXDOMAIN</code>, your bug bounty radar should be on.</p>
<p>Previously, I haven't mentioned that <code>trafficmanager.net</code> is also one of the domains where subdomain takeover is possible. Let's look at what is <a href="https://docs.microsoft.com/en-us/azure/traffic-manager/traffic-manager-overview">Traffic Manager</a> about:</p>
<p><em>&quot;Microsoft Azure Traffic Manager allows you to control the distribution of user traffic for service endpoints in different datacenters. [...] You can also use Traffic Manager with external, non-Azure endpoints.&quot;</em></p>
<pre><code>$ dig a wfmnarptpc.starbucks.com

; &lt;&lt;&gt;&gt; DiG 9.10.6 &lt;&lt;&gt;&gt; a wfmnarptpc.starbucks.com
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NXDOMAIN, id: 20251
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;wfmnarptpc.starbucks.com.	IN	A

;; ANSWER SECTION:
wfmnarptpc.starbucks.com. 33165	IN	CNAME	s00149tmppcrpt.trafficmanager.net.
</code></pre>
<p>Simply put, there is some domain which has link to non-existing subdomain of <code>trafficmanager.net</code>. To prove our point, we need to registered the previously removed asset in Azure. Thankfully (for us), Azure is not doing any domain ownership verification :-)</p>
<p>You may <a href="https://0xpatrik.com/subdomain-takeover-basics/">remember</a> that this situation is still not the winning point since there might be disabled configuration with this subdomain in Azure. In this case, even though <em>externally</em> it seems that takeover is possible, PoC creation would fail.</p>
<p>I started by creating a new Traffic Manager profile in the Azure portal:</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/trafficmanager-create.png" alt="Subdomain Takeover: Yet another Starbucks case"></p>
<p>Nice! At this point, I knew that the subdomain takeover is possible. The <code>s00149tmppcrpt.trafficmanager.net</code> is available; I can take it and progress with PoC. Now I needed to point the domain to one of the servers that I own:</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/endpoint.png" alt="Subdomain Takeover: Yet another Starbucks case"></p>
<p>The only thing left was to create a new <a href="https://www.nginx.com/resources/wiki/start/topics/examples/server_blocks/">virtual host</a> on my endpoint:</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/vhost-1.png" alt="Subdomain Takeover: Yet another Starbucks case"></p>
<p>Time well spent. Thank you very much.</p>
<p><img src="https://0xpatrik.com/content/images/2018/08/poc.png" alt="Subdomain Takeover: Yet another Starbucks case"></p>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Takeover: Yet another Starbucks case" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[OSINT Primer: Organizations (Part 3)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>In the previous posts, I cover a lot of things around OSINT. There are, however, still some techniques and ideas which were kept untold. I kept them for this post because I feel they are mostly related to organizations. That being said, don't let this stop you from using them</p>]]></description><link>https://0xpatrik.com/osint-organizations/</link><guid isPermaLink="false">5dd051c7140a9354e2f01635</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Thu, 26 Jul 2018 22:27:33 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/07/osint-organizations-2.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/07/osint-organizations-2.jpg" alt="OSINT Primer: Organizations (Part 3)"><p>In the previous posts, I cover a lot of things around OSINT. There are, however, still some techniques and ideas which were kept untold. I kept them for this post because I feel they are mostly related to organizations. That being said, don't let this stop you from using them elsewhere. This post demonstrates them in the context of organizations. As always, I present you with some limited framework:</p>
<ul>
<li>I am interviewing for/joining/doing business with the organization; I want to find some information around them.</li>
<li>I am doing security assessment/bug bounty on the organization; I want to find some technical details.</li>
</ul>
<h2 id="employeereviews">Employee Reviews</h2>
<p><em>An organization is as good as its employees</em>. With that being said, employees also like to write an anonymous review of their company. This is particularly useful when you are considering joining the company or looking to find the salary to ask. The most popular site for that is <a href="https://www.glassdoor.com/Reviews/index.htm">Glassdoor Company Reviews</a>. Note that you will be required to log in before viewing all reviews. A similar site for reviews is <a href="https://www.indeed.com/companies">Indeed</a>.</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/glassdoor-1.png" alt="OSINT Primer: Organizations (Part 3)"></p>
<p>(Review of <em>Apple Inc.</em> on <a href="https://www.glassdoor.com/Reviews/index.htm">Glassdoor.com</a>)</p>
<p>Business type information about a company tends to be specific to its country of registration, so I decided not to focus on that in this post heavily. There are aggregators such as <a href="https://opencorporates.com/">opencorporates.com</a>. I recommend checking <a href="http://osintframework.com/">OSINT framework</a> as its <em>Business Records</em> for specific search provider.</p>
<h2 id="technicalstack">Technical Stack</h2>
<p>From the eyes of pentester, knowing the technology stack of the organization is a valuable thing to have. You want to maximize your efforts, so knowing for instance which antivirus or outbound proxy is the company using might help you with structuring your attack. I like to do multiple things to find out these things.</p>
<ul>
<li>
<p><em>Look for job postings</em>. They usually include the required skills or experience for the position. Look for technical positions. You can see the job postings in several ways. One good idea is <a href="https://www.linkedin.com/jobs/">LinkedIn Jobs</a>. There are also job posting sites like <a href="https://www.indeed.com/">Indeed</a> or <a href="https://www.monster.com/">Monster Job</a>. I recommend using Google dork to find all possible sites: <code>&quot;&lt;ORG_NAME&gt;&quot; intext:career | intext:jobs | intext:job posting</code>. Often, company is listing job postings on its website. The idea behind this technique is simple: Organizations tend to stay consistent and deploy the same products company-wide.</p>
</li>
<li>
<p>Similar to the previous technique, <em>look for (technical) employees of the organization</em> (check <a href="https://0xpatrik.com/osint-people/">the previous post</a>) on LinkedIn. They will most likely have there certifications and skills up to date. Beware that the certifications could be acquired in the previous gigs, so I usually use this information to cross-validate the other methods.</p>
</li>
<li>
<p><em>Check <a href="https://stackshare.io/stacks">stackshare.io</a></em>. Some (mainly technical) companies share its stack publicly.</p>
</li>
<li>
<p><em>Use search engines</em>. You should not limit yourself to job postings. There might be questions on <a href="http://stackoverflow.com/">StackOverflow</a> or other similar sites from employees about specific products. These step will require more in-depth OSINT.</p>
</li>
<li>
<p><em>Metadata</em>. Organizations often share documents publicly on their website. You can leverage the fact, that popular business products such as Microsoft Office or Adobe Reader by default append metadata to the files. This metadata contains things like author's name, date, and most importantly software type and version. You can target the old version of some software with client-side exploit. The best part is that since the metadata often contain author's name, you know who is your primary target. If you are interested in this topic, I highly recommend <a href="https://blog.sweepatic.com/metadata-hackers-best-friend/">this post</a> written by <a href="https://twitter.com/intense_feel">Martin Carnogursky</a>.</p>
</li>
<li>
<p><em>Fingerprint on your own</em>. This part is a little tricky. Mainly, you want to find out what is running inside the network without being in the network (note that external scans will most likely not tell you what web proxy is being deployed). There is, however, one method for that, although I would still label it as <em>experimental</em>. The method is called <strong>DNS Cache Snooping</strong>.</p>
</li>
</ul>
<p>The basic idea is this: You will check the organization's DNS cache to see, whether there were some previous requests to some specific domain. Why is it useful? Imagine the antivirus. It downloads the new signatures periodically. For instance, some updates from McAfee some from domain <code>download.nai.com</code>. You can use non-recursive DNS request to organization's DNS server to check whether this domain is in its cache or not. However, external and internal DNS servers must be shared (or at least their cache) and still, having a cache hit might be only a false positive. That's why I called it <em>experimental</em>. Let's look at a diagram that might make things more easy for you (or not):</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/cache_snooping.png" alt="OSINT Primer: Organizations (Part 3)"></p>
<p>You can execute the non-recursive DNS query using this <code>dig</code> command:</p>
<pre><code>dig @DNS_SERVER -t A DOMAIN_TO_CHECK +norecurse
</code></pre>
<p>By <em>external</em> DNS server, I primarily mean DNS servers serving organization's website(s), in other words:</p>
<pre><code>dig -t NS MAIN_DOMAIN
</code></pre>
<p>Another problem is that you need to know the domains of products (a.k.a snooping signatures). There is a project such as <a href="https://github.com/felmoltor/DNSSnoopDogg">DNSSnoopDogg</a>. However, they are not updated for some time.</p>
<h2 id="publicsecrets">Public Secrets</h2>
<p>The last of this post and probably my most favorite are public secrets. It is incredible, what organizations share publicly without them realizing it. This post in fact already covered two categories: <em>Metadata</em> and <em>Exposed services</em>.</p>
<p>There are, however, other types of public secrets. Firstly, there are secrets committed to git repositories. This usually happens by accident when developers work with code which has API keys or passwords hardcoded in the source code. When such code is committed to a git repository, it stays in its history even if the secret is later deleted (not purged). There are two projects which I use for scanning git repositories: <a href="https://github.com/zricethezav/gitleaks">gitleaks</a> and <a href="https://github.com/dxa4481/truffleHog">truffleHog</a>.</p>
<p>Similarly, paste sites are a gold mine for secret data. Developers tend to share code using these sites, and they don't tend to look on security aspect - often submitting code with included secrets. If you want to dig deep into this, I recommend using <a href="https://github.com/kevthehermit/PasteHunter">PasteHunter</a>. It is a project which periodically checks popular paste sites and runs <a href="https://virustotal.github.io/yara/">YARA</a> signatures to check, whether it contains interesting strings. Alternatively, you can use ad-hoc methods such as using Google dorks: <code>site:pastebin.com ORG_DOMAIN</code>.</p>
<p>Lastly, I want to mention public <a href="https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html">S3 buckets</a>. Recently, there were <a href="https://www.scmagazine.com/open-aws-s3-bucket-exposes-sensitive-experian-and-census-info-on-123-million-us-households/article/720067/">multiple</a> <a href="https://www.infosecurity-magazine.com/news/fedex-s3-bucket-exposes-private/">cases</a> where sensitive information was hosted in public S3 buckets. An S3 bucket can be configured as public which developers often opt to because it is easier to work with. The problem is that once the bucket name is discovered all its content can be seen by anybody without authentication. From the tools, I recommend <a href="https://github.com/eth0izzle/bucket-stream">bucket-stream</a> which is a CLI tool. I also highly recommend a new tool which can be seen as <em>Shodan for S3</em> - <a href="https://buckets.grayhatwarfare.com/">buckets.grayhatwarfare.com</a>.</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/shodans3.png" alt="OSINT Primer: Organizations (Part 3)"></p>
<p>Part 4 of OSINT Primer will deal with <em>Certificates</em>. Stay tuned on <a href="https://twitter.com/0xpatrik">Twitter</a> to get it first.</p>
<p>Parts in this series:</p>
<p><a href="https://0xpatrik.com/osint-domains/">OSINT Primer: Domains</a><br>
<a href="https://0xpatrik.com/osint-people/">OSINT Primer: People</a><br>
<a href="https://0xpatrik.com/osint-organizations/">OSINT Primer: Organizations</a></p>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="OSINT Primer: Organizations (Part 3)" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[OSINT Primer: People (Part 2)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>In this post, continuing with OSINT related topics, we will look at researching people. Similarly to <a href="https://0xpatrik.com/osint-domains/">domains</a>, there are some specific goals during our &quot;person analysis&quot;:</p>
<ul>
<li>The person is our new acquaintance. We want to find some information about him/her.</li>
<li>You want to hire a new employee.</li></ul>]]></description><link>https://0xpatrik.com/osint-people/</link><guid isPermaLink="false">5dd051c7140a9354e2f01636</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Wed, 18 Jul 2018 19:09:21 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/07/osint-people.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/07/osint-people.jpg" alt="OSINT Primer: People (Part 2)"><p>In this post, continuing with OSINT related topics, we will look at researching people. Similarly to <a href="https://0xpatrik.com/osint-domains/">domains</a>, there are some specific goals during our &quot;person analysis&quot;:</p>
<ul>
<li>The person is our new acquaintance. We want to find some information about him/her.</li>
<li>You want to hire a new employee. Besides standard background check by HR, you might want to perform your OSINT to see, whether he/she will be a good candidate.</li>
<li>You want to pitch a new business product to a high-profile individual in some particular company. You need to get his/her e-mail or mobile number first. <em>Note that this step usually includes some organizational research which will be cover in next parts of this series.</em></li>
<li>You are a penetration tester and are currently doing spear phishing assessment. You need to find information to increase the potential success of the phishing assessment.</li>
</ul>
<p>As you can see, there are multiple situations where OSINT about people might come in handy. Let's look at some specific techniques.</p>
<p><strong>Note: The techniques in this guide should NOT be used for malicious purposes. Although it is hard to write a guide without the methods that can be used in malicious scenarios, I am not responsible for such actions.</strong></p>
<h2 id="opsec">OPSEC</h2>
<p>Before we begin, I want to mention something important. You may have heard about <em>operational security</em> or <em><a href="https://en.wikipedia.org/wiki/Operations_security">OPSEC</a></em>. During the searches, you might expose yourself in many different ways. For example, if you are logged in to LinkedIn and visit some other profile, the person will be notified about that (including your name). OPSEC can be thus seen as guidelines in a specific context. These guidelines prevent the other person from knowing either that the OSINT is being performed on them or knowing YOUR true identity.</p>
<p>I recommend using <a href="https://www.torproject.org/projects/torbrowser.html.en">Tor Browser Bundle</a> for all OSINT related activities. Firstly, your IP identity is hidden because of several encrypted connections a.k.a <em>onion</em>. Secondly, the customized version of Firefox assures that between the restarts, the cookies are deleted, and so no past activities can be fingerprinted. You should never login to your accounts using Tor.</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/tor-bundle.png" alt="OSINT Primer: People (Part 2)"></p>
<p>If the speed of Tor is problematic to you, you can opt to use <a href="https://torrentfreak.com/vpn-services-keep-anonymous-2018/">VPN service</a> combined with some safe browsing environment. Again, you don't want to expose the cookies in any way. The simplest option is to use <em>Private Mode</em> in a browser, although I would go as far and recommend using <a href="https://inteltechniques.com/buscador/">virtual machine dedicated to OSINT</a>.</p>
<h2 id="socialmedia">Social Media</h2>
<p>First thing I like to do is to find the social media profiles. Why? I believe that they hold the majority of useful OSINT information. You should expect multiple false positives when dealing with popular names such as <em>John Smith</em>, etc.</p>
<p>Finding social media profiles might be difficult or easy depending on privacy and <em>consistency</em> of your target. Simple Google search will sometimes do its trick:</p>
<pre><code>John Doe site:facebook.com
John Doe site:instagram.com
John Doe site:linkedin.com
...
</code></pre>
<p>Note that for several social media sites, you will need to have an account created to see the full profile. I recommend creating a fake account for this purpose.</p>
<p>People tend to reuse their usernames across different services. Username there acts as a unique identifier of a person across the Internet. I like to extract the username from the Instagram of the person. Then, I use a service called <a href="https://namechk.com/">namechk</a> to search for this username across many different social media platforms.</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/namechk.png" alt="OSINT Primer: People (Part 2)"></p>
<p>I have to say that I haven't registered an account on all of the indicated platforms. You should expect some false positives, as always.</p>
<p>There are also aggregator such as <a href="https://pipl.com/">pipl.com</a> or <a href="https://www.social-searcher.com/">social-searcher</a>. Although I don't always use them, they tend to provide a more high-level view of the person.</p>
<h2 id="prospects">Prospects</h2>
<p>This is a topic that can be suited both here and to organizational OSINT as well. I decided to stick it here since I think it mostly relates to people than organizations itself.</p>
<p>When dealing with sales, it is often necessary to have a good contact in the organization to pitch to. You should be smart about that and decide, which person is the right choice. Certainly, it is not a good idea to pitch an infosec related product to CEO of Fortune 500 company. CISO or Senior Security Engineer might be a better choice here. On the other hand, pitching a security-related product to CEO of startup makes more sense.</p>
<p>I don't want to describe the full cold calling/e-mailing approach here; I want to explain the best ways to find the contact information of key people in your target organization. I highly recommend checking <a href="https://clearbit.com/prospector">Clearbit Prospector</a> for this task. It is a great product with accurate data. Although it is a paid product, I honestly think it is worth the money if you are doing lot of such searches. Yes, it is not OSINT in a true sense, other techniques are explained below.</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/clearbit-1.png" alt="OSINT Primer: People (Part 2)"></p>
<p>Another product that I like is <a href="https://hunter.io/">Hunter.io</a>. Again it is a paid product, but you have a 100 searches / month for free. Similar services are called <a href="https://www.voilanorbert.com/">voilanorbert</a> and <a href="https://headreach.com/">headreach</a>. They also operate on a freemium model. I think that this is the best way of finding e-mail addresses for specific people in organizations.</p>
<p>Alternatively, you can use LinkedIn for the initial cold message. You simply use <em>Search bar</em> with query <code>&lt;COMPANY_NAME&gt; &lt;POSITION&gt;</code> and get the most accurate results. People tend to keep their LinkedIn profiles updated. You can then connect with them easily (although not via e-mail). A similar thing applies to Twitter. However, I would say it is a less formal medium.</p>
<p><strong>Pro tip</strong>: For smaller companies, the e-mails are usually listed directly on their website.</p>
<p>For some useful Google Dorks about cold calling, I recommend <a href="https://apollonsky.me/growth-hacking-google-dork/">this article</a>.</p>
<h2 id="telephonenumbers">Telephone Numbers</h2>
<p>Finding telephone numbers is more tricky than e-mails. My go-to tool is either Google where I try to dork using the name of the person and some combination of <code>telephone number</code> keywords or use White/Yellow Pages in the particular country such as <a href="https://www.whitepages.com/">whitepages.com</a> for the US. Make sure to check <a href="https://github.com/jivoi/awesome-osint">awesome-osint</a> for a list of telephone number searching services.</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/whitepages.png" alt="OSINT Primer: People (Part 2)"></p>
<p>Sometimes, I need to perform a reverse telephone search: Given the telephone number, I want to retrieve the name of its owner. This is useful when you have missed calls which you want to correlate to the owner. You could either use services described above, but the more universal approach is as follows:</p>
<ol>
<li>Try the Facebook search with the number. The owner should come up in the results if he/she has the number associated with the profile.</li>
<li>Save the number in your phone and look at Viber or WhatsApp contact list. These services allow specifying photo and the name of the owner and this information can be extracted just by knowing the telephone number.</li>
</ol>
<h2 id="emails">E-mails</h2>
<p>I described finding e-mails in the <em>Prospecting</em> section above. Now, I want to extend that and talk about more technical things about e-mail OSINT. SMTP support two, not very well-known commands <a href="https://cr.yp.to/smtp/vrfy.html">VRFY and EXPN</a>. The former is used to verify directly on the mail server, whether some particular mailbox exists or not. This is particularly useful when you are already familiar with standard e-mail address format for the company. The formats are usually:</p>
<pre><code>lastname@company.tld
firstname.lastname@company.tld
firstletterfirstname.lastname@company.tld
</code></pre>
<p>The easiest way to test this is to use an online tool such as <a href="http://mailtester.com/testmail.php">MailTester.com</a>. Don't be distracted by a historic design of this websites. It does the outstanding job compared to other similar services. Note that not every SMTP server allows this command (apparently), but from experience, even the high-profile organizations sometimes have this turned on (ehm, Apple).</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/apple.png" alt="OSINT Primer: People (Part 2)"><br>
<img src="https://0xpatrik.com/content/images/2018/07/apple-1.png" alt="OSINT Primer: People (Part 2)"></p>
<p>The <em>EXPN</em> command is used to list members of some distribution list. SMTP server provides the individual e-mail addresses of such members.</p>
<p>I also like to test, whether some e-mail address is present in some dump of leaked credentials. The easiest way is to use <a href="https://haveibeenpwned.com/">Have I Been Pwned</a> by <a href="https://twitter.com/troyhunt">Troy Hunt</a>. This is useful in combination with security assessment. Why? Usually, people reuse passwords, and there is a chance that the password that user used in some services from which the credentials were stolen is used in a corporate environment as well.</p>
<p>The purpose of this guide is not to flood you with as many tools as possible. Rather, I try to explain different techniques. If you want to use different tools, you can find the right one <a href="https://github.com/jivoi/awesome-osint">here</a>. Note that some of the tools work only in specific countries.</p>
<p>Parts in this series:</p>
<p><a href="https://0xpatrik.com/osint-domains/">OSINT Primer: Domains</a><br>
<a href="https://0xpatrik.com/osint-people/">OSINT Primer: People</a><br>
<a href="https://0xpatrik.com/osint-organizations/">OSINT Primer: Organizations</a></p>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="OSINT Primer: People (Part 2)" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Finding Phishing: Tools and Techniques]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Phishing is still one of the most prominent ways of how cyber adversaries monetize their actions. Generally, phishing tries to accomplish two primary goals:</p>
<ul>
<li><strong>Gain initial access to network</strong> — Adversary sends spear phishing e-mail with a well-crafted pretext and malicious attachment. Adversary then waits until the victim opens the attachment</li></ul>]]></description><link>https://0xpatrik.com/phishing-domains/</link><guid isPermaLink="false">5dd051c7140a9354e2f01638</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Mon, 09 Jul 2018 20:41:13 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/07/phishing.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/07/phishing.jpg" alt="Finding Phishing: Tools and Techniques"><p>Phishing is still one of the most prominent ways of how cyber adversaries monetize their actions. Generally, phishing tries to accomplish two primary goals:</p>
<ul>
<li><strong>Gain initial access to network</strong> — Adversary sends spear phishing e-mail with a well-crafted pretext and malicious attachment. Adversary then waits until the victim opens the attachment and connects to the C2 server. The attachment is usually one of Office file formats in combination with VBScript/WScript/Powershell and has pretty high success in evading anti-virus (when done correctly).</li>
<li><strong>Steal credentials for online services</strong> — Adversary clones some high-value website (usually login form of some web services) and convince the user to enter her credentials. Adversary then gathers the credentials and uses it to further (malicious) actions. The cloned website is delivered to the victim using different channels. Delivery of such website (with pretext) to the user depends on the adversary &quot;audience&quot;. Generally, e-mail is a prominent delivery channel for this type of phishing as well. The attachment is not present this time. However, the pretext is crafted in a way that it contains URL to the malicious domain. Other channels include Whatsapp, Facebook Messenger, etc.</li>
</ul>
<p><img src="https://0xpatrik.com/content/images/2018/07/phishing_process.png" alt="Finding Phishing: Tools and Techniques"></p>
<p>When dealing with incident response, the general workflow in analyzing phishing is in most cases <em>reactive</em>. In other words, incident responders wait until some tech-savvy employee/customer reports the suspicious phishing site, suspicious e-mail, or start seeing suspicious traffic in SIEM. At that time, it is likely that other employees have already been compromised.</p>
<p>In this post, I want to focus on the latter category and describe, how you can proactively find domains that try to mimic the websites of some particular organization (read <em>yours</em>). I will focus on:</p>
<ul>
<li><em>Websites mimicking intranet</em> sites to get valid internal network credentials.</li>
<li><em>Websites mimicking product</em> sites to get valid credentials from <strong>your customers</strong>. These can the result of brand damage since the phishing site is associated with your brand.</li>
</ul>
<p>By proactively detecting these sites, you can be prepared to face phishing waves <em>inside</em> your organization and notify your customers about malicious actions hopefully before they happen.</p>
<p>Please note that if you want to get some results from these techniques, you should implement <strong>continuous processes</strong> regarding automation instead then one-time search. By no means you should expect perfect process for this problem - instead, we are trying to use heuristics to find a significant amount of badness without least amount of false positives.</p>
<p><em>I will dedicate the whole post for explaining details of attachment-based spear phishing, including macro creation and some Powershell tricks.</em></p>
<h2 id="domains">Domains</h2>
<p>Firstly, let's look at the general scheme of finding such domains/websites. Since there are countless websites created every day, it would be pretty hard to check them all. We need to limit the scope, somehow. Usually, an adversary creates a new domain that at least look somehow legitimate:</p>
<ul>
<li><strong>Typosquatting domain</strong> — <a href="https://en.wikipedia.org/wiki/Typosquatting">Typosquatting</a> is a technique of registering domain names which look similar to some legitimate domain name. For instance, given <em>google.com</em>, one example of typosquatting domain might be <em>g00gle.com</em><br>
(notice the &quot;zero&quot; instead of &quot;o&quot;). Such domain name appears identical to the original one. There is a <a href="https://zeltser.com/domain-name-variations-in-phishing/">large list</a> of typosquatting techniques.</li>
<li><strong>Doppelganger domain</strong> — A <a href="https://en.wikipedia.org/wiki/Doppelganger_domain">doppelganger domain</a> is similar to typosquatting domain. It is a domain which is missing &quot;.&quot; (dot) in a domain name. For example, an instance of Doppelganger domain for <em>mail.google.com</em> is <em>mailgoogle.com</em> (notice the missing dot). When the content on these domain matches branding and content of the original website, users are not able to tell the difference and are more likely to be tricked by an attacker (e.g., for credential harvesting or financial fraud).</li>
<li><strong>Domain with keyword present</strong> — The new trend in phishing domains is, that adversaries create long domain names with gibberish, but include the keyword of targeted brand inside the domain name. Because of keyword and (almost always) SSL certificate present, <a href="https://www.wired.com/story/phishing-schemes-use-encrypted-sites-to-seem-legit/">users believe</a> that this is indeed a legitimate site. This should by no means be considered as a rule. There are certainly domain names that clone some brand but doesn't include any such keyword in FQDN.</li>
</ul>
<p>From my own experience, the last category is the most prominent. One of the reasons is that many typosquatted domains for popular brands are already registered. An adversary needs to be more creative and look for typosquatting domains which are easily spotted as somehow suspicious by a majority of users.</p>
<p>On the other hand, a long domain name with brand name present as a keyword is &quot;<em>less</em>&quot; suspicious that somehow weirdly typo-squatted domain. <em>Keep in mind that these are my opinions about this problem.</em></p>
<h2 id="findingtyposquatting">Finding typosquatting</h2>
<p>There is probably just one tool you need for detecting typosquatting: <a href="https://github.com/elceef/dnstwist">dnstwist</a>. It is a Python package that will enumerate all typosquatting possibilities and present you with a nice report. The list of domains can be then fed to <a href="https://github.com/FortyNorthSecurity/EyeWitness">EyeWitness</a> to see, whether some domain is hosting something potentially malicious.</p>
<p>Excerpt from dnstwist running on <code>paypal.com</code>:<br>
<img src="https://0xpatrik.com/content/images/2018/07/dnstwist-1.png" alt="Finding Phishing: Tools and Techniques"></p>
<p>Alternatively, there are online services like <a href="https://dnstwist.it/">dnstwist.it</a> which do the similar thing directly in your browser.</p>
<p><img src="https://0xpatrik.com/content/images/2020/08/dnstwister.png" alt="Finding Phishing: Tools and Techniques"></p>
<h2 id="findinglongdomainswiththekeyword">Finding Long Domains with the Keyword</h2>
<p><em>Before going forward, I recommend reading <a href="https://0xpatrik.com/censys-guide/">Censys Guide</a> that I wrote before.</em></p>
<p>The technique in this section is possible because of two things that emerged in recent years:</p>
<ul>
<li>Free CA's such as <a href="https://letsencrypt.org/">Let's Encrypt</a></li>
<li><a href="https://www.certificate-transparency.org/what-is-ct">Certificate Transparency</a></li>
</ul>
<p>The basic premise is this: Since the TLS/SSL certificate is now free to obtain, adversaries in most cases issue one for the malicious domain. <strong>&quot;Secure&quot;</strong> badge in URL bar makes things more legitimate.</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/paypal-phishing.png" alt="Finding Phishing: Tools and Techniques"></p>
<p><em>(Picture taken shamelessly from <a href="https://github.com/x0rz/phishing_catcher">https://github.com/x0rz/phishing_catcher</a>)</em></p>
<p><strong>How can we leverage this fact?</strong></p>
<p>Certificate Transparency (CT) is a project that collects the majority of certificates that were issued and provided this data to the public. By parsing CT logs, we can easily extract domain names (from Subject / SAN fields) and make a simple syntactic comparison of keywords inside these domain names.</p>
<p>Firstly, we need to get access to Certificate Transparency logs. There are numerous services offering this, including <a href="https://certdb.com/">certdb</a>, and <a href="https://crt.sh/">crt.sh</a>. I don't use either of these two because they don't offer advanced query options. I recommend you start using <a href="https://0xpatrik.com/censys-guide/">Censys</a> for querying CT logs.</p>
<p>Secondly, we need to gather a list of potential keywords we want to search. The most common keyword would be the full domain name of some company/service (e.g., apple.com). You shouldn't stop here but look for variations like striping TLD (<em>apple</em>) or querying domain names. Beware that depending on the keyword; the result set might provide a couple of false positives which you would need to sort manually at first. I also like to filter based on particular CA (mainly Let's Encrypt) but only in cases where the result set is too big. The example query to find phishing domain for <em>apple.com</em> would then be:</p>
<p><code>(apple.com*) AND parsed.issuer.organization.raw:&quot;Let's Encrypt&quot;</code></p>
<p>you can also limit the results by specifying issue date range like so:</p>
<p><code>parsed.validity.start: [2018-07-09 TO *]</code></p>
<p><img src="https://0xpatrik.com/content/images/2018/07/cert_listing.png" alt="Finding Phishing: Tools and Techniques"></p>
<p>An alternative to using Censys as the primary source of CT data, you can leverage a fantastic project called <a href="https://medium.com/cali-dog-security/introducing-certstream-3fc13bb98067">CertStream</a>. CertStream provides a real-time stream of newly generated certificates which you can use to detect specified keywords in (near) real-time. In fact, there is a project called <a href="https://github.com/x0rz/phishing_catcher">phishing_catcher</a> that does just like that. The major downside of this approach from my perspective is a lot of unnecessary work when you are interested in only one brand. You need to run CertStream regularly whereas Censys can be queried anytime with more advanced query options.</p>
<p>Screenshot from <em>phishing_catcher</em>:</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/phishing_catcher.png" alt="Finding Phishing: Tools and Techniques"></p>
<p>There is also an option of creating your own certificates database using projects like <a href="https://github.com/CaliDog/Axeman">Axeman</a>.</p>
<p>Lastly, I want to point out why certificates are ideal for finding such domains. Long domains usually contain multiple levels of subdomains. One of the alternative ideas is to gather a list of newly registered domains for some TLDs (<a href="https://www.whoxy.com/newly-registered-domains/">Whoxy</a> provides such service) and check the keywords in these domains. The problem is that these domains are second-level domains - you need to perform <a href="https://0xpatrik.com/asset-discovery/">subdomain enumeration</a> first to discover all potentially malicious domains. Another problem is, that since such domain names contain a lot of gibberish, subdomain enumeration techniques are likely to fail (unless using CT sources).</p>
<h2 id="puttingittogether">Putting It Together</h2>
<p>As always, I would like to automate this boring process. It is sometimes useful to combine both techniques:</p>
<ol>
<li>Run <a href="https://github.com/elceef/dnstwist">dnstwist</a> on some domain</li>
<li>Resolve the typosquatting domains</li>
<li>Strip TLD and find them in Censys</li>
</ol>
<p>High-level, this is the process that I follow (dotted line represents alternative approach):</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/finding_phishing.png" alt="Finding Phishing: Tools and Techniques"></p>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Finding Phishing: Tools and Techniques" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[OSINT Primer: Domains (Part 1)]]></title><description><![CDATA[The post doesn't explain the enumeration part for finding related domains, but rather finding domain-specific data such as owner, reputation, or DNS settings.]]></description><link>https://0xpatrik.com/osint-domains/</link><guid isPermaLink="false">5dd051c7140a9354e2f01634</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Sun, 08 Jul 2018 16:06:56 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/07/osint-domains.jpeg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/07/osint-domains.jpeg" alt="OSINT Primer: Domains (Part 1)"><p>In this post, I explain how I approach finding as much information about the domain as possible. The post doesn't solve the <em>enumeration</em> part for finding related domains (as I explained <a href="https://0xpatrik.com/asset-discovery/">here</a>), but rather finding domain-specific data such as owner, reputation, or DNS settings. The post is aimed towards <strong>everybody working on threat intel, malware analysis, bug bounty, journalism, and many similar areas</strong>.</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/domains-1.png" alt="OSINT Primer: Domains (Part 1)"></p>
<p><em>Note: This is the first version (July '18) of this <strong>OSINT Primer</strong>. I will be progressively updating it with new tools and techniques.</em></p>
<p>Before I dig into specific techniques/tools, I want to talk about my mindset briefly. Usually, I have one of these goals in mind:</p>
<ul>
<li>The domain is <em>primary domain</em> of my target, I want to get as much information as I can. Note that in this case I usually go with <em>gather-everything-use-something</em>.</li>
<li>The domain is likely <em>malicious</em>, I want to confirm my hypothesis and see what it is about.</li>
<li>The domain seems like a potential attack vector to gather initial foothold. Specifically, it is hosting some services which can be exploited. I want to see details about these services.</li>
</ul>
<p>Remember that you should always have a clear goal in mind. This prevents you from doing unnecessary stuff.</p>
<p>Note that there is a slight overlap with <em>domains</em> and <em>services</em> present on domains. In some cases, I will explain techniques which affect <em>services</em> as well.</p>
<h2 id="whois">WHOIS</h2>
<p>The very first technique that should be in your arsenal is WHOIS lookup. WHOIS is used for querying databases that store the registered users of domain names, IP blocks, or ASN. You can use the CLI tool:</p>
<pre><code>$ whois DOMAIN
</code></pre>
<p>or opt to some web service such as <a href="https://whois.icann.org/en">ICANN WHOIS</a>.</p>
<p>WHOIS data provide information about an entity that registered the domain. Remember that some domains might have WHOIS information hidden, and some might provide false data.</p>
<p>WHOIS data provide a clue whether the domain is tied to some specific organization or not. Although this is more useful in <em>enumeration</em> step, WHOIS data can provide help in some specific situations - for instance, if you encounter domain which tries to mimic some specific organization and WHOIS records are not tied to that organizations, this is a huge red flag.</p>
<h2 id="domainprofiling">Domain Profiling</h2>
<p>Sometimes, you want to get an overall picture of domain information or decisions that domain administrator made.</p>
<p>One of my go-to tools is <a href="https://www.robtex.com/dns-lookup/eff.org">Robtex's DNS lookup</a>. It provides a massive amount of information about the domain. I especially like the <em>Shared</em> sections which provide you with an overview about other related domains (yes, this is related to the enumeration phase, forgive me  for once :-))</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/robtex-shared-1.png" alt="OSINT Primer: Domains (Part 1)"></p>
<p>Robtex provides much more information (e.g., SEO details, reputation, ...), however usually in a limited scope. I try to use another source for specific details. <em>Robtex provides me with a high-level perspective</em>. I highly recommend creating (free) account there so you can leverage more advanced functionality.</p>
<p>Next, I like to use <a href="https://github.com/eldraco/domain_analyzer">domain_analyzer</a> to provide me with in-depth technical information about domain settings. This tool is a literal beast. It can even crawl the websites to discover e-mails and much more. I like to use it in a more limited way like so:</p>
<pre><code>python domain_analyzer.py -d DOMAIN -w -j -n -a
</code></pre>
<p>It is hard to tell directly what data can be useful from this output. However, it helped me multiple times in the past. I like to store the output and get back to it during the analysis multiple times.</p>
<h2 id="passivedata">Passive Data</h2>
<p>It is useful to check what was the domain serving in the past. There are two types of passive domain data:</p>
<ul>
<li><strong>Passive DNS</strong> — What were the values of DNS records in the past</li>
<li><strong>Passive &quot;content&quot;</strong> — What was a web server on this particular domain hosting in the past</li>
</ul>
<p>For Passive DNS, I like to use <a href="https://community.riskiq.com/home">RiskIQ Community Edition</a>. The interface is super simple, and search results will show you the passive data immediately:</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/riskiq-community.png" alt="OSINT Primer: Domains (Part 1)"></p>
<p>Although RiskIQ CE is meant to be an overall analysis platform for domains, I exclusively use it to get passive DNS data. As in many other areas of this post, it is up to you to decide, whether you stick with one source or use multiple sources for different data. I like to use the latter approach since each provider is usually reliable in just one area.</p>
<p>Next to RiskIQ CE, I like to use <a href="https://www.virustotal.com/">VirusTotal</a> as well:</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/virustotal.png" alt="OSINT Primer: Domains (Part 1)"></p>
<p>Again, you will get more data than just passive DNS. From my own experience, RiskIQ tends to provide more data for passive DNS.</p>
<p>Lastly, I will mention <a href="https://www.circl.lu/services/passive-dns/">passive DNS from CIRCL.LU</a> which I am lucky to have access to. I sometimes use it to cross-correlate the above two sources. Note that CIRCL.LU passive DNS is not open to the public.</p>
<p>More Passive DNS sources:</p>
<ul>
<li><a href="https://passivedns.mnemonic.no/search">mnemonic</a></li>
<li><a href="https://securitytrails.com/dns-trails">DNSTrails</a></li>
</ul>
<p>My go-to tool for passive content is <a href="https://web.archive.org/">Wayback Machine</a>. It includes snapshots of most websites from the past. There are usually multiple snapshots, so you can even choose the date of the snapshot you want to see:</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/wayback-machine-1.png" alt="OSINT Primer: Domains (Part 1)"></p>
<p>The frequency of snapshots depends on website popularity. Next, I like to use simple Google Dork to retrieve the last content of some URL from Google database like so:</p>
<pre><code>cache:https://eff.org/
</code></pre>
<p><img src="https://0xpatrik.com/content/images/2018/07/google-cache.png" alt="OSINT Primer: Domains (Part 1)"></p>
<h2 id="contentanalysis">Content Analysis</h2>
<p>You might want to check what is the web server on the domain currently serving. When dealing with potential malware site, it is necessary to follow basic OPSEC guidelines. You should NEVER directly visit such site without at least some protection regarding VPN or even a virtual machine. I like to use the service called <a href="https://urlscan.io/">urlscan.io</a> which makes HTTP request on your behalf, provide you with a screenshot and some other information that can be used for your analysis.</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/urlscan.png" alt="OSINT Primer: Domains (Part 1)"></p>
<p>Sometimes, you want to detect the visual changes on some websites. This is useful when the domain is currently parked and might be changed to something different in the future. For this purpose, I like to use <a href="https://visualping.io/">visualping.io</a>. This service will automatically notify you once the content on some domain change. An open-source alternative to this is called <a href="https://github.com/thp/urlwatch">urlwatch</a>.</p>
<p>From the content perspective, short URLs are often used to mask the malware/phishing domain in delivery to the victim. The tool called <a href="http://checkshorturl.com/">checkshorturl.com</a> is used to expand the short URL to its original form automatically.</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/short-url.png" alt="OSINT Primer: Domains (Part 1)"></p>
<p>Related to content, I usually want to check what is the technology stack on some website. I use <a href="https://www.wappalyzer.com/">Wappalyzer</a> as a browser plugin. Wappalyzer automatically recognizes technologies on each website you browse to:</p>
<p><img src="https://0xpatrik.com/content/images/2018/07/wappalyzer.png" alt="OSINT Primer: Domains (Part 1)"></p>
<p>Results from Wappalyzer enable me to then fire some vulnerability scanning tools such as <a href="https://github.com/droope/droopescan">droopescan</a> in this case. If you want rather use a CLI based tool, I recommend <a href="https://github.com/WeiChiaChang/stacks-cli">stacks-cli</a>.</p>
<h2 id="trafficanalytics">Traffic Analytics</h2>
<p>After content analysis, I want to check how to website (on the domain) is popular on the Web. I use several SEO analytics tools for this:</p>
<ul>
<li><a href="https://www.similarweb.com/website/">SimilarWeb</a></li>
<li><a href="https://analytics.moz.com/pro/link-explorer/home">moz Link Explorer</a></li>
<li><a href="https://www.semrush.com/info/">SEMRush</a></li>
<li><a href="http://moonsearch.com/">moonsearch</a></li>
<li><a href="https://www.alexa.com/siteinfo/">Alexa</a></li>
</ul>
<p><img src="https://0xpatrik.com/content/images/2018/07/similarweb.png" alt="OSINT Primer: Domains (Part 1)"></p>
<h2 id="reputation">Reputation</h2>
<p>During incident response or malware analysis, it is often necessary to check the reputation of some domain. The reputation might give you a clue whether the domain is known to be associated with some malicious activity. There are numerous (free) services for providing this information. You should always check multiple sources as the strategies for categorizing domains differ from vendor to vendor. Reputation often goes hand-in-hand with categorization. Domain categorization is determined by the content the (web) server is hosting. The categories can be then used for many purposes such as web traffic filtering using proxies. Reputation is then determined based on the category - low trusting domains will have category <em>ads</em>, <em>suspicious</em>, <em>malicious</em> and so on.</p>
<p>Reputation tools that I use the most:</p>
<ul>
<li><a href="https://sitereview.bluecoat.com/">Bluecoat Sitereview</a></li>
<li><a href="https://www.google.com/transparencyreport/safebrowsing/diagnostic/">Google Safebrowsing</a></li>
<li><a href="https://sitecheck.sucuri.net/">Sucuri Sitecheck</a></li>
<li><a href="https://www.threatminer.org/">ThreatMiner</a></li>
<li><a href="https://cymon.io/">CyMon</a></li>
<li><a href="https://www.trustedsource.org/en/feedback/url?action=checksingle">McAfee TrustedSource</a></li>
</ul>
<p><img src="https://0xpatrik.com/content/images/2018/07/bluecoat.png" alt="OSINT Primer: Domains (Part 1)"></p>
<p>There are also domain <em>blacklist</em> which are a list of domains that are explicitly categorized as malicious. Tools such as <em>CyMon</em> also look inside these blacklists. Example of this blacklist is <a href="https://www.spamhaus.org/lookup/">Spamhause Domain Blacklist</a>.</p>
<h2 id="osintautomation">OSINT Automation</h2>
<p>As you might see, there are many sources to domain-related data. Manually querying each of these sources can be exhausting at times of extensive analysis when you need to gather information about tens or hundreds of domains. Although to my knowledge, there is currently no tool that can query every one of the tools mentioned in this post, my primary OSINT tool at the moment is <a href="https://github.com/Te-k/harpoon">harpoon</a>. It is a super useful tool which can save you a massive amount of time during your analysis. I recommend reading the documentation carefully and checking which sources are available. Example output from <em>harpoon</em> (looking for website snapshots):</p>
<pre><code>p@eternity:~$ harpoon cache https://eff.org
Google: FOUND https://webcache.googleusercontent.com/search?num=1&amp;q=cache%3Ahttps%3A%2F%2Feff.org&amp;strip=0&amp;vwsrc=1 (2018-07-07 13:04:39+00:00)
Yandex: NOT FOUND
Archive.is: FOUND
-2012-12-20 17:36:48+00:00: http://archive.is/20121220173648/https://eff.org/
-2013-09-30 21:30:38+00:00: http://archive.is/20130930213038/http://eff.org/
-2014-01-27 14:55:32+00:00: http://archive.is/20140127145532/https://eff.org/
-2014-03-18 07:18:52+00:00: http://archive.is/20140318071852/http://eff.org/
-2014-03-29 01:59:16+00:00: http://archive.is/20140329015916/http://eff.org/
-2014-10-12 13:29:16+00:00: http://archive.is/20141012132916/http://eff.org/
-2014-11-18 05:30:31+00:00: http://archive.is/20141118053031/http://eff.org/
-2014-11-26 00:27:10+00:00: http://archive.is/20141126002710/http://eff.org/
-2015-01-06 05:16:11+00:00: http://archive.is/20150106051611/http://eff.org/
-2015-02-25 23:13:18+00:00: http://archive.is/20150225231318/http://eff.org/
-2015-04-03 12:32:17+00:00: http://archive.is/20150403123217/http://eff.org/
-2015-06-03 17:17:27+00:00: http://archive.is/20150603171727/http://eff.org/
-2017-01-16 17:29:46+00:00: http://archive.is/20170116172946/https://eff.org/
-2017-02-20 20:15:58+00:00: http://archive.is/20170220201558/https://eff.org/
-2017-12-13 05:06:22+00:00: http://archive.is/20171213050622/http://eff.org/
-2017-12-17 21:18:37+00:00: http://archive.is/20171217211837/http://eff.org/
Archive.org: NOT FOUND
Bing: FOUND http://cc.bingj.com/cache.aspx?d=4505675932894641&amp;w=enxY6wdkqMMA8cCOvykvjwxhAM6cEKCx (2018-06-07 00:00:00)
</code></pre>
<p>Alternatives (less sources and weak quality):</p>
<ul>
<li><a href="https://github.com/QTek/QRadio">QRadio</a></li>
<li><a href="https://github.com/1aN0rmus/TekDefense-Automater">Automater</a></li>
</ul>
<p>..or you might use a swiss-army knife for all areas of OSINT - <a href="https://github.com/DataSploit/datasploit">datasploit</a>. For more tools dealing with domain OSINT, you should also check-out <a href="http://osintframework.com/">OSINT Framework</a>.</p>
<p>Parts in this series:</p>
<p><a href="https://0xpatrik.com/osint-domains/">OSINT Primer: Domains</a><br>
<a href="https://0xpatrik.com/osint-people/">OSINT Primer: People</a><br>
<a href="https://0xpatrik.com/osint-organizations/">OSINT Primer: Organizations</a></p>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Subdomain Takeover: Basics]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Although I have written <a href="https://0xpatrik.com/subdomain-takeover-starbucks/">multiple</a> <a href="https://0xpatrik.com/takeover-proofs/">posts</a> about subdomain takeover, I realized that there aren't many posts covering basics of subdomain takeover and the whole &quot;problem statement.&quot; This post aims to explain (in-depth) the entire subdomain takeover problem once again, along with results of an Internet-wide scan that I</p>]]></description><link>https://0xpatrik.com/subdomain-takeover-basics/</link><guid isPermaLink="false">5dd051c7140a9354e2f01637</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Wed, 27 Jun 2018 16:31:48 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/06/subdomain-takeover.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/06/subdomain-takeover.jpg" alt="Subdomain Takeover: Basics"><p>Although I have written <a href="https://0xpatrik.com/subdomain-takeover-starbucks/">multiple</a> <a href="https://0xpatrik.com/takeover-proofs/">posts</a> about subdomain takeover, I realized that there aren't many posts covering basics of subdomain takeover and the whole &quot;problem statement.&quot; This post aims to explain (in-depth) the entire subdomain takeover problem once again, along with results of an Internet-wide scan that I performed back in 2017.</p>
<p><img src="https://0xpatrik.com/content/images/2018/06/notation.png" alt="Subdomain Takeover: Basics"></p>
<h2 id="groundzero">Ground Zero</h2>
<p>Subdomain takeover is a process of registering a non-existing domain name to gain control over another domain. The most common scenario of this process follows:</p>
<ol>
<li>Domain name (e.g., <em>sub.example.com</em>) uses a CNAME record to another domain (e.g., <em>sub.example.com</em> CNAME <em>anotherdomain.com</em>).</li>
<li>At some point in time, <em>anotherdomain.com</em> expires and is available for registration by anyone.</li>
<li>Since the CNAME record is not deleted from example.com DNS zone, anyone who registers <em>anotherdomain.com</em> has full control over sub.example.com until the DNS record is present.</li>
</ol>
<p>The implications of the subdomain takeover can be pretty significant. Using a subdomain takeover, attackers can send phishing emails from the legitimate domain, perform cross-site scripting (XSS), or damage the reputation of the brand which is associated with the domain. You can read more about implications (risks) in my other <a href="https://0xpatrik.com/subdomain-takeover/">post</a>.</p>
<p>Subdomain takeover is not limited to CNAME records. NS, MX and even A records (which are not subject to this post) are affected as well. This post deals primarily with CNAME records. However, use cases for NS and MX records are presented where needed.</p>
<h2 id="regulardomains">Regular Domains</h2>
<p>DNS delegation using a CNAME record is entirely transparent to the user, i.e., it happens in the background during DNS resolution. The picture below illustrates the behavior of a web browser for the domain name which has CNAME record in place.</p>
<p><img src="https://0xpatrik.com/content/images/2018/06/takeover_basic.png" alt="Subdomain Takeover: Basics"></p>
<p>Note that a web browser is implicitly putting trust to anything that DNS resolver returns. Such trust means that when an attacker gains control over DNS records, all web browser security measurements (e.g., <em>same-origin policy</em>) are bypassed. This presents a considerable security threat since subdomain takeover breaks the authenticity of a domain which can be leveraged by an attacker in several ways. As will be shown in later, TLS/SSL does not fix this problem since subdomain takeover is not regular <a href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">Man-in-the-middle</a> style attack.</p>
<p><strong>CNAME subdomain takeover</strong>. One of the primary types of CNAME subdomain takeover is the scenario when a canonical domain name is a regular Internet domain (not one owned by cloud providers as will be explained <a href="#cloudproviders">below</a>). The process of detecting whether some source domain name is vulnerable to CNAME subdomain takeover is quite straightforward:</p>
<p><em>Given the pair of source and canonical domain names, if the base domain of a canonical domain name is available for registration, the source domain name is vulnerable to subdomain takeover.</em></p>
<p><img src="https://0xpatrik.com/content/images/2018/06/flowchart_regular_domain.png" alt="Subdomain Takeover: Basics"></p>
<p>The noteworthy thing in the process is <em>,,the base domain of a canonical domain name&quot;</em>. That is because the canonical domain name might be in the form of a higher-level domain. If a base domain is available for registration, the higher-level domain names can be easily recreated in the DNS zone afterward.</p>
<p>Checking the availability of base domain names can be achieved using domain registrars such as <a href="https://www.namecheap.com/">Namecheap</a>. One might think that testing a DNS response status for NXDOMAIN is sufficient indication that the domain name is available for registration. Note however that it is not the case since there are cases where domain name responds with NXDOMAIN but cannot be registered. Reasons include restricted top-level domains (e.g., .GOV, .MIL) or reserved domain names by TLD registrars.</p>
<p><strong>NS subdomain takeover</strong>. The concept of subdomain takeover can be naturally extended to NS records: <em>If the base domain of canonical domain name of at least one NS record is available for registration, the source domain name is vulnerable to subdomain takeover.</em></p>
<p>One of the problems in subdomain takeover using NS record is that the source domain name usually has multiple NS records. Multiple NS records are used for redundancy and load balancing. The nameserver is chosen randomly before DNS resolution. Suppose that the domain <em>sub.example.com</em> has two NS records: <em>ns.vulnerable.com</em> and <em>ns.nonvulnerable.com</em>. If an attacker takes over the <em>ns.vulnerable.com</em>, the situation from the perspective of the user who queries <em>sub.example.com</em> looks as follows:</p>
<ol>
<li>Since there are two nameservers, one is randomly chosen. This means the probability of querying nameserver controlled by an attacker is 50%.</li>
<li>If user's DNS resolver chooses <em>ns.nonvulnerable.com</em> (legitimate nameserver), the correct result is returned and likely being cached somewhere between 6 and 24 hours.</li>
<li>If user's DNS resolver chooses <em>ns.vulnerable.com</em> (nameserver owned by an attacker), an attacker might provide a false result which will also be cached. Since an attacker is in control of nameserver, she can set TTL for this particular result to be for example one week.</li>
</ol>
<p><strong>MX subdomain takeover.</strong> Compared to NS and CNAME subdomain takeovers, MX subdomain takeover has the lowest impact. Since MX records are used only to receive e-mails, gaining control over canonical domain name in MX record only allows an attacker to receive e-mails addressed to source domain name. Although the impact is not as significant as for CNAME or NS subdomain takeover, MX subdomain takeover might play a role in spear phishing attacks and intellectual property stealing.</p>
<h2 id="cloudproviders">Cloud Providers</h2>
<p>Cloud services are gaining popularity in recent years. One of the basic premises of the cloud is to offload its users from setting up their infrastructure. Organizations are switching from an on-premise setup to alternatives such as cloud storage, e-commerce in a cloud, and platform-as-a-service, to name a few.</p>
<p>After a user creates a new cloud service, the cloud provider in most cases generates a unique domain name which is used to access the created resource. Because registering a domain name via TLD registrar is not very convenient because of a large amount of cloud service customers, cloud providers opt to use subdomains. The subdomain identifying unique cloud resource often comes in the format of <em>name-of-customer.cloudprovider.com</em>, where <em>cloudprovider.com</em> is a base domain owned by the particular cloud provider.</p>
<p>If the cloud service registered by an organization is meant to be public (e.g., e-commerce store), the particular organization might want to have it present as part of their domain. The main reason behind this is branding: <em>shop.organization.com</em> looks better than <em>organization.ecommerceprovider.com</em>. In this case, the organization has two choices:</p>
<ul>
<li>
<p><strong>HTTP 301/302 redirect</strong> — <em>301</em> and <em>302</em> are HTTP response codes that trigger a web browser to redirect the current URL to another URL. In the context of cloud services, the first request is made to a domain name of an organization (e.g., <em>shop.organization.com</em>) and then redirect is made to a domain name of cloud providers (e.g., <em>organization.ecommerceprovider.com</em>).</p>
</li>
<li>
<p><strong>CNAME record</strong> — Using this method, the ,,redirect&quot; happens during DNS resolution. The organization sets CNAME record, and all traffic is automatically delegated to the cloud provider. Using this method, the URL in the user's browser stays the same. Note however that the particular cloud service must support delegation using CNAME records.</p>
</li>
</ul>
<p>If the CNAME record method is used, the possibility of subdomain takeovers comes into play. Even though the cloud provider owns the base domain of a canonical domain name, subdomain takeover is still possible as is presented in the next sections.</p>
<p>The providers in the subsequent sections were chosen based on three primary reasons:</p>
<ul>
<li><strong>Prevalence</strong> — Based on statistics on CNAME records, cloud providers domains with the highest usage in CNAME records were prioritized.</li>
<li><strong>Support for CNAME records</strong> — As explained above, cloud provider needs to support CNAME delegation. Cloud providers realize that customers request such behavior and the most popular cloud providers already support it.</li>
<li><strong>Domain ownership verification</strong> — The chosen cloud providers are not verifying the ownership of the source domain name. Since the owner does not need to be proven, anyone can use expired cloud configuration to realize subdomain takeover.</li>
</ul>
<h4 id="amazoncloudfront">Amazon CloudFront</h4>
<p>Amazon CloudFront is a <em>Content Delivery Network (CDN)</em> in Amazon Web Services (AWS). CDN distributes copies of web content to servers located in different geographic locations (called points of presence). When a user makes a request to CDN, the closest point of presence is chosen based on visitors location to lower the latency. CDNs are utilized by organizations, mainly to distribute media files such as video, audio, and images. Other advantages of CDNs include Denial of Service attacks protection, reduced bandwidth, and load balancing in case of high traffic spikes.</p>
<p>CloudFront uses <em>Amazon S3</em> as a primary source of web content. Amazon S3 is another service offered by AWS. It is a cloud storage service (S3 is an abbreviation for Simple Storage Service) which allows users to upload files into so-called <em>buckets</em>, which is a name for logical groups within S3.</p>
<p>CloudFront works with the notion of <em>distributions</em>. Each distribution is a link to specific Amazon S3 bucket to serve the objects (files) from. When the new CloudFront distribution is created, a unique subdomain is generated to provide access. The format of this subdomain is <em>SUBDOMAIN.cloudfront.net</em>. The <em>SUBDOMAIN</em> part is produced by CloudFront and cannot be specified by a user.</p>
<p>In addition to a randomly generated subdomain, CloudFront includes a possibility to specify an alternate domain name for accessing the distribution. This works by creating CNAME record from alternate domain name to subdomain generated by CloudFront. Although Amazon does not provide documentation about the internal CloudFront concepts, the high-level architecture can be deducted from its behavior. Based on the geographic location, DNS query to any subdomain of <em>cloudfront.net</em> leads to the same A records (in the same region). This indicates that CloudFront is using the virtual hosting setup in the backend. After the HTTP request arrives, CloudFront's edge server determines the correct distribution based on HTTP <em>Host</em> header. Documentation also supports this theory as it states: <em>,,You cannot add an alternate domain name to a CloudFront distribution if the alternate domain name already exists in another CloudFront distribution, even if your AWS account owns the other distribution&quot;&quot;</em>. Having multiple alternate domains pointing to one distribution is correct, however, having the same alternate domain name present in multiple distributions is not.</p>
<p><img src="https://0xpatrik.com/content/images/2018/06/cloudfront_vh.png" alt="Subdomain Takeover: Basics"></p>
<p>Therefore to correctly handle alternate domain names, CloudFront needs to know beforehand to which distribution the alternate domain name is attached. In other words, having CNAME record configured is not enough, the alternate domain name needs to be explicitly set in distribution settings.</p>
<p>The problem with alternate domain names in CloudFront is similar to problems explained in <em>Regular Domains</em> section. Let's assume that <em>sub.example.com</em> has a CNAME record set to <em>d1231731281.cloudfront.net</em>. When there is no <em>sub.example.com</em> registered in any CloudFront distribution as an alternate domain name, subdomain takeover is possible. Anyone can create a new distribution and set <em>sub.example.com</em> as an alternate domain name in its settings. Note that however, the newly created CloudFront subdomain does not need to match the one specified in the CNAME record (<em>d1231731281.cloudfront.net</em>). Since CloudFront uses a virtual hosting setup, the correct distribution is determined using HTTP Host header and not DNS record.</p>
<p>The picture below shows the error message that is presented after HTTP request to an alternate domain name which has the DNS CNAME record to CloudFront in place but is not registered in any CloudFront distribution.</p>
<p><img src="https://0xpatrik.com/content/images/2018/06/cloudfront_error.png" alt="Subdomain Takeover: Basics"></p>
<p>This error message is a solid indication of the possibility of subdomain takeover. Nevertheless, the two exceptions need to be taken into account:</p>
<ul>
<li><strong>HTTP / HTTPS only distributions</strong> — CloudFront allows specifying whether the distribution is HTTP-only or HTTPS-only. Switching HTTP to HTTPS might provide correct responses for some distributions.</li>
<li><strong>Disabled distribution</strong> — Some distributions might be disabled. Disabled distribution is no longer actively serving content while still preserving its settings. It means that some alternate domain name might be throwing an error message after HTTP request. However, it is even registered inside the disabled distribution and thus is not vulnerable to subdomain takeover. The correct way to determine whether an alternate domain is registered inside some distribution is to create a new distribution and set the alternate domain name. If the registration process does not throw an error, the custom domain is vulnerable to subdomain takeover. The screenshot below shows the error that is presented after the user tries to register the alternate domain name which is already present in some other CloudFront distribution.</li>
</ul>
<p><img src="https://0xpatrik.com/content/images/2018/06/5_cloudfront_error.png" alt="Subdomain Takeover: Basics"></p>
<h4 id="other">Other</h4>
<p>As presented in the case of CloudFront, subdomain takeover is possible even on cloud services which do not have its base domain available for registration. However, since cloud services provide a way of specifying alternate domain names (CNAME records), the possibility of subdomain takeover is still present. This section provides a quick overview of other cloud services which work very similarly to CloudFront (virtual hosting architecture).</p>
<ul>
<li>
<p><strong>Amazon S3</strong> — Amazon S3 was briefly mentioned in previously. The default base domain used to access the bucket is not always the same and depends on the AWS region that is used. The full list of Amazon S3 base domains is available in AWS documentation. Similarly to CloudFront, Amazon S3 allows specifying the alternate (custom) domain name to access the bucket's content.</p>
</li>
<li>
<p><strong>Heroku</strong> — Heroku is a Platform-as-a-Service provider which enables deployment of an application using simple workflow. Since access to the application is needed, Heroku exposes the application using subdomain formed on <em>herokuapp.com</em>. However, it is also possible to specify the custom domain name to access the deployed application.</p>
</li>
<li>
<p><strong>Shopify</strong> — Shopify provides a way of creating and customizing e-commerce stores in the cloud. The default subdomain to access the store is built on <em>myshopify.com</em>. As services described before, Shopify allows specifying alternate domain names. Noteworthy is that Shopify verifies correct CNAME record configuration. However, this verification is not domain ownership verification. Shopify only checks for accurate CNAME record that is present in the alternate domain's DNS zone. This verification, therefore, does not prevent subdomain takeovers.</p>
</li>
<li>
<p><strong>GitHub</strong> — GitHub is a version control repository for Git. GitHub also allows free web hosting using their <em>GitHub Pages</em> project. This web hosting is usually used for project's documentation, technical blogs, or supporting web pages to open-source projects. GitHub Pages supports custom domain name in addition to default domain name under <em>github.io</em>.</p>
</li>
<li>
<p><strong>Microsoft Azure</strong> — Microsoft Azure is a more prominent cloud provider, similar to AWS. It is different compared to the cloud services mentioned above in that it does not provide a virtual hosting architecture. Simply put, for each cloud service, Azure creates own virtual machine with own IP address. Therefore the mapping between a domain name and IP address is unambiguous (one-to-one mapping). Noteworthy is that since this is not a regular virtual hosting setup, configuring CNAME record does not necessarily have to be explicitly defined in the resource settings. Azure provides multiple cloud services but the ones discussed in this thesis have default domains of <em>cloudapp.net</em> and <em>azurewebsites.net</em>. Its documentation describes setting the link between the domain name and Azure resource using A or CNAME records (pointing to one of the two domains mentioned previously). An interesting observation is that for A records, Azure does a domain ownership verification using TXT records. However, it is not the case for a CNAME record, and subdomain takeover is, therefore, possible even in the case of Microsoft Azure.</p>
</li>
</ul>
<p>For an extended listing of affected cloud providers, I highly recommend checking <a href="https://github.com/EdOverflow/can-i-take-over-xyz">&quot;Can I take over XYZ?&quot;</a> guide.</p>
<h2 id="internetwidescan">Internet-wide Scan</h2>
<p><a href="https://0xpatrik.com/project-sonar-guide/">Project Sonar</a> can be used to show the prevalence of subdomain takeover across the Internet. Because Project Sonar already contains resolved CNAME records, it is pretty straightforward to automate scanning for subdomain takeover across the Internet. This section explains its results.</p>
<p><strong>Chain of CNAME records</strong>. In some instances, CNAME records might form CNAME record chains. Let's have the domain <em>sub.example.com</em> which has a CNAME record to <em>sub.example1.com</em>. If in turn, <em>sub.example1.com</em> has a CNAME record to <em>sub.example2.com</em> a three-way chain is formed:</p>
<p><code>sub.example.com -&gt; sub.example1.com -&gt; sub.example2.com</code></p>
<p>In such cases, when the base domain of last domain in the chain (<em>example2.com</em>) is available for registration both <em>sub.example1.com</em> and <em>sub.example.com</em> are affected. Fortunately, Project Sonar implicitly contains all CNAME references in the chain. For a chain given above, even though there is no direct CNAME record from <em>sub.example.com</em> to <em>sub.example2.com</em>, Project Sonar contains this record. Therefore, no direct changes need to be made to the automation tool to support CNAME record chains in Project Sonar.</p>
<p>The scanning was performed using a custom automation tool which I don't plan to release yet. The tool was able to scan cloud provider domains and found <strong>12,888</strong> source domain names vulnerable to subdomain takeover (November 2017). The cloud provider distribution follows:</p>
<p><img src="https://0xpatrik.com/content/images/2018/06/takeover_distribution.png" alt="Subdomain Takeover: Basics"></p>
<p><em>Some parts of this post are excerpts from my <a href="https://is.muni.cz/th/byrdn/Thesis.pdf">Master's Thesis</a></em>.</p>
<p>Check out my other posts about subdomain takeovers:</p>
<ul>
<li><a href="https://0xpatrik.com/subdomain-takeover/">Subdomain Takeover: Thoughts on Risks</a></li>
<li><a href="https://0xpatrik.com/subdomain-takeover-ns/">Subdomain Takeover: Going beyond CNAME</a></li>
<li><a href="https://0xpatrik.com/takeover-proofs/">Subdomain Takeover: Proof Creation for Bug Bounties</a></li>
<li><a href="https://0xpatrik.com/subdomain-takeover-candidates/">Subdomain Takeover: Finding Candidates</a></li>
</ul>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Takeover: Basics" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Subdomain Takeover: Starbucks points to Azure]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>This post is the write-up about <a href="https://hackerone.com/reports/325336">bug bounty report</a> that I reported back in March 2018 to Starbucks. The report is now disclosed, and I was awarded $2,000 bounty. Although I have written about subdomain takeover in <a href="https://0xpatrik.com/subdomain-takeover/">multiple</a> <a href="https://0xpatrik.com/takeover-proofs/">posts</a>, this case was somehow different.</p>
<p><img src="https://0xpatrik.com/content/images/2018/06/report_header.png" alt="HackerOne Report"></p>
<p>The domain in question was</p>]]></description><link>https://0xpatrik.com/subdomain-takeover-starbucks/</link><guid isPermaLink="false">5dd051c7140a9354e2f01633</guid><dc:creator><![CDATA[Patrik Hudak]]></dc:creator><pubDate>Mon, 25 Jun 2018 22:07:01 GMT</pubDate><media:content url="https://0xpatrik.com/content/images/2018/06/starbucks.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://0xpatrik.com/content/images/2018/06/starbucks.jpg" alt="Subdomain Takeover: Starbucks points to Azure"><p>This post is the write-up about <a href="https://hackerone.com/reports/325336">bug bounty report</a> that I reported back in March 2018 to Starbucks. The report is now disclosed, and I was awarded $2,000 bounty. Although I have written about subdomain takeover in <a href="https://0xpatrik.com/subdomain-takeover/">multiple</a> <a href="https://0xpatrik.com/takeover-proofs/">posts</a>, this case was somehow different.</p>
<p><img src="https://0xpatrik.com/content/images/2018/06/report_header.png" alt="Subdomain Takeover: Starbucks points to Azure"></p>
<p>The domain in question was <code>svcgatewayus.starbucks.com</code>. The domain pointed to a non-existing resource in <a href="https://azure.microsoft.com">Microsoft Azure</a>. I realized that I have never talked about Microsoft Azure as a potential vector for subdomain takeover.</p>
<p>Firstly, Azure provides multiple services. I look for two primary services:</p>
<ul>
<li>Azure Websites — <strong>.azurewebsites.net</strong></li>
<li>Cloud Apps — <strong>.cloudapp.net</strong></li>
</ul>
<p>The most significant difference compared to CloudFront and other similar services are, that Azure provides dedicated IP address to both of these services. The provided subdomain that points to it using A record. In other words, Azure doesn't utilize virtual hosts setup (as I described <a href="http://blog.sweepatic.com/subdomain-takeover-principles/">previously</a>). This means that for potential subdomain takeover, you only need to look for DNS status being <code>NXDOMAIN</code>.</p>
<p>There are lots of misconceptions about when the subdomain takeover for Azure is possible. I recommend running a simple <code>dig</code> command:</p>
<pre><code>dig -t A DOMAIN_TO_CHECK
</code></pre>
<p>Is the response status <code>NXDOMAIN</code>? If yes, great, the takeover might be possible. Note that receiving 404 HTTP error does not mean the subdomain takeover is possible at all! As I said before, the services have dedicated VPS. For successful subdomain takeover, DNS request should always return <code>NXDOMAIN</code>.</p>
<p>The subdomain in the report pointed to <code>1fd05821-7501-40de-9e44-17235e7ab48b.cloudapp.net</code>. I needed to create a PoC which was a little bit tricky. The rough guideline of how I did it follows:</p>
<ol>
<li>Created a new Cloud Service in the <a href="https://portal.azure.com/#create/Microsoft.CloudService">portal</a>. It asks for a custom domain name. <em>Remember: This domain name needs to match since you are not dealing with virtual host anymore. You can confirm this theory by noticing that Cloud Service never asks for a domain name which you will use for CNAME</em>.</li>
<li>Created a Storage Account for the Cloud Service in the Azure portal.</li>
<li>Azure requires a specific format for deployment of Cloud Services which is generated by Visual Studio. I created a simple ASP.NET web application and uploaded it to this Cloud Service using <a href="https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-how-to-create-deploy-portal">this</a> tutorial.</li>
<li>Because of DNS, the A record for <code>svcgatewayus.starbucks.com</code> is pointing to Azure, and so the HTTP request returns the content from the ASP.NET application I just deployed.</li>
</ol>
<p>For Azure Websites, the process is much more straightforward and looks closer to traditional PaaS. To create PoC for Azure Websites, I recommend the following <a href="https://docs.microsoft.com/en-us/azure/app-service/app-service-web-get-started-python">this</a> tutorial. I tested that, and it works correctly.</p>
<p>I have to say that I find the Azure portal very messy. IMHO it is a lot more complex than AWS with no significant benefits.</p>
<p>Azure offers several other services with a different structure, subdomains, and PoC process that I will cover in one of the future posts. Follow me on <a href="https://twitter.com/0xpatrik">Twitter</a> to get it first.</p>
<p>Until next time!</p>
<p><a href="https://twitter.com/0xpatrik">Patrik</a><br>
<a href="https://twitter.com/0xpatrik?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-show-count="false">Follow @0xpatrik</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<p><a href="http://buymeacoff.ee/0xpatrik" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Subdomain Takeover: Starbucks points to Azure" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"></a></p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>