Aller au contenu

Cheat subzy Feuille

Copier toutes les commandes Générer PDF

Aperçu général

Subzy est un scanner rapide de vulnérabilité à la prise en charge sous-domaine qui détecte les enregistrements DNS et identifie les possibilités potentielles de prise en charge sous-domaine. Il prend en charge plusieurs fournisseurs et services cloud, ce qui le rend essentiel pour des évaluations complètes de la sécurité des applications web modernes et de l'infrastructure cloud.

C'est-à-dire Caractéristiques principales: Détection rapide de la prise en charge sous-domaine, support multi-fournisseurs, numérisation simultanée, empreintes digitales personnalisées, rapports complets et formats de sortie faciles à intégrer.

Installation et configuration

Installation binaire

# Download latest release for Linux
wget https://github.com/LukaSikic/subzy/releases/latest/download/subzy_linux_amd64.tar.gz
tar -xzf subzy_linux_amd64.tar.gz
sudo mv subzy /usr/local/bin/

# Download for macOS
wget https://github.com/LukaSikic/subzy/releases/latest/download/subzy_darwin_amd64.tar.gz
tar -xzf subzy_darwin_amd64.tar.gz
sudo mv subzy /usr/local/bin/

# Download for Windows
wget https://github.com/LukaSikic/subzy/releases/latest/download/subzy_windows_amd64.zip
unzip subzy_windows_amd64.zip
# Move subzy.exe to PATH

# Verify installation
subzy --version

# Check available options
subzy --help

Aller à l'installation

# Install via Go (requires Go 1.19+)
go install github.com/LukaSikic/subzy@latest

# Verify installation
subzy --version

# Update to latest version
go install github.com/LukaSikic/subzy@latest

# Install specific version
go install github.com/LukaSikic/subzy@v1.0.7

# Build from source
git clone https://github.com/LukaSikic/subzy.git
cd subzy
go build -o subzy main.go
sudo mv subzy /usr/local/bin/
```_

### Installation Docker
```bash
# Pull official Docker image
docker pull lukasikic/subzy:latest

# Run Subzy in Docker
docker run --rm lukasikic/subzy:latest --version

# Run with volume mount for input/output
docker run --rm -v $(pwd):/app lukasikic/subzy:latest --targets /app/subdomains.txt

# Create alias for easier usage
echo 'alias subzy="docker run --rm -v $(pwd):/app lukasikic/subzy:latest"' >> ~/.bashrc
source ~/.bashrc

# Build custom Docker image
cat > Dockerfile << EOF
FROM lukasikic/subzy:latest
RUN apk add --no-cache curl jq
COPY custom-fingerprints.json /app/
EOF

docker build -t custom-subzy .
```_

### Installation du gestionnaire de paquets
```bash
# Homebrew (macOS/Linux)
brew install subzy

# Arch Linux (AUR)
yay -S subzy-bin

# Snap package
sudo snap install subzy

# APT (Ubuntu/Debian) - via GitHub releases
curl -s https://api.github.com/repos/LukaSikic/subzy/releases/latest \
| grep "browser_download_url.*linux_amd64.deb" \
| cut -d '"' -f 4 \
| wget -qi -
sudo dpkg -i subzy_*.deb

# RPM (CentOS/RHEL/Fedora)
curl -s https://api.github.com/repos/LukaSikic/subzy/releases/latest \
| grep "browser_download_url.*linux_amd64.rpm" \
| cut -d '"' -f 4 \
| wget -qi -
sudo rpm -i subzy_*.rpm

Configuration et configuration

# Create configuration directory
mkdir -p ~/.subzy

# Create custom fingerprints file
cat > ~/.subzy/custom-fingerprints.json << 'EOF'
{
  "fingerprints": [
    {
      "service": "Custom Service",
      "cname": ["custom.example.com"],
      "fingerprint": ["Custom error message"],
      "nxdomain": false,
      "discussion": "https://example.com/discussion"
    }
  ]
}
EOF

# Create subdomain list for testing
cat > test-subdomains.txt << 'EOF'
subdomain1.example.com
subdomain2.example.com
subdomain3.example.com
api.example.com
admin.example.com
staging.example.com
dev.example.com
test.example.com
EOF

# Set environment variables
export SUBZY_CONFIG=~/.subzy/custom-fingerprints.json
export SUBZY_THREADS=50
export SUBZY_TIMEOUT=10

Utilisation de base et commandes

Numériser une cible unique

# Basic subdomain takeover check
subzy run --target subdomain.example.com

# Check with verbose output
subzy run --target subdomain.example.com --verbose

# Check with custom timeout
subzy run --target subdomain.example.com --timeout 30

# Check with custom user agent
subzy run --target subdomain.example.com --user-agent "Custom Agent"

# Check with proxy
subzy run --target subdomain.example.com --proxy http://127.0.0.1:8080

# Check with custom DNS resolver
subzy run --target subdomain.example.com --resolver 8.8.8.8

# Check with HTTPS verification disabled
subzy run --target subdomain.example.com --https

# Save results to file
subzy run --target subdomain.example.com --output results.txt

Numériser plusieurs cibles

# Scan multiple targets from file
echo -e "sub1.example.com\nsub2.example.com" > targets.txt
subzy run --targets targets.txt

# Scan with threading
subzy run --targets targets.txt --concurrency 50

# Scan with custom output format
subzy run --targets targets.txt --output results.json

# Scan with verbose logging
subzy run --targets targets.txt --verbose --output detailed-results.txt

# Scan with custom fingerprints
subzy run --targets targets.txt --fingerprints custom-fingerprints.json

# Scan and save only vulnerable targets
subzy run --targets targets.txt --output vulnerable.txt --vulnerable-only

# Scan with rate limiting
subzy run --targets targets.txt --concurrency 10 --timeout 15

Options avancées de numérisation

# Scan with all available checks
subzy run --targets targets.txt --verify-ssl --https --verbose

# Scan with custom DNS settings
subzy run --targets targets.txt --resolver 1.1.1.1 --timeout 20

# Scan with proxy and custom headers
subzy run --targets targets.txt \
    --proxy http://127.0.0.1:8080 \
    --user-agent "Mozilla/5.0 Custom Agent" \
    --timeout 30

# Scan with output in different formats
subzy run --targets targets.txt --output results.json --format json
subzy run --targets targets.txt --output results.csv --format csv
subzy run --targets targets.txt --output results.xml --format xml

# Scan with custom fingerprint validation
subzy run --targets targets.txt --fingerprints custom.json --validate-fingerprints

# Scan with detailed error reporting
subzy run --targets targets.txt --verbose --debug --output debug-results.txt

Détection avancée de reprise de sous-domaine

Développement personnalisé de l'empreinte digitale

# Create advanced custom fingerprints file
{
  "fingerprints": [
    {
      "service": "AWS S3",
      "cname": ["s3.amazonaws.com", "s3-website"],
      "fingerprint": [
        "NoSuchBucket",
        "The specified bucket does not exist"
      ],
      "nxdomain": false,
      "discussion": "https://github.com/EdOverflow/can-i-take-over-xyz"
    },
    {
      "service": "GitHub Pages",
      "cname": ["github.io", "githubusercontent.com"],
      "fingerprint": [
        "There isn't a GitHub Pages site here.",
        "For root URLs (like http://example.com/) you must provide an index.html file"
      ],
      "nxdomain": false,
      "discussion": "https://github.com/EdOverflow/can-i-take-over-xyz"
    },
    {
      "service": "Heroku",
      "cname": ["herokuapp.com", "herokussl.com"],
      "fingerprint": [
        "No such app",
        "There's nothing here, yet."
      ],
      "nxdomain": false,
      "discussion": "https://github.com/EdOverflow/can-i-take-over-xyz"
    },
    {
      "service": "Netlify",
      "cname": ["netlify.com", "netlifyglobalcdn.com"],
      "fingerprint": [
        "Not Found - Request ID:",
        "Site Not Found"
      ],
      "nxdomain": false,
      "discussion": "https://github.com/EdOverflow/can-i-take-over-xyz"
    },
    {
      "service": "Azure",
      "cname": ["azurewebsites.net", "cloudapp.net"],
      "fingerprint": [
        "404 Web Site not found",
        "This site is stopped"
      ],
      "nxdomain": false,
      "discussion": "https://github.com/EdOverflow/can-i-take-over-xyz"
    },
    {
      "service": "Shopify",
      "cname": ["myshopify.com"],
      "fingerprint": [
        "Sorry, this shop is currently unavailable",
        "Only one step left!"
      ],
      "nxdomain": false,
      "discussion": "https://github.com/EdOverflow/can-i-take-over-xyz"
    },
    {
      "service": "Fastly",
      "cname": ["fastly.com", "fastlylb.net"],
      "fingerprint": [
        "Fastly error: unknown domain",
        "Please check that this domain has been added to a service"
      ],
      "nxdomain": false,
      "discussion": "https://github.com/EdOverflow/can-i-take-over-xyz"
    },
    {
      "service": "CloudFront",
      "cname": ["cloudfront.net"],
      "fingerprint": [
        "Bad Request: ERROR: The request could not be satisfied",
        "The distribution does not exist"
      ],
      "nxdomain": false,
      "discussion": "https://github.com/EdOverflow/can-i-take-over-xyz"
    },
    {
      "service": "Bitbucket",
      "cname": ["bitbucket.org"],
      "fingerprint": [
        "Repository not found"
      ],
      "nxdomain": false,
      "discussion": "https://github.com/EdOverflow/can-i-take-over-xyz"
    },
    {
      "service": "Tumblr",
      "cname": ["tumblr.com"],
      "fingerprint": [
        "Whatever you were looking for doesn't currently exist at this address"
      ],
      "nxdomain": false,
      "discussion": "https://github.com/EdOverflow/can-i-take-over-xyz"
    }
  ]
}

Détection automatisée de découverte et de prise en charge du sous-domaine

