Skip to content

Instantly share code, notes, and snippets.

@0x3n0
Last active August 12, 2025 23:33
Show Gist options
  • Select an option

  • Save 0x3n0/1121226debbf0978ca12dbce46746539 to your computer and use it in GitHub Desktop.

Select an option

Save 0x3n0/1121226debbf0978ca12dbce46746539 to your computer and use it in GitHub Desktop.

GitHub Actions: Recon & Takeover

🎯 Goal

This workflow performs automated recon and subdomain takeover checks every time there's a push to the main branch. All results are stored in the results/ directory and automatically committed back to the repo.


πŸ§ͺ Trigger

  • Runs on: ubuntu-latest
  • Trigger: push to the main branch

🧰 Toolchain (Installed via go install)

  • subfinder – Passive subdomain enumeration
  • assetfinder – Subdomain finder by TomNomNom
  • httpx – Probe for live hosts + HTTP metadata
  • dnsx – DNS resolver for A/CNAME records
  • subzy – Subdomain takeover detection
  • nuclei – Vulnerability scanner using templates
  • qsreplace, gau, dig, etc.

πŸ” Workflow Summary

For each domain defined in the ${{ secrets.DOMAIN }} (multiline secret):

1. Subdomain Enumeration

subfinder + assetfinder
β†’ results/${TARGET}-subdomains.txt

2. Live Host Discovery

httpx with multiple ports (80,443,8080, etc.)
β†’ results/${TARGET}-live.txt

3. Filter HTTPX SUCCESS Only

awk 'SUCCESS' from httpx output
β†’ results/${TARGET}-httpx-success.txt

4. DNS Resolution via DNSX

dnsx -a -cname -resp
β†’ results/${TARGET}-resolved.txt

5. Detect Dangling CNAMEs

if dig returns empty for CNAME
β†’ results/${TARGET}-dangling-cname.txt

6. Subdomain Takeover Scan (via subzy)

  • Run subzy on:

    • Full subdomain list
    • DNS-resolved hostnames
β†’ results/subzy-takeover-${TARGET}.json  
β†’ results/dnsx-takeover-${TARGET}.json

7. Run Nuclei on Valid HTTPX Hosts

nuclei -l httpx-success.txt
β†’ results/nuclei-${TARGET}.txt

πŸ” Required GitHub Secrets

Secret Name Purpose
DOMAIN Newline-separated domains to scan
EMAIL_ADDRESS Git commit identity
USER_NAME Git commit identity

πŸ“€ Result Handling

  • Git is configured in the workflow
  • All results are committed and pushed to the repo (results/ folder)
name: Recon & Takeover

on:
  push:
    branches: [main]

jobs:
  full-recon:
    runs-on: ubuntu-latest

    steps:
      - name: Setup Go 1.23
        uses: actions/setup-go@v5
        with:
          go-version: '1.23'

      - name: Checkout code
        uses: actions/checkout@v3

      - name: Install Dependencies & Tools
        run: |
          set -e
          sudo apt-get update
          sudo apt-get install -y wget unzip jq git curl dnsutils
          # Install Go tools
          go install github.com/projectdiscovery/httpx/cmd/httpx@latest && sudo mv ~/go/bin/httpx /usr/bin/
          go install github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest && sudo mv ~/go/bin/subfinder /usr/bin/
          go install github.com/projectdiscovery/dnsx/cmd/dnsx@latest && sudo mv ~/go/bin/dnsx /usr/bin/
          go install github.com/tomnomnom/qsreplace@latest && sudo mv ~/go/bin/qsreplace /usr/bin/
          go install github.com/lc/gau/v2/cmd/gau@latest && sudo mv ~/go/bin/gau /usr/bin/
          go install github.com/cybercdh/assetfinder@cybercdh && sudo mv ~/go/bin/assetfinder /usr/bin/
          go install github.com/PentestPad/subzy@latest && sudo mv ~/go/bin/subzy /usr/bin/
          # Install nuclei (latest release)
          LATEST_VERSION=$(curl -s https://api.github.com/repos/projectdiscovery/nuclei/releases/latest | jq -r '.tag_name')
          CLEAN_VERSION=${LATEST_VERSION#v}
          wget https://github.com/projectdiscovery/nuclei/releases/download/${LATEST_VERSION}/nuclei_${CLEAN_VERSION}_linux_amd64.zip
          unzip -o nuclei_${CLEAN_VERSION}_linux_amd64.zip
          sudo mv nuclei /usr/bin/
          sudo chmod +x /usr/bin/nuclei
          rm -rf nuclei* *.md

      - name: Recon
        env:
          DOMAINS: ${{ secrets.DOMAIN }}
        run: |
          set -e
          TODAY=$(date +%F)
          mkdir -p results
          echo "$DOMAINS" | while read -r TARGET; do
            echo "\nπŸš€ Scanning: $TARGET"

            mkdir -p results/$TARGET

            echo "[*] Subdomain Enumeration..."
            assetfinder $TARGET --subs-only | grep "\.${TARGET}$" | sort -u > results/$TARGET/subdomains.txt

            echo "[*] Probing live hosts..."
            cat results/$TARGET/subdomains.txt | httpx -silent \
              -status-code -location -title -web-server -cname -ip \
              -tech-detect -cdn -method -probe -follow-redirects -fr \
              -random-agent -no-color -timeout 15 -retries 3 -threads 100 \
              -o results/$TARGET/httpx.txt

            echo "[*] Filtering SUCCESS responses..."
            cat results/$TARGET/httpx.txt | grep "SUCCESS" | awk '{print $1}' > results/$TARGET/httpx-success.txt

            echo "[*] Resolving DNS (via dnsx)..."
            awk '{print $1}' results/$TARGET/httpx.txt | dnsx -nc -cname -resp -silent > results/$TARGET/dnsx.txt

            echo "[*] Filtering dangling CNAME (possible takeover)..."
            awk '/\[CNAME\]/ {
              gsub(/\[|\]/, "", $0);  # remove all brackets
              print $1, $3;
            }' results/$TARGET/dnsx.txt | while read sub cname; do
              if ! dig +short "$cname" | grep -q .; then
                echo "$sub -> $cname [πŸ”₯ Dangling]" >> results/$TARGET/dangling-cname.txt
              fi
            done

            echo "[*] Running Subdomain Takeover Check with Subzy (original list)..."
            subzy run --targets results/$TARGET/subdomains.txt \
              --concurrency 50 \
              --hide_fails \
              --timeout 10 \
              --vuln \
              --output results/$TARGET/subzy-subdomains.json

            echo "[*] Extra Subzy (from resolved list)..."
            awk '{print $1}' results/$TARGET/dnsx.txt | sort -u > results/$TARGET/filtered.txt
            subzy run --targets results/$TARGET/filtered.txt \
              --concurrency 50 \
              --hide_fails \
              --timeout 10 \
              --vuln \
              --output results/$TARGET/subzy-dnsx.json

            echo "[*] Running Nuclei on successful HTTPX targets..."
            nuclei -l results/$TARGET/httpx-success.txt \
              -severity low, medium, high, critical, unknown \
              -c 50 \
              -timeout 10 \
              -rate-limit 100 \
              -silent \
              -o results/$TARGET/nuclei-httpx.txt
          done

      - name: Set Git
        run: |
          git config --global user.email "${{ secrets.EMAIL_ADDRESS }}"
          git config --global user.name "${{ secrets.USER_NAME }}"

      - name: Commit & Push
        run: |
          git add results/
          git commit -m "Recon & Takeover $(date -u)" --no-verify || echo "No changes"
          git push origin main || true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment