You do not need a paid attack surface management platform to catch the obvious mistakes. In a fast-moving information system, public exposure changes all the time. New subdomains appear, temporary services stay online longer than expected, demo applications become production dependencies, and with the rise of vibe coding it is even easier to ship something quickly and forget the boring security cleanup.

That is why I like having a simple blackbox monitoring loop on the public perimeter. Not because it replaces a pentest. It does not. But because it catches low-hanging fruits before they become embarrassing: forgotten admin panels, exposed Swagger documentation, database banners, directory listing, debug pages, or old test applications still reachable from the internet.

Subdomain Analysis Toolkit is my small open-source toolbox for that use case. It is not an ASM platform and it will not do miracles. It is a cheap safety net that you can run once, then automate if it proves useful.

This article focuses on the main workflow: discover subdomains, scan them with Nuclei, read the report, and schedule the loop. The repository contains more helper scripts, but the goal here is to bootstrap something useful fast.

1. The Basic Idea

The workflow is intentionally simple:

targets.txt -> subdomains.sh -> targets.latest.txt -> nuclei.sh -> report.2026-Week16.txt

targets.txt contains the root domains you are allowed to test. subdomains.sh collects and consolidates subdomains. nuclei.sh scans the resulting list by severity and protocol. The output is a weekly report that can be archived, compared, or plugged into your own internal alerting.

The important part is not only finding subdomains. The useful part is repeating the scan over time and noticing what changed.

2. 10-Minute Bootstrap

Assuming you already have Go available, clone the project and install only what is needed for this first loop: subfinder and amass for discovery, then nuclei for the scan. curl is also used by nuclei.sh to check the current outbound IP, but it is usually already installed on Linux servers.

$ git clone https://github.com/nbeguier/SubdomainAnalysisToolkit.git $ cd SubdomainAnalysisToolkit $ go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest $ go install -v github.com/owasp-amass/amass/v3/...@master $ go install -v github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest

The other Python and Go dependencies are useful for the rest of the toolbox: stats, CSV exports, provider mapping, Wayback URLs, public bucket checks, or TCP exposure checks. You do not need them to validate the main idea.

Create your local configuration and a small target file. Only scan domains you own or have explicit permission to test.

$ cp settings.sample.py settings.py $ echo "beguier.eu" > targets.txt

Now generate the subdomain list and run the Nuclei scan. For a first manual run, keep the colored output in your terminal:

$ bash subdomains.sh $ bash nuclei.sh

If you want to archive the run as a clean weekly report, use the no-color output variant:

$ bash nuclei.sh --no-color > "report.$(date +%G-Week%V).txt"

At this point you already have the two files that matter most for a first run: the latest known public targets and the current scan report.

3. Reading the Target List

The consolidated list is stored in targets.latest.txt. For example:

$ cat targets.latest.txt
beguier.eu
secret.beguier.eu
www.beguier.eu

In a real perimeter, this file quickly becomes your blackbox inventory. It will not replace your CMDB, cloud inventory, DNS management, or asset ownership data. It gives you a simple outside view: what can an external observer discover and try to reach?

4. Why Nuclei Is Split by Severity and Protocol

nuclei.sh does not launch everything as one big opaque scan. It loops over severities and protocols. This keeps the scan easier to follow, limits the impact of heavy template categories, and gives you progress visibility while the run is still active.

$ more report.2026-Week16.txt
[*] Checking SOCKS5 proxy at socks5://127.0.0.1:9050...
[-] SOCKS5 proxy not detected. Proceeding without proxy.
[+] Current IP without proxy: 10.0.0.1
[*] Updating HTTPx, DNSx, Nuclei and templates...
[*] Starting Nuclei scans on 1050 targets...
[*] Severity: critical
    [*] Protocol: dns
    [+] Found 2 templates for severity: critical and protocol: dns
    [*] Protocol: file
    [+] Found 5 templates for severity: critical and protocol: file
    [*] Protocol: http
    [+] Found 1618 templates for severity: critical and protocol: http
    [*] Protocol: headless
    [+] Found 3 templates for severity: critical and protocol: headless
    [*] Protocol: tcp
    [+] Found 31 templates for severity: critical and protocol: tcp
    [*] Protocol: workflow
    [+] Found 2 templates for severity: critical and protocol: workflow