#!/usr/bin/env python3
# Comprehensive subdomain takeover detection automation

import subprocess
import json
import threading
import time
import dns.resolver
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
from urllib.parse import urlparse
import re

class SubdomainTakeoverScanner:
    def __init__(self, max_workers=50, timeout=10):
        self.max_workers = max_workers
        self.timeout = timeout
        self.results = []
        self.lock = threading.Lock()
        self.vulnerable_services = []

    def discover_subdomains(self, domain, methods=['subfinder', 'amass', 'assetfinder']):
        """Discover subdomains using multiple tools"""

        all_subdomains = set()

        for method in methods:
            try:
                if method == 'subfinder':
                    result = subprocess.run(
                        ['subfinder', '-d', domain, '-silent'],
                        capture_output=True, text=True, timeout=300
                    )
                    if result.returncode == 0:
                        subdomains = result.stdout.strip().split('\n')
                        all_subdomains.update([s for s in subdomains if s])

                elif method == 'amass':
                    result = subprocess.run(
                        ['amass', 'enum', '-d', domain, '-passive'],
                        capture_output=True, text=True, timeout=600
                    )
                    if result.returncode == 0:
                        subdomains = result.stdout.strip().split('\n')
                        all_subdomains.update([s for s in subdomains if s])

                elif method == 'assetfinder':
                    result = subprocess.run(
                        ['assetfinder', '--subs-only', domain],
                        capture_output=True, text=True, timeout=300
                    )
                    if result.returncode == 0:
                        subdomains = result.stdout.strip().split('\n')
                        all_subdomains.update([s for s in subdomains if s])

            except subprocess.TimeoutExpired:
                print(f"Timeout during {method} subdomain discovery")
            except FileNotFoundError:
                print(f"{method} not found, skipping...")
            except Exception as e:
                print(f"Error with {method}: {e}")

        return list(all_subdomains)

    def check_dns_record(self, subdomain):
        """Check DNS records for subdomain"""

        dns_info = {
            'subdomain': subdomain,
            'a_records': [],
            'cname_records': [],
            'mx_records': [],
            'ns_records': [],
            'txt_records': [],
            'nxdomain': False,
            'error': None
        }

        try:
            # Check A records
            try:
                answers = dns.resolver.resolve(subdomain, 'A')
                dns_info['a_records'] = [str(rdata) for rdata in answers]
            except dns.resolver.NXDOMAIN:
                dns_info['nxdomain'] = True
            except dns.resolver.NoAnswer:
                pass
            except Exception as e:
                dns_info['error'] = str(e)

            # Check CNAME records
            try:
                answers = dns.resolver.resolve(subdomain, 'CNAME')
                dns_info['cname_records'] = [str(rdata) for rdata in answers]
            except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
                pass
            except Exception as e:
                if not dns_info['error']:
                    dns_info['error'] = str(e)

            # Check MX records
            try:
                answers = dns.resolver.resolve(subdomain, 'MX')
                dns_info['mx_records'] = [str(rdata) for rdata in answers]
            except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
                pass
            except Exception:
                pass

            # Check NS records
            try:
                answers = dns.resolver.resolve(subdomain, 'NS')
                dns_info['ns_records'] = [str(rdata) for rdata in answers]
            except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
                pass
            except Exception:
                pass

            # Check TXT records
            try:
                answers = dns.resolver.resolve(subdomain, 'TXT')
                dns_info['txt_records'] = [str(rdata) for rdata in answers]
            except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
                pass
            except Exception:
                pass

        except Exception as e:
            dns_info['error'] = str(e)

        return dns_info

    def check_http_response(self, subdomain):
        """Check HTTP response for takeover indicators"""

        http_info = {
            'subdomain': subdomain,
            'status_code': None,
            'response_body': '',
            'headers': {},
            'redirect_url': None,
            'error': None,
            'takeover_indicators': []
        }

        # Common takeover indicators
        takeover_patterns = {
            'aws_s3': [
                'NoSuchBucket',
                'The specified bucket does not exist'
            ],
            'github_pages': [
                "There isn't a GitHub Pages site here",
                'For root URLs (like http://example.com/) you must provide an index.html file'
            ],
            'heroku': [
                'No such app',
                "There's nothing here, yet"
            ],
            'netlify': [
                'Not Found - Request ID:',
                'Site Not Found'
            ],
            'azure': [
                '404 Web Site not found',
                'This site is stopped'
            ],
            'shopify': [
                'Sorry, this shop is currently unavailable',
                'Only one step left!'
            ],
            'fastly': [
                'Fastly error: unknown domain',
                'Please check that this domain has been added to a service'
            ],
            'cloudfront': [
                'Bad Request: ERROR: The request could not be satisfied',
                'The distribution does not exist'
            ]
        }

        try:
            # Try HTTPS first, then HTTP
            for protocol in ['https', 'http']:
                try:
                    url = f"{protocol}://{subdomain}"
                    response = requests.get(
                        url, 
                        timeout=self.timeout,
                        allow_redirects=True,
                        verify=False
                    )

                    http_info['status_code'] = response.status_code
                    http_info['response_body'] = response.text[:5000]  # Limit body size
                    http_info['headers'] = dict(response.headers)

                    if response.history:
                        http_info['redirect_url'] = response.url

                    # Check for takeover indicators
                    response_text = response.text.lower()
                    for service, patterns in takeover_patterns.items():
                        for pattern in patterns:
                            if pattern.lower() in response_text:
                                http_info['takeover_indicators'].append({
                                    'service': service,
                                    'pattern': pattern,
                                    'confidence': 'high'
                                })

                    break  # Success, no need to try other protocol

                except requests.exceptions.SSLError:
                    if protocol == 'https':
                        continue  # Try HTTP
                    else:
                        http_info['error'] = 'SSL Error'
                except requests.exceptions.ConnectionError:
                    if protocol == 'https':
                        continue  # Try HTTP
                    else:
                        http_info['error'] = 'Connection Error'
                except requests.exceptions.Timeout:
                    http_info['error'] = 'Timeout'
                    break
                except Exception as e:
                    http_info['error'] = str(e)
                    break

        except Exception as e:
            http_info['error'] = str(e)

        return http_info

    def run_subzy_scan(self, subdomain):
        """Run Subzy scan on subdomain"""

        try:
            result = subprocess.run(
                ['subzy', 'run', '--target', subdomain, '--timeout', str(self.timeout)],
                capture_output=True, text=True, timeout=self.timeout + 10
            )

            subzy_result = {
                'subdomain': subdomain,
                'vulnerable': False,
                'service': None,
                'output': result.stdout,
                'error': result.stderr if result.returncode != 0 else None
            }

            # Parse Subzy output for vulnerabilities
            if 'VULNERABLE' in result.stdout.upper() or 'TAKEOVER' in result.stdout.upper():
                subzy_result['vulnerable'] = True

                # Try to extract service name
                lines = result.stdout.split('\n')
                for line in lines:
                    if 'service:' in line.lower() or 'provider:' in line.lower():
                        subzy_result['service'] = line.split(':')[-1].strip()
                        break

            return subzy_result

        except subprocess.TimeoutExpired:
            return {
                'subdomain': subdomain,
                'vulnerable': False,
                'service': None,
                'output': '',
                'error': 'Subzy scan timeout'
            }
        except Exception as e:
            return {
                'subdomain': subdomain,
                'vulnerable': False,
                'service': None,
                'output': '',
                'error': str(e)
            }

    def comprehensive_scan(self, subdomain):
        """Perform comprehensive subdomain takeover scan"""

        print(f"Scanning: {subdomain}")

        # Get DNS information
        dns_info = self.check_dns_record(subdomain)

        # Get HTTP response information
        http_info = self.check_http_response(subdomain)

        # Run Subzy scan
        subzy_info = self.run_subzy_scan(subdomain)

        # Combine results
        scan_result = {
            'subdomain': subdomain,
            'timestamp': time.time(),
            'dns': dns_info,
            'http': http_info,
            'subzy': subzy_info,
            'vulnerable': False,
            'confidence': 'low',
            'risk_factors': []
        }

        # Analyze results for vulnerability indicators
        risk_factors = []

        # Check DNS indicators
        if dns_info['nxdomain']:
            risk_factors.append('NXDOMAIN response')

        if dns_info['cname_records']:
            for cname in dns_info['cname_records']:
                # Check for common vulnerable services in CNAME
                vulnerable_cnames = [
                    'github.io', 'herokuapp.com', 'netlify.com',
                    'azurewebsites.net', 's3.amazonaws.com', 'cloudfront.net'
                ]
                for vcname in vulnerable_cnames:
                    if vcname in cname:
                        risk_factors.append(f'Vulnerable CNAME: {cname}')

        # Check HTTP indicators
        if http_info['takeover_indicators']:
            for indicator in http_info['takeover_indicators']:
                risk_factors.append(f"HTTP indicator: {indicator['service']} - {indicator['pattern']}")

        # Check Subzy results
        if subzy_info['vulnerable']:
            risk_factors.append(f"Subzy detected vulnerability: {subzy_info['service']}")
            scan_result['vulnerable'] = True
            scan_result['confidence'] = 'high'

        # Determine overall vulnerability status
        if len(risk_factors) >= 2:
            scan_result['vulnerable'] = True
            scan_result['confidence'] = 'medium' if scan_result['confidence'] == 'low' else scan_result['confidence']

        scan_result['risk_factors'] = risk_factors

        with self.lock:
            self.results.append(scan_result)
            if scan_result['vulnerable']:
                self.vulnerable_services.append(scan_result)

        return scan_result

    def scan_subdomains(self, subdomains):
        """Scan multiple subdomains concurrently"""

        print(f"Starting comprehensive scan of {len(subdomains)} subdomains")
        print(f"Max workers: {self.max_workers}")
        print(f"Timeout: {self.timeout}s")

        with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
            # Submit all tasks
            future_to_subdomain = {
                executor.submit(self.comprehensive_scan, subdomain): subdomain 
                for subdomain in subdomains
            }

            # Process completed tasks
            for future in as_completed(future_to_subdomain):
                subdomain = future_to_subdomain[future]
                try:
                    result = future.result()
                    if result['vulnerable']:
                        print(f"🚨 VULNERABLE: {subdomain} - {', '.join(result['risk_factors'])}")
                    else:
                        print(f"✓ Safe: {subdomain}")
                except Exception as e:
                    print(f"✗ Error scanning {subdomain}: {e}")

        return self.results

    def generate_report(self, output_file='subdomain_takeover_report.json'):
        """Generate comprehensive report"""

        # Calculate statistics
        total_subdomains = len(self.results)
        vulnerable_subdomains = len(self.vulnerable_services)

        report = {
            'scan_summary': {
                'total_subdomains': total_subdomains,
                'vulnerable_subdomains': vulnerable_subdomains,
                'vulnerability_rate': (vulnerable_subdomains / total_subdomains * 100) if total_subdomains > 0 else 0,
                'scan_date': time.strftime('%Y-%m-%d %H:%M:%S')
            },
            'vulnerable_subdomains': self.vulnerable_services,
            'all_results': self.results
        }

        # Save report
        with open(output_file, 'w') as f:
            json.dump(report, f, indent=2)

        print(f"\nReport saved to: {output_file}")

        # Generate summary
        print("\nScan Summary:")
        print(f"Total subdomains: {total_subdomains}")
        print(f"Vulnerable subdomains: {vulnerable_subdomains}")
        print(f"Vulnerability rate: {report['scan_summary']['vulnerability_rate']:.1f}%")

        if self.vulnerable_services:
            print("\nVulnerable Subdomains:")
            for vuln in self.vulnerable_services:
                print(f"- {vuln['subdomain']}: {', '.join(vuln['risk_factors'])}")

        return report

