Metadata-Version: 2.4
Name: subpulse
Version: 0.1.0
Summary: High-Performance Asynchronous DNS Resolver & Subdomain Takeover Auditor
Home-page: https://github.com/dhruvrathod68/SubPulse-CLI
Author: Dhruv Rathod
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: System :: Networking :: Monitoring
Classifier: Environment :: Console
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiodns==3.2.0
Requires-Dist: pycares==4.11.0
Requires-Dist: dnspython==2.6.1
Requires-Dist: colorama==0.4.6
Requires-Dist: python-dotenv==1.0.1
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# SubPulse-CLI (subpulse)

[![PyPI Version](https://img.shields.io/pypi/v/subpulse.svg)](https://pypi.org/project/subpulse/)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Layer 7 Concurrency](https://img.shields.io/badge/concurrency-asyncio%20%7C%20aiodns-brightgreen.svg)](https://docs.python.org/3/library/asyncio.html)
[![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20Windows%20%7C%20macOS-lightgrey.svg)](https://github.com/dhruvrathod68/SubPulse-CLI)

**SubPulse-CLI** is a high-throughput, non-blocking DNS resolution engine and infrastructure health auditor engineered in Python. It evaluates organizational domain perimeters, discovers active subdomains, isolates wildcard DNS zones, and identifies dangling CNAME takeover vulnerabilities without thread-pool overhead.

---

## 🎯 Primary Use Cases

* **External Attack Surface Management:** Rapidly discover active subdomains, forgotten staging environments, and shadow-IT infrastructure across corporate root domains.
* **Subdomain Takeover Auditing:** Detect dangling CNAME records pointing to decommissioned or unclaimed third-party cloud assets (AWS S3, GitHub Pages, Heroku, Azure, CloudFront).
* **Wildcard DNS Suppression:** Identify wildcard DNS configurations upfront using high-entropy probes, filtering out false-positive resolution storms.
* **CI/CD & DevSecOps Perimeter Checks:** Run lightweight DNS health audits inside automated security testing pipelines to detect domain misconfigurations.

---

## 🏛️ Architectural Overview

Traditional DNS enumeration utilities rely on synchronous OS resolver calls (`socket.getaddrinfo()` / `gethostbyname()`) wrapped in heavy thread pools. When querying thousands of potential subdomains, thread context-switching overhead and OS blocking timeouts degrade throughput.

**SubPulse-CLI** bypasses this limitation using asynchronous socket multiplexing powered by `aiodns` and `c-ares`.

```text
               [CLI Entrypoint: subpulse <target>]
                               │
                               ▼
                  [Wordlist & Resolver Loader] <── (Embedded Defaults or Custom Wordlist)
                               │
                               ▼
                   [Wildcard Pre-flight Probe] <── (High-Entropy Random Subdomain)
                               │
                               ▼
                  [Async Event Loop Initiated]
                               │
                ┌──────────────┼──────────────┐
                ▼              ▼              ▼
          [Worker Task]  [Worker Task]  [Worker Task] <── Managed concurrently via aiodns & Semaphore
                │              │              │
                └──────────────┼──────────────┘
                               ▼
                 [Takeover Heuristics & Resolver]
                               │
                ┌──────────────┴──────────────┐
                ▼                             ▼
        [Colorama ANSI UI]            [RFC JSON Report]
```

### Key Technical Advantages

- **Non-Blocking C-Ares Event Multiplexing**: Leverages asynchronous UDP/TCP DNS sockets, enabling thousands of concurrent queries on a single Python thread.
- **Entropy-Based Wildcard Suppression**: Pre-scans domains with randomized probe records to identify wildcard catch-all configurations and isolate responder IP addresses.
- **Dangling CNAME Takeover Heuristics**: Matches canonical records against 16+ cloud vendor signatures and validates secondary resolution to catch orphaned pointer states (`NXDOMAIN`).
- **Socket Saturation Control**: Gated with `asyncio.Semaphore` to prevent OS file descriptor exhaustion while maximizing network throughput.

---

## 🚀 Installation & Setup

### Option A: Global System Installation via PyPI (Recommended)

Install `subpulse` directly from PyPI into an isolated global environment:

```bash
# Using pipx (Recommended for isolated CLI binaries)
pipx install subpulse

# Or using standard pip
pip install subpulse
```

### Option B: Local Virtual Environment from Source

```bash
# 1. Clone the repository
git clone https://github.com/dhruvrathod68/SubPulse-CLI.git
cd SubPulse-CLI

# 2. Create and activate a virtual environment
# On Linux / macOS / Kali:
python3 -m venv venv
source venv/bin/activate

# On Windows PowerShell:
python -m venv venv
.\venv\Scripts\Activate.ps1

# 3. Install in editable mode
pip install -e .
```

---

## 🔄 Updating SubPulse-CLI

To update your globally installed version to the latest release:

```bash
# If installed via pipx
pipx upgrade subpulse

# If installed via pip
pip install --upgrade subpulse

# If cloned from Git source
git pull origin main
pip install -e .
```

---

## 💻 Usage & Command Reference

```text
usage: subpulse [-h] [-t TARGET_OPT] [-w WORDLIST] [-r RESOLVERS] [-c CONCURRENCY] [--timeout TIMEOUT] [-o OUTPUT] [TARGET]

positional arguments:
  TARGET                Target base domain to enumerate (e.g. github.com, example.com).

options:
  -h, --help            Show this help message and exit.
  -t, --target          Target base domain (flag format).
  -w, --wordlist        Path to custom subdomain prefix wordlist file.
  -r, --resolvers       Comma-separated custom DNS resolvers (e.g. 1.1.1.1,8.8.8.8).
  -c, --concurrency     Maximum concurrent asynchronous DNS queries (default: 50).
  --timeout             Query timeout in seconds per DNS request (default: 2.0).
  -o, --output          File path to export structured JSON telemetry report.
```

### Example Commands

```bash
# 1. Basic Subdomain Enumeration (Default Wordlist)
subpulse github.com

# 2. Custom Wordlist with Specific Upstream Resolvers & Concurrency
subpulse target.com -w custom_subs.txt -r 1.1.1.1,8.8.8.8 -c 100

# 3. Comprehensive Audit with JSON Telemetry Export
subpulse target.com -c 40 --timeout 1.5 -o scan_report.json
```

---

## 🛠️ Customizing & Extending Wordlists

You can supply custom subdomain lists without altering Python source code. By default, SubPulse-CLI ships with 50 high-value standard infrastructure prefixes (`api`, `dev`, `staging`, `admin`, `vpn`, `auth`, `portal`, `cloud`, etc.).

### Adding Custom Subdomain Wordlists

Create a plain-text file (e.g., `custom_subdomains.txt`) with one prefix per line:

```text
api-internal
k8s-node01
auth-stage
vault-cluster
gateway-proxy
```

Execute your audit with your custom list:

```bash
subpulse target.com -w custom_subdomains.txt
```

---

## 📊 Telemetry Output Schema

When `-o` or `--output` is supplied, SubPulse-CLI exports a structured JSON report:

```json
{
  "target": "github.com",
  "timestamp_utc": "2026-08-31T12:00:00Z",
  "duration_seconds": 0.045,
  "wildcard_detected": false,
  "wildcard_ips": [],
  "summary": {
    "total_queried": 50,
    "resolved": 12,
    "takeover_candidates": 0
  },
  "results": [
    {
      "fqdn": "api.github.com",
      "status": "RESOLVED",
      "records": [
        "20.207.73.85"
      ],
      "cname": null,
      "is_wildcard": false,
      "takeover_risk": false,
      "takeover_service": null,
      "latency_ms": 5.52,
      "error": null
    },
    {
      "fqdn": "remote.github.com",
      "status": "RESOLVED",
      "records": [],
      "cname": "remote.github.net",
      "is_wildcard": false,
      "takeover_risk": false,
      "takeover_service": null,
      "latency_ms": 5.44,
      "error": null
    }
  ]
}
```

### Telemetry Field Definitions

| Field | Type | Description |
| :--- | :--- | :--- |
| `target` | `string` | Base domain audited during enumeration. |
| `timestamp_utc` | `string (ISO-8601)` | Audit initiation timestamp in UTC. |
| `duration_seconds` | `float` | Total wall-clock time consumed by the DNS worker pool. |
| `wildcard_detected` | `boolean` | True if pre-flight entropy probe resolved to wildcard records. |
| `wildcard_ips` | `array of strings` | Set of IP addresses returned by wildcard responses. |
| `summary` | `object` | Aggregate counts (`total_queried`, `resolved`, `takeover_candidates`). |
| `results[].fqdn` | `string` | Fully Qualified Domain Name tested. |
| `results[].status` | `string` | Query status (`RESOLVED`, `NXDOMAIN`, `TIMEOUT`, `ERROR`). |
| `results[].records` | `array of strings` | Resolved 'A' or 'AAAA' record IP addresses. |
| `results[].cname` | `string / null` | Canonical Name alias target if present. |
| `results[].is_wildcard` | `boolean` | True if resolved IPs match the wildcard suppression set. |
| `results[].takeover_risk` | `boolean` | True if CNAME points to an unclaimed/orphaned cloud service. |
| `results[].takeover_service` | `string / null` | Identified cloud vendor signature (e.g. "GitHub Pages"). |
| `results[].latency_ms` | `float` | Round-trip DNS query time in milliseconds. |
| `results[].error` | `string / null` | Resolver error code if query failed. |

---

## 📂 Project Directory Structure

```text
SubPulse-CLI/
├── wordlists/
│   └── subdomains_default.txt       # Standard Subdomain Discovery Wordlist
├── venv/                            # Python Virtual Environment (git-ignored)
├── .gitignore                       # Repository Exclusion Rules
├── LICENSE                          # MIT License (2026 Dhruv Rathod)
├── MANIFEST.in                      # Source Distribution Packaging Manifest
├── main.py                          # Core Asynchronous DNS Engine & Orchestrator
├── requirements.txt                 # Pinned Dependencies Manifest
├── setup.py                         # Setuptools Packaging Manifest & Console Scripts
└── README.md                        # Enterprise Open-Source Documentation
```

---

## 🗺️ Roadmap & Upcoming Features

- **Multitype Record Sweeping**: Concurrent auditing of MX, TXT, AAAA, and SRV records per subdomain.
- **AXFR Zone Transfer Auditing**: Automated detection of open DNS zone transfer misconfigurations on authoritative nameservers.
- **Certificate Transparency (CT) Stream Ingestion**: Passive real-time subdomain discovery via crt.sh log streaming.
- **Multi-Format Reporting**: Native export to CSV, Markdown summary tables, and SARIF formats.

---

## 🤝 Contributing & Issue Reporting

Contributions, bug reports, and cloud takeover signature additions are welcome!

### Reporting Issues
If you encounter false classifications, resolver exceptions, or socket leaks, please open an issue on the [GitHub Issue Tracker](https://github.com/dhruvrathod68/SubPulse-CLI/issues).

### Submitting Pull Requests
1. Fork the repository.
2. Create a feature branch (`git checkout -b feature/AddCloudSignatures`).
3. Commit your changes with clear messages (`git commit -m 'feat: add S3 bucket takeover heuristic'`).
4. Push to your branch (`git push origin feature/AddCloudSignatures`).
5. Open a Pull Request detailing your modifications.

---

## ⚖️ License & Attribution

Distributed under the **MIT License**. See [`LICENSE`](LICENSE) for full details.

- **Author**: Dhruv Rathod
- **Year**: 2026
