punk-security / dnsReaper

dnsReaper - subdomain takeover tool for attackers, bug bounty hunters and the blue team!
GNU Affero General Public License v3.0
2.03k stars 167 forks source link

A Record Scanning #166

Open Apipia opened 1 year ago

Apipia commented 1 year ago

Currently my team is using this tool to check for subdomain takeovers. We are running it every morning. You can imagine my disappointment when our BugBounty program received some subdomain takeover submissions while the scanner showed no findings. I was able to confirm that the finding was legitimate and that dnsReaper did iterate over the DNS record.

The issue was that the record was an A Record, rather than a CNAME record. the A Record had an IP address that pointed to Azure's public IP space. I was able to design my own script to do this A Record scanning but was curious if it could be built into dnsReaper. I'm not quite sure how to include it/contribute.

My script filters the DNS records to Azure-IP Address records only using this endpoint: https://www.azurespeed.com/api/ipinfo?ipAddressOrUrl=IP-ADDR

Then compares that to a dump of public ip addresses from Azure. This part does require an App Service in azure and requires AZURE_CLIENT_ID, AZURE_TENANT_ID, and AZURE_CLIENT_SECRET environment variables to be set in order to work. The dump is grabbed using the ResourceGraphClient installed with pip: azure-mgmt-resourcegraph as well as SubscriptionClient installed with pip: azure-mgmt-subscription . It works like this:

      query = "resources | where type contains 'publicIPAddresses' and isnotempty(properties.ipAddress) | project properties.ipAddress"
      subs_list = [s.subscription_id for s in self.subscription_client.subscriptions.list()]
      # Azure Resource Graph API
      results = arg.resources(QueryRequest(
          subscriptions=subs_list,
          query=query
      ))
      return results

Can I request that this feature be added to dnsReaper so A records can be checked against Azure? I could try to do the contribution myself but I was really unsure how to fit this into the current scheme.

Thanks!

SimonGurney commented 1 year ago

Hi @Apipia.

Thanks for raising the issue, and for the detail you put in. I really like your solution.

We can look to include this, including similar support for aws ec2 IP space.

Pointing to the wrong IP / a disused IP is slightly tricky to get a solid detection on, which is why we haven't done it so far.

What is your thought on detecting the take over, just that the IP does not respond on port 80 and 443?

We will raise a lot of false positives for records pointing to azure IPs that don't serve web servers on standard ports or which are firewalled, but we could I guess have it so you have to enable this check with an opt-in flag.

Is there a better signature for an unallocated IP, something like a standard traceroute path or some standard ICMP response?

Apipia commented 1 year ago

Honestly, that's the big issue. The reason it works for our team is because I'm keeping the scope on Azure public IP addresses and I'm able to dump a list of all of the public IP addresses used in our organization from azure, then just do a diff.

I suppose it could be added to the tool this way if there were additional command line arguments or required environment variables added for an azure app registration to authenticate to azure. Then the code could pull the public ip addresses down from azure and compare them to the DNS records (code sample for this provided above). The only caveat is that you need to make sure your app registration has global read permissions or you'll get a lot of false positives. But just trying to determine if an Azure IP address is in use with no other context? Not sure how to do that.

If using an azure app registration is outside the scope of this project, I'd completely understand. I would just continue running dnsReaper alongside my own script.

ebarped commented 1 month ago

Hi!

Just to inform, we detected the same scenario, but with AWS IP adress space.

As you state, there is not a perfect way of handling this case... (check ICMP, ports 80/443... there is no perfect solution)

Maybe we can add this check in the pool of the signatures executed when you use the --enable-unlikely flag?