# Usage example
if __name__ == "__main__":
    # Create scanner instance
    scanner = SubdomainTakeoverScanner(max_workers=20, timeout=10)

    # Discover subdomains
    domain = "example.com"
    print(f"Discovering subdomains for {domain}...")
    subdomains = scanner.discover_subdomains(domain)
    print(f"Found {len(subdomains)} subdomains")

    # Scan for takeover vulnerabilities
    results = scanner.scan_subdomains(subdomains)

    # Generate report
    report = scanner.generate_report('comprehensive_takeover_report.json')

Automatisation et intégration

Intégration CI/CD

#!/bin/bash
# CI/CD script for subdomain takeover detection

set -e

DOMAIN="$1"
OUTPUT_DIR="$2"
THRESHOLD="$3"

if [ -z "$DOMAIN" ] || [ -z "$OUTPUT_DIR" ]; then
    echo "Usage: $0 <domain> <output_dir> [threshold]"
    exit 1
fi

THRESHOLD=${THRESHOLD:-0}  # Default: fail on any takeover found

echo "Starting subdomain takeover scan..."
echo "Domain: $DOMAIN"
echo "Output directory: $OUTPUT_DIR"
echo "Threshold: $THRESHOLD vulnerabilities"

mkdir -p "$OUTPUT_DIR"

