Skip to main content
Glama

recon_vhost

Identify virtual hosts by fuzzing Host headers with a wordlist to discover hidden subdomains and web applications during security testing.

Instructions

Brute-force virtual hosts by fuzzing the Host header. Returns baseline_length, results (vhost/status/length/length_delta), unique_vhosts, and tested count. Read-only, sends one request per wordlist entry.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
targetYesTarget IP or domain to send requests to
base_domainYesBase domain for vhost names, e.g. hackycorp.com
wordlistNoPath to wordlist file. Uses built-in common subdomains if not provided.

Implementation Reference

  • The handler implementation for the `recon_vhost` tool, which performs vhost brute-forcing by fuzzing the Host header using curl.
    async ({ target, base_domain, wordlist }) => {
      requireTool("curl");
    
      // Built-in common subdomains
      const defaultSubs = [
        "admin", "www", "mail", "ftp", "api", "dev", "staging",
        "test", "portal", "dashboard", "app", "blog", "shop",
        "internal", "intranet", "vpn", "remote", "beta", "demo",
        "docs", "wiki", "git", "jenkins", "ci", "cd", "monitor",
        "grafana", "kibana", "elastic", "balancer", "proxy",
      ];
    
      let subs: string[];
      if (wordlist && fs.existsSync(wordlist)) {
        const content = fs.readFileSync(wordlist, "utf-8");
        subs = content
          .split("\n")
          .map((l) => l.trim())
          .filter((l) => l.length > 0)
          .slice(0, 500);
      } else {
        subs = defaultSubs;
      }
    
      // Baseline: request with the raw target as Host
      const baseline = await runCmd("curl", [
        "-sk", "-o", "/dev/null", "-w", "%{http_code}:%{size_download}",
        `http://${target}/`,
      ]);
      const bp = baseline.stdout.split(":");
      const baselineLength = bp.length > 1 ? parseInt(bp[1], 10) : 0;
    
      const results: Array<{
        vhost: string;
        status: number;
        length: number;
        length_delta: number;
      }> = [];
    
      for (const sub of subs) {
        const vhost = `${sub}.${base_domain}`;
        const res = await runCmd("curl", [
          "-sk", "-o", "/dev/null",
          "-w", "%{http_code}:%{size_download}",
          "-H", `Host: ${vhost}`,
          `http://${target}/`,
        ]);
        const parts = res.stdout.split(":");
        const status = parts.length > 0 ? parseInt(parts[0], 10) : 0;
        const length = parts.length > 1 ? parseInt(parts[1], 10) : 0;
    
        // Only include results different from baseline
        if (Math.abs(length - baselineLength) > 20 || (status !== 0 && status !== 301 && status !== 404)) {
          results.push({
            vhost,
            status,
            length,
            length_delta: length - baselineLength,
          });
        }
      }
    
      const result = {
        baseline_length: baselineLength,
        results,
        unique_vhosts: results.map((r) => r.vhost),
        tested: subs.length,
      };
    
      return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
    }
  • Registration of the `recon_vhost` tool within the MCP server, including its schema/parameter definitions.
    server.tool(
      "recon_vhost",
      "Brute-force virtual hosts by fuzzing the Host header. Returns baseline_length, results (vhost/status/length/length_delta), unique_vhosts, and tested count. Read-only, sends one request per wordlist entry.",
      {
        target: z
          .string()
          .describe("Target IP or domain to send requests to"),
        base_domain: z
          .string()
          .describe("Base domain for vhost names, e.g. hackycorp.com"),
        wordlist: z
          .string()
          .optional()
          .describe("Path to wordlist file. Uses built-in common subdomains if not provided."),
      },

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/operantlabs/operant-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server