[*] Severity: high
    [*] Protocol: http
    [+] Found 2267 templates for severity: high and protocol: http
[CVE-2025-4123:open-redirect] [http] [high] https://secret.beguier.eu/grafana/..%2F%5coast.pro%2F%3f%2F..%2F..
[symfony-debug] [http] [high] https://www.beguier.eu
[...]

During a run, Nuclei exposes runtime metrics on port 9092:

$ curl localhost:9092/metrics; echo ""
{"matched":0,"total":4024467,"templates":1605,"summary":"[0:00:04] | Templates: 1605 | Hosts: 1251 | RPS: 182 | Matched: 0 | Errors: 384 | Requests: 790/4024467 (0%)\n","duration":"0:00:04","rps":"182","requests":790,"errors":384,"startedAt":"2026-05-03T08:24:57.631716231Z","hosts":1251,"percent":"0"}

5. What I Triage First

The first pass is obvious: critical, high, and medium findings. But do not ignore all low or info templates blindly. Some of them are low from a generic scanner perspective but very interesting in a real company context.

If I have limited time, I usually start with high signal findings such as:

Nuclei has a lot of templates. That is a strength, but it also means you must tune your review process. The goal is not to worship scanner severity. The goal is to find things that should not be public.

6. Run It Continuously with systemd

For a one-shot test, the commands above are enough. In a company environment, I prefer turning it into a recurring monitoring loop. The public repository gives the scanning toolbox; your environment can add storage, ownership mapping, ticketing, Slack alerts, or whatever matches your constraints.

On Linux, a simple pattern is to refresh subdomains every day, then run Nuclei once a week.

Subdomain discovery service

# /etc/systemd/system/subdomains.service
[Unit]
Description=Subdomain Analysis Toolkit - Daily run

[Service]
Type=oneshot
WorkingDirectory=/opt/SubdomainAnalysisToolkit
ExecStart=/bin/bash /opt/SubdomainAnalysisToolkit/subdomains.sh
# /etc/systemd/system/subdomains.timer
[Unit]
Description=Run Subdomain Analysis Toolkit every day at 23:00

[Timer]
OnCalendar=*-*-* 23:00:00
Persistent=true

[Install]
WantedBy=timers.target

Nuclei scan service

# /etc/systemd/system/nuclei.service
[Unit]
Description=Nuclei scan - daily run

[Service]
Type=oneshot
User=root
WorkingDirectory=/opt/SubdomainAnalysisToolkit
Environment=HOME=/root
Environment=XDG_CONFIG_HOME=/root/.config
Environment=XDG_CACHE_HOME=/root/.cache
ExecStart=/bin/bash -c '/bin/bash nuclei.sh --no-color > report.$(date +%%G-Week%%V).txt'
# /etc/systemd/system/nuclei.timer
[Unit]
Description=Run Nuclei scan every Monday at 00:00

[Timer]
OnCalendar=Mon *-*-* 00:00:00
Persistent=true

[Install]
WantedBy=timers.target
$ systemctl daemon-reload $ systemctl enable --now subdomains.timer nuclei.timer $ systemctl list-timers subdomains.timer nuclei.timer $ journalctl -x -u subdomains.service -f $ journalctl -x -u nuclei.service -f

7. Limits

This is not a replacement for a pentest. It does not test business logic, authenticated workflows, chained vulnerabilities, or architecture decisions. It is also not a full external attack surface management platform.

It is a small blackbox control that costs almost nothing and catches obvious mistakes. If it finds nothing, good. If it finds a forgotten panel, an exposed debug endpoint, a database banner, or a public Swagger file, it already paid for itself.

Conclusion

The public perimeter is your storefront. In a system that constantly changes, you need at least a cheap way to notice when something new becomes visible from the outside.

Start small: one target file, one subdomain discovery run, one Nuclei report. Then automate it if the signal is useful.

The project is available on GitHub: Subdomain Analysis Toolkit.