# Discover subdomains
echo "Discovering subdomains..."
subfinder -d "$DOMAIN" -silent > "$OUTPUT_DIR/subdomains.txt" 2>/dev/null || echo "Subfinder not available"
amass enum -d "$DOMAIN" -passive >> "$OUTPUT_DIR/subdomains.txt" 2>/dev/null || echo "Amass not available"
assetfinder --subs-only "$DOMAIN" >> "$OUTPUT_DIR/subdomains.txt" 2>/dev/null || echo "Assetfinder not available"

# Remove duplicates and empty lines
sort "$OUTPUT_DIR/subdomains.txt" | uniq | grep -v '^$' > "$OUTPUT_DIR/unique_subdomains.txt"
SUBDOMAIN_COUNT=$(wc -l < "$OUTPUT_DIR/unique_subdomains.txt")

echo "Found $SUBDOMAIN_COUNT unique subdomains"

# Run Subzy scan
echo "Running Subzy scan..."
subzy run --targets "$OUTPUT_DIR/unique_subdomains.txt" \
    --concurrency 50 \
    --timeout 15 \
    --output "$OUTPUT_DIR/subzy_results.txt" \
    --verbose

# Parse results
VULN_COUNT=$(grep -c "VULNERABLE\|TAKEOVER" "$OUTPUT_DIR/subzy_results.txt" || echo "0")

echo "Found $VULN_COUNT potential subdomain takeover vulnerabilities"

# Generate summary report
cat > "$OUTPUT_DIR/takeover-summary.txt" << EOF
Subdomain Takeover Scan Summary
==============================
Date: $(date)
Domain: $DOMAIN
Total Subdomains: $SUBDOMAIN_COUNT
Potential Vulnerabilities: $VULN_COUNT
Threshold: $THRESHOLD

