Andrew Katz

Building my own Nuclei scanning infrastructure

July 18, 2025

Project Discovery’s Nuclei is my favorite vulnerability/misconfiguration scanning tool.

It is fast, open source, extremely flexible, surfaces high-fidelity findings, and has a large community of contributors that are constantly publishing templates for the most important vulns that are being exploited today. I think a lot of people on the defensive side of the house tend to sleep on Nuclei as its traditionally been seen as only an offensive tool. If you are a security person, and you are not using Nuclei to scan your infrastructure, I would recommend giving it a look.

All that aside, I have always wanted to have some kind of orchestration around it that not only includes some scheduling features, but also bolts on other tools into the scans, such as Trufflehog (secrets scanning), Subfinder (subdomain enumeration), and Katana (URL spidering).

So, I built my own Nuclei scanning web app called Scanny.

Disclaimer: this is not a commercial product, but rather a personal throwaway project that I built to scratch my own itch. You can use this software however you want, but I will not provide any support/maintenance for it nor do I recommend using it in production or to propel yourself into a life of crime (and whatever else the LICENSE file says on GitHub). I also don’t claim to be an “offensive security person”. I just like to build cool shit.

Scanny

The core of Scanny allows you to add domains, schedule Nuclei scans, and view the results.

Separately from the main app, Scanny needs one or more worker nodes that have containers that run the actual scans. Workers can be scaled horizontally with docker compose up -d --scale worker=<number> --build. The most I have ever scaled to was 22 for this post, and it was glorious.

Within the web app, you can also see the status of workers, the number of scans they are running, and the results of those scans.

Given that the traffic that Scanny generates for its scans looks very suspicious, I don’t recommend running it without using some kind of VPN, VPS, or have some other anonymizing measures in place around each worker node. That way you don’t get put into some blacklisted reputation database and have your IP address blocked by various services.

What’s in a scan?

Here is the most fully-featured scan that Scanny can run:

  1. You configure the domain you want to scan in the web app. If the domain doesn’t resolve to an IP address, you can force Scanny to add it if you need to.
  2. Your domain is added to the Domain & Scan Configuration area. Each domain has a unique X-Scanny-ID header that gets sent by Scanny when using scanning tools (for bypassing WAF).
  3. Then you can configure the scan/interval itself: You can choose the frequency, severities, secrets scanning, and a bunch of other cool features.
  4. We will select everything, and then you can see the scan interval configured in the app.
  5. As soon as the scan interval is configured, one of our worker containers will pick up the scan from the database and start running it.
  6. First, the worker will run a quick port scan and banner grab against the domain. The banner grab will show up in the scan results.
  7. Next, the worker will run a Nuclei scan as configured in the scan interval. The results will show up in the scan results as well.
  8. If you have secrets scanning enabled, the worker will run Katana against the domain. This is another ProjectDiscovery tool that is used to spider a domain and find URLs. For each URL found, the worker will use httpx to download the content of that URL and then run a Trufflehog “filesystem” scan against that content. This just means it is running a secrets scan against that file - nothing too crazy. Any discovered secret results will also show up in the scan results as critical findings.
  9. Once the scan is complete, the worker will publish the results to the Scanny web app, as well as send a webhook or Pushover notification for any High or Critical severity vulns if you have either one of those configured.
  10. If you have subdomain enumeration enabled, the worker will run Subfinder against the domain and add identical scans for each one of those subdomains. This is useful for finding additional vulnerabilities that may not be present on the main domain, but are present on the subdomains of that domain.
  11. The secret results show up at the bottom of the web app and show the count and severity of found vulns as well as open ports.
  12. When you expand the results, you can see the banner grab information as well as the Nuclei and secret scanning results.
  13. We can see that Scanny automatically added the subdomains that were found by Subfinder.

I think the biggest advantages of Scanny are that it can do subdomain enumeration for you and be run on a schedule, although the other features are pretty powerful too.

Broadly scanning AWS

In my experimentation with Scanny, by far the best way to put it through its paces is to run subdomain-crawling scans against AWS’ regional public domain names for EC2, Elastic Beanstalk, S3, etc.

This way, you are usually(?) not scanning services that are behind a WAF. You’re just directly hitting the origin server, so it is easier to run all the test cases of the templates in general.

To give you an idea of what may appear on any random day, let’s just try scanning us-west-1.compute.amazonaws.com and us-east-1.compute.amazonaws.com which should give us some scans against public EC2 instances in the us-west-1 and us-east-1 AWS regions.

As the initial scan completes, scanners ramp up to grab some of the 2000 or so EC2 public DNS names that were found by Subfinder.

Sidenote: I only have 22 workers running in parallel for this scan. How crazy would it be if I got a beefy VPS where I could run 100+ workers in parallel?

Pretty quickly, we found a medium severity vuln. It is CVE-2023-48795/vulnerable to SSH Terrapin attack. You can click a button to get the current EPSS score for any CVE. I added this feature because I am a huge fan of EPSS and actually focusing on CVEs that matter.

Here are our vulnerability finding results after letting it run for the entire night:

Some of the results that stood out to me were:

  • .env file disclosure - developers often leave environment files with sensitive information exposed to the public internet. This is a common and can be a pretty bad misconfiguration mistake that can lead to credential leaks.
  • Strikingly Takeover Detection - a Strinkingly site is configured in a way where an attacker can takeover a subdomain.
  • qdPM 9.2 - Directory Traversal - attacker can read arbitrary files in the /upload directory.

Takeaways

  • Building this project was a fun way to learn more about Nuclei and how to use it effectively. I learned how to tune Nuclei scans, limit memory usage, and how to pair Nuclei with other Project Discovery tools.
  • Nuclei’s community is amazing and there are so many templates that you can use to scan for vulnerabilities.
  • Building things for fun and getting rid of them instantly should be encouraged.

An alternative approach

Depending on how many assets you need to scan, I would actually recommend running Nuclei and Subfinder within GitHub Actions if you have self-hosted runners.

Check out this repo for an example of how to do this: ackatz/nuclei-subfinder-github-actions-example

Thanks for reading!