Status: $(if [ "$VULN_COUNT" -le "$THRESHOLD" ]; then echo "PASS"; else echo "FAIL"; fi)
EOF

# Generate detailed report
python3 << 'PYTHON_EOF'
import sys
import json
import re
from datetime import datetime

output_dir = sys.argv[1]
domain = sys.argv[2]

# Read Subzy results
try:
    with open(f"{output_dir}/subzy_results.txt", 'r') as f:
        subzy_output = f.read()
except FileNotFoundError:
    subzy_output = ""

# Parse vulnerabilities
vulnerabilities = []
lines = subzy_output.split('\n')

for line in lines:
    if 'VULNERABLE' in line.upper() or 'TAKEOVER' in line.upper():
        # Extract subdomain and service information
        parts = line.split()
        if len(parts) >= 2:
            subdomain = parts[0] if '://' not in parts[0] else parts[0].split('://')[-1]
            service = 'Unknown'

            # Try to extract service name
            for part in parts:
                if any(svc in part.lower() for svc in ['aws', 'github', 'heroku', 'netlify', 'azure']):
                    service = part
                    break

            vulnerability = {
                'subdomain': subdomain,
                'service': service,
                'description': line.strip(),
                'severity': 'High',
                'risk': 'Subdomain takeover possible'
            }
            vulnerabilities.append(vulnerability)

# Create detailed report
report = {
    'scan_info': {
        'domain': domain,
        'scanner': 'Subzy',
        'scan_date': datetime.now().isoformat(),
        'vulnerability_count': len(vulnerabilities)
    },
    'vulnerabilities': vulnerabilities,
    'raw_output': subzy_output
}

# Save JSON report
with open(f"{output_dir}/subzy-report.json", 'w') as f:
    json.dump(report, f, indent=2)

# Generate HTML report
html_content = f"""
<!DOCTYPE html>
<html>
<head>
    <title>Subdomain Takeover Scan Report</title>
    <style>
        body {{ font-family: Arial, sans-serif; margin: 20px; }}
        .header {{ background-color: #f0f0f0; padding: 20px; border-radius: 5px; }}
        .vuln {{ margin: 10px 0; padding: 15px; border-left: 4px solid #dc3545; background-color: #f8f9fa; }}
        .safe {{ color: #28a745; }}
        .danger {{ color: #dc3545; }}
        table {{ border-collapse: collapse; width: 100%; margin: 20px 0; }}
        th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
        th {{ background-color: #f2f2f2; }}
        .code {{ background-color: #f8f9fa; padding: 10px; border-radius: 3px; font-family: monospace; }}
    </style>
</head>
<body>
    <div class="header">
        <h1>Subdomain Takeover Scan Report</h1>
        <p><strong>Domain:</strong> {domain}</p>
        <p><strong>Scan Date:</strong> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
        <p><strong>Vulnerabilities Found:</strong> <span class="{'danger' if len(vulnerabilities) > 0 else 'safe'}">{len(vulnerabilities)}</span></p>
    </div>

    <h2>Vulnerability Details</h2>
"""

if vulnerabilities:
    html_content += "<table><tr><th>Subdomain</th><th>Service</th><th>Risk</th><th>Description</th></tr>"
    for vuln in vulnerabilities:
        html_content += f"""
        <tr>
            <td>{vuln.get('subdomain', '')}</td>
            <td>{vuln.get('service', '')}</td>
            <td>{vuln.get('risk', '')}</td>
            <td><div class="code">{vuln.get('description', '')}</div></td>
        </tr>
        """
    html_content += "</table>"
else:
    html_content += "<p class='safe'>No subdomain takeover vulnerabilities detected.</p>"

html_content += """
    <h2>Raw Output</h2>
    <div class="code">
        <pre>{}</pre>
    </div>
</body>
</html>
""".format(subzy_output.replace('<', '&lt;').replace('>', '&gt;'))

with open(f"{output_dir}/subzy-report.html", 'w') as f:
    f.write(html_content)

print(f"Detailed reports generated:")
print(f"- JSON: {output_dir}/subzy-report.json")
print(f"- HTML: {output_dir}/subzy-report.html")
PYTHON_EOF

# Check threshold and exit
if [ "$VULN_COUNT" -gt "$THRESHOLD" ]; then
    echo "ERROR: Found $VULN_COUNT vulnerabilities, exceeds threshold of $THRESHOLD"
    exit 1
else
    echo "SUCCESS: Vulnerability count within acceptable threshold"
    exit 0
fi

Intégration des actions GitHub

# .github/workflows/subdomain-takeover-scan.yml
name: Subdomain Takeover Security Scan

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]
  schedule:
    - cron: '0 4 * * 3'  # Weekly scan on Wednesdays at 4 AM

jobs:
  subdomain-takeover-scan:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3

    - name: Install subdomain discovery tools
      run: |
        # Install Subfinder
        wget https://github.com/projectdiscovery/subfinder/releases/latest/download/subfinder_2.6.3_linux_amd64.zip
        unzip subfinder_2.6.3_linux_amd64.zip
        sudo mv subfinder /usr/local/bin/

        # Install Assetfinder
        go install github.com/tomnomnom/assetfinder@latest

        # Install Subzy
        wget https://github.com/LukaSikic/subzy/releases/latest/download/subzy_linux_amd64.tar.gz
        tar -xzf subzy_linux_amd64.tar.gz
        sudo mv subzy /usr/local/bin/

        # Verify installations
        subfinder -version
        assetfinder --help
        subzy --version

    - name: Discover subdomains
      run: |
        mkdir -p scan-results

        # Discover subdomains using multiple tools
        subfinder -d ${{ vars.TARGET_DOMAIN }} -silent > scan-results/subfinder.txt
        assetfinder --subs-only ${{ vars.TARGET_DOMAIN }} > scan-results/assetfinder.txt

        # Combine and deduplicate
        cat scan-results/subfinder.txt scan-results/assetfinder.txt | sort | uniq > scan-results/all_subdomains.txt

        SUBDOMAIN_COUNT=$(wc -l < scan-results/all_subdomains.txt)
        echo "SUBDOMAIN_COUNT=$SUBDOMAIN_COUNT" >> $GITHUB_ENV
        echo "Found $SUBDOMAIN_COUNT unique subdomains"

    - name: Run subdomain takeover scan
      run: |
        # Run Subzy scan
        subzy run --targets scan-results/all_subdomains.txt \
          --concurrency 30 \
          --timeout 15 \
          --output scan-results/subzy_results.txt \
          --verbose

        # Count vulnerabilities
        VULN_COUNT=$(grep -c "VULNERABLE\|TAKEOVER" scan-results/subzy_results.txt || echo "0")
        echo "VULN_COUNT=$VULN_COUNT" >> $GITHUB_ENV

        # Generate summary
        echo "Subdomain takeover vulnerabilities found: $VULN_COUNT" > scan-results/summary.txt
        echo "Total subdomains scanned: $SUBDOMAIN_COUNT" >> scan-results/summary.txt

    - name: Process scan results
      run: |
        # Extract vulnerable subdomains
        grep "VULNERABLE\|TAKEOVER" scan-results/subzy_results.txt > scan-results/vulnerable_subdomains.txt || touch scan-results/vulnerable_subdomains.txt

        # Create detailed summary
        cat > scan-results/detailed_summary.txt << EOF
        Subdomain Takeover Scan Results
        ==============================
        Domain: ${{ vars.TARGET_DOMAIN }}
        Scan Date: $(date)
        Total Subdomains: $SUBDOMAIN_COUNT
        Vulnerable Subdomains: $VULN_COUNT

        Vulnerable Subdomains:
        $(cat scan-results/vulnerable_subdomains.txt)
        EOF

    - name: Upload scan results
      uses: actions/upload-artifact@v3
      with:
        name: subdomain-takeover-results
        path: scan-results/

    - name: Comment PR with results
      if: github.event_name == 'pull_request'
      uses: actions/github-script@v6
      with:
        script: |
          const fs = require('fs');
          const summary = fs.readFileSync('scan-results/summary.txt', 'utf8');

          github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body: `## Subdomain Takeover Scan Results\n\n\`\`\`\n${summary}\n\`\`\``
          });

    - name: Fail if vulnerabilities found
      run: |
        if [ "$VULN_COUNT" -gt "0" ]; then
          echo "Subdomain takeover vulnerabilities detected! Check the scan results."
          cat scan-results/vulnerable_subdomains.txt
          exit 1
        fi

Optimisation des performances et dépannage

Analyse des performances

# Optimize Subzy for different scenarios

# High-speed scanning
subzy run --targets subdomains.txt \
    --concurrency 100 \
    --timeout 5 \
    --https

# Thorough scanning
subzy run --targets subdomains.txt \
    --concurrency 20 \
    --timeout 30 \
    --verify-ssl \
    --verbose

# Memory-efficient scanning for large lists
subzy run --targets large_subdomains.txt \
    --concurrency 10 \
    --timeout 15 \
    --output results.txt

# Network-optimized scanning
subzy run --targets subdomains.txt \
    --concurrency 50 \
    --timeout 10 \
    --resolver 8.8.8.8

# Performance monitoring script
#!/bin/bash
monitor_subzy_performance() {
    local targets_file="$1"
    local output_file="subzy-performance-$(date +%s).log"

    echo "Starting performance monitoring for Subzy scan"
    echo "Targets file: $targets_file"
    echo "Log file: $output_file"

    # Start monitoring in background
    {
        echo "Timestamp,CPU%,Memory(MB),Targets/sec"
        start_time=$(date +%s)
        while true; do
            if pgrep -f "subzy" > /dev/null; then
                local cpu=$(ps -p $(pgrep -f "subzy") -o %cpu --no-headers | awk '{sum+=$1} END {print sum}')
                local mem=$(ps -p $(pgrep -f "subzy") -o rss --no-headers | awk '{sum+=$1} END {print sum/1024}')
                local current_time=$(date +%s)
                local elapsed=$((current_time - start_time))
                local targets_processed=$(wc -l < "$targets_file" 2>/dev/null || echo "0")
                local rate=$(echo "scale=2; $targets_processed / $elapsed" | bc -l 2>/dev/null || echo "0")
                echo "$(date +%s),$cpu,$mem,$rate"
            fi
            sleep 5
        done
    } > "$output_file" &

    local monitor_pid=$!

    # Run Subzy scan
    subzy run --targets "$targets_file" \
        --concurrency 50 \
        --timeout 15 \
        --verbose \
        --output "subzy-results-$(date +%s).txt"

    # Stop monitoring
    kill $monitor_pid 2>/dev/null

    echo "Performance monitoring completed: $output_file"
}

# Usage
monitor_subzy_performance "subdomains.txt"

Résolution de problèmes communs

# Troubleshooting script for Subzy
troubleshoot_subzy() {
    echo "Subzy Troubleshooting Guide"
    echo "=========================="

    # Check if Subzy is installed
    if ! command -v subzy &> /dev/null; then
        echo "❌ Subzy not found in PATH"
        echo "Solution: Install Subzy using one of the installation methods"
        return 1
    fi

    echo "✅ Subzy found: $(which subzy)"
    echo "Version: $(subzy --version 2>&1)"

    # Check network connectivity
    if ! curl -s --connect-timeout 5 https://httpbin.org/get > /dev/null; then
        echo "❌ Network connectivity issues"
        echo "Solution: Check internet connection and proxy settings"
        return 1
    fi

    echo "✅ Network connectivity OK"

    # Test basic functionality
    echo "Testing basic Subzy functionality..."
    echo "test.example.com" > /tmp/test_subdomains.txt

    if timeout 30 subzy run --targets /tmp/test_subdomains.txt --timeout 10 > /dev/null 2>&1; then
        echo "✅ Basic functionality test passed"
    else
        echo "❌ Basic functionality test failed"
        echo "Solution: Check Subzy installation and permissions"
        return 1
    fi

    # Check DNS resolution
    if ! nslookup google.com > /dev/null 2>&1; then
        echo "❌ DNS resolution issues"
        echo "Solution: Check DNS settings or use custom resolver"
        echo "Example: subzy run --targets file.txt --resolver 8.8.8.8"
        return 1
    fi

    echo "✅ DNS resolution OK"

    # Check for common issues
    echo "Checking for common configuration issues..."

    # Check file permissions
    if [ ! -r "/tmp/test_subdomains.txt" ]; then
        echo "⚠️  File permission issues detected"
        echo "Solution: Check read permissions on target files"
    fi

    # Check for proxy issues
    if [ -n "$HTTP_PROXY" ] || [ -n "$HTTPS_PROXY" ]; then
        echo "⚠️  Proxy environment variables detected"
        echo "Note: Use --proxy option if needed"
    fi

    # Clean up
    rm -f /tmp/test_subdomains.txt

    echo "Troubleshooting completed"
}

# Common error solutions
fix_common_subzy_errors() {
    echo "Common Subzy Error Solutions"
    echo "==========================="

    echo "1. 'no such file or directory'"
    echo "   Solution: Check if targets file exists and is readable"
    echo "   Example: ls -la targets.txt"
    echo ""

    echo "2. 'connection timeout'"
    echo "   Solution: Increase timeout or reduce concurrency"
    echo "   Example: subzy run --targets file.txt --timeout 30 --concurrency 10"
    echo ""

    echo "3. 'too many open files'"
    echo "   Solution: Reduce concurrency or increase system limits"
    echo "   Example: ulimit -n 4096 && subzy run --targets file.txt --concurrency 20"
    echo ""

    echo "4. 'DNS resolution failed'"
    echo "   Solution: Use custom DNS resolver"
    echo "   Example: subzy run --targets file.txt --resolver 1.1.1.1"
    echo ""

    echo "5. 'SSL certificate verification failed'"
    echo "   Solution: Disable SSL verification (use with caution)"
    echo "   Example: subzy run --targets file.txt --https"
    echo ""

    echo "6. 'permission denied'"
    echo "   Solution: Check file permissions and run with appropriate privileges"
    echo "   Example: chmod +r targets.txt"
    echo ""

    echo "7. 'no vulnerabilities found' (potential false negatives)"
    echo "   Solution: Use verbose mode and custom fingerprints"
    echo "   Example: subzy run --targets file.txt --verbose --fingerprints custom.json"
}

# Run troubleshooting
troubleshoot_subzy
fix_common_subzy_errors

Ressources et documentation

Ressources officielles

Ressources communautaires

  • Puis-je prendre le contrôle de XYZ? - Guide complet de prise en charge du sous-domaine
  • [Scanner de prise en charge du sous-domaine] (LINK_12) - Outil de numérisation alternatif
  • [Modèles Nuclei] (LINK_12) - Modèles de détection de reprise
  • [Méthodes de Bounty Bounty] (LINK_12) - Chasse par prise de contrôle sous-domaine

Recherche et apprentissage