[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6ESSE9EB3Z3PDM145J52Z94":3,"skill-same:01M6ESSE9EB3Z3PDM145J52Z94":122},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":31,"publishedAt":52,"linkOnly":53,"markdownContent":54,"markdownBody":55,"frontMatter":56,"refName":77,"commitSha":78,"skillDirectory":79,"forksCount":14,"repositoryHtmlUrl":80,"repositoryHomepageUrl":81,"ownerHtmlUrl":82,"ownerBlogUrl":6,"ownerDescription":83,"updatedAt":84,"install":85,"resources":98},"01M6ESSE9EB3Z3PDM145J52Z94","analyzing-typosquatting-domains-with-dnstwist",null,"Detect typosquatting, homograph phishing, and brand impersonation domains using dnstwist to generate domain permutations and identify registered lookalike domains targeting your organization.","henriquescastilho\u002Fmy-claude","henriquescastilho","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F153296945?v=4","01M6ESH7EXPXTH9CVQ4K16SRG8","Henrique Scheer","01M6ESH7JHEK2PTNNH4HEH787Z",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fanalyzing-typosquatting-domains-with-dnstwist\u002FSKILL.md",[18,23,26],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"with","domains","analyzing","dnstwist","typosquatting","analyzing typosquatting domains with dnstwist","brand","de","domain","intelligence","organization","cm","threat","aml","cybersecurity","t1566","dns","threat-intelligence","monitoring","generate","2026-11-10 10:12:30",false,"---\nname: analyzing-typosquatting-domains-with-dnstwist\ndescription: Detect typosquatting, homograph phishing, and brand impersonation domains\n  using dnstwist to generate domain permutations and identify registered lookalike\n  domains targeting your organization.\ndomain: cybersecurity\nsubdomain: threat-intelligence\ntags:\n- dnstwist\n- typosquatting\n- phishing\n- domain-monitoring\n- brand-protection\n- homograph\n- dns\n- threat-intelligence\nversion: '1.0'\nauthor: mahipal\nlicense: Apache-2.0\natlas_techniques:\n- AML.T0073\n- AML.T0052\nnist_csf:\n- ID.RA-01\n- ID.RA-05\n- DE.CM-01\n- DE.AE-02\nmitre_attack:\n- T1583.001\n- T1566.002\n- T1598.003\n- T1583.006\n---\n# Analyzing Typosquatting Domains with DNSTwist\n\n## Overview\n\nDNSTwist is a domain name permutation engine that generates similar-looking domain names to detect typosquatting, homograph phishing attacks, and brand impersonation. It creates thousands of domain permutations using techniques like character substitution, transposition, insertion, omission, and homoglyph replacement, then checks DNS records (A, AAAA, NS, MX), calculates web page similarity using fuzzy hashing (ssdeep) and perceptual hashing (pHash), and identifies potentially malicious registered domains.\n\n\n## When to Use\n\n- When investigating security incidents that require analyzing typosquatting domains with dnstwist\n- When building detection rules or threat hunting queries for this domain\n- When SOC analysts need structured procedures for this analysis type\n- When validating security monitoring coverage for related attack techniques\n\n## Prerequisites\n\n- Python 3.9+ with `dnstwist` installed (`pip install dnstwist[full]`)\n- Optional: GeoIP database for IP geolocation\n- Optional: Shodan API key for enrichment\n- Network access to perform DNS queries\n- Understanding of DNS record types and domain registration\n\n## Key Concepts\n\n### Domain Permutation Techniques\n\nDNSTwist generates permutations using: addition (appending characters), bitsquatting (bit-flip errors), homoglyph (visually similar Unicode characters like rn vs m), hyphenation (adding hyphens), insertion (inserting characters), omission (removing characters), repetition (repeating characters), replacement (replacing with adjacent keyboard keys), subdomain (inserting dots), transposition (swapping adjacent characters), vowel-swap (swapping vowels), and dictionary-based (appending common words).\n\n### Fuzzy Hashing and Visual Similarity\n\nDNSTwist uses ssdeep (locality-sensitive hash) to compare HTML content and pHash (perceptual hash) to compare screenshots of web pages. This helps identify cloned phishing sites that visually mimic the legitimate site. A high similarity score indicates a likely phishing page.\n\n### Detection Workflow\n\nThe typical workflow is: generate domain permutations -> resolve DNS records -> check for registered domains -> compare web page similarity -> flag suspicious domains -> alert security team -> request takedown. For a typical corporate domain, dnstwist generates 5,000-10,000 permutations.\n\n## Workflow\n\n### Step 1: Basic Domain Permutation Scan\n\n```python\nimport subprocess\nimport json\nimport csv\nfrom datetime import datetime\n\ndef run_dnstwist_scan(domain, output_file=None):\n    \"\"\"Run dnstwist scan against a target domain.\"\"\"\n    cmd = [\n        \"dnstwist\",\n        \"--registered\",     # Only show registered domains\n        \"--format\", \"json\", # Output in JSON\n        \"--nameservers\", \"8.8.8.8,1.1.1.1\",\n        \"--threads\", \"50\",\n        \"--mxcheck\",        # Check MX records\n        \"--ssdeep\",         # Fuzzy hash comparison\n        \"--geoip\",          # GeoIP lookup\n        domain,\n    ]\n\n    print(f\"[*] Scanning permutations for: {domain}\")\n    result = subprocess.run(cmd, capture_output=True, text=True, timeout=600)\n\n    if result.returncode == 0:\n        results = json.loads(result.stdout)\n        registered = [r for r in results if r.get(\"dns_a\") or r.get(\"dns_aaaa\")]\n        print(f\"[+] Found {len(registered)} registered lookalike domains\")\n\n        if output_file:\n            with open(output_file, \"w\") as f:\n                json.dump(registered, f, indent=2)\n            print(f\"[+] Results saved to {output_file}\")\n\n        return registered\n    else:\n        print(f\"[-] dnstwist error: {result.stderr}\")\n        return []\n\nresults = run_dnstwist_scan(\"example.com\", \"typosquat_results.json\")\n```\n\n### Step 2: Analyze and Prioritize Results\n\n```python\ndef analyze_results(results, legitimate_ips=None):\n    \"\"\"Analyze dnstwist results and prioritize threats.\"\"\"\n    legitimate_ips = legitimate_ips or set()\n    high_risk = []\n    medium_risk = []\n    low_risk = []\n\n    for entry in results:\n        domain = entry.get(\"domain\", \"\")\n        fuzzer = entry.get(\"fuzzer\", \"\")\n        dns_a = entry.get(\"dns_a\", [])\n        dns_mx = entry.get(\"dns_mx\", [])\n        ssdeep_score = entry.get(\"ssdeep_score\", 0)\n\n        risk_score = 0\n        risk_factors = []\n\n        # High similarity to legitimate site\n        if ssdeep_score and ssdeep_score > 50:\n            risk_score += 40\n            risk_factors.append(f\"high web similarity ({ssdeep_score}%)\")\n\n        # Has MX records (can receive email \u002F phishing)\n        if dns_mx:\n            risk_score += 20\n            risk_factors.append(\"has MX records (email capable)\")\n\n        # Recently registered (if whois data available)\n        whois_created = entry.get(\"whois_created\", \"\")\n        if whois_created:\n            try:\n                created = datetime.fromisoformat(whois_created.replace(\"Z\", \"+00:00\"))\n                age_days = (datetime.now(created.tzinfo) - created).days\n                if age_days \u003C 30:\n                    risk_score += 30\n                    risk_factors.append(f\"recently registered ({age_days} days)\")\n                elif age_days \u003C 90:\n                    risk_score += 15\n                    risk_factors.append(f\"registered {age_days} days ago\")\n            except (ValueError, TypeError):\n                pass\n\n        # Homoglyph attacks are highest risk\n        if fuzzer == \"homoglyph\":\n            risk_score += 25\n            risk_factors.append(\"homoglyph (visually identical)\")\n        elif fuzzer in (\"addition\", \"replacement\", \"transposition\"):\n            risk_score += 10\n            risk_factors.append(f\"permutation type: {fuzzer}\")\n\n        # Not pointing to legitimate infrastructure\n        if dns_a and not set(dns_a).intersection(legitimate_ips):\n            risk_score += 10\n            risk_factors.append(\"different IP from legitimate\")\n\n        entry[\"risk_score\"] = risk_score\n        entry[\"risk_factors\"] = risk_factors\n\n        if risk_score >= 50:\n            high_risk.append(entry)\n        elif risk_score >= 25:\n            medium_risk.append(entry)\n        else:\n            low_risk.append(entry)\n\n    high_risk.sort(key=lambda x: x[\"risk_score\"], reverse=True)\n    medium_risk.sort(key=lambda x: x[\"risk_score\"], reverse=True)\n\n    print(f\"\\n=== Typosquatting Analysis ===\")\n    print(f\"High Risk: {len(high_risk)}\")\n    print(f\"Medium Risk: {len(medium_risk)}\")\n    print(f\"Low Risk: {len(low_risk)}\")\n\n    if high_risk:\n        print(f\"\\n--- High Risk Domains ---\")\n        for entry in high_risk[:10]:\n            print(f\"  {entry['domain']} (score: {entry['risk_score']})\")\n            for factor in entry['risk_factors']:\n                print(f\"    - {factor}\")\n\n    return {\"high\": high_risk, \"medium\": medium_risk, \"low\": low_risk}\n\nanalysis = analyze_results(results, legitimate_ips={\"93.184.216.34\"})\n```\n\n### Step 3: Continuous Monitoring Pipeline\n\n```python\nimport time\nimport hashlib\n\nclass TyposquatMonitor:\n    def __init__(self, domains, known_domains_file=\"known_typosquats.json\"):\n        self.domains = domains\n        self.known_file = known_domains_file\n        self.known_domains = self._load_known()\n\n    def _load_known(self):\n        try:\n            with open(self.known_file, \"r\") as f:\n                return json.load(f)\n        except FileNotFoundError:\n            return {}\n\n    def _save_known(self):\n        with open(self.known_file, \"w\") as f:\n            json.dump(self.known_domains, f, indent=2)\n\n    def scan_all_domains(self):\n        \"\"\"Scan all monitored domains for new typosquats.\"\"\"\n        new_findings = []\n        for domain in self.domains:\n            results = run_dnstwist_scan(domain)\n            for entry in results:\n                domain_key = entry.get(\"domain\", \"\")\n                if domain_key not in self.known_domains:\n                    entry[\"first_seen\"] = datetime.now().isoformat()\n                    entry[\"monitored_domain\"] = domain\n                    self.known_domains[domain_key] = entry\n                    new_findings.append(entry)\n                    print(f\"  [NEW] {domain_key} ({entry.get('fuzzer', '')})\")\n\n        self._save_known()\n        print(f\"\\n[+] New typosquatting domains found: {len(new_findings)}\")\n        return new_findings\n\n    def generate_alert(self, findings):\n        \"\"\"Generate alert for new high-risk typosquatting domains.\"\"\"\n        analysis = analyze_results(findings)\n        alerts = []\n        for entry in analysis[\"high\"]:\n            alerts.append({\n                \"severity\": \"HIGH\",\n                \"domain\": entry[\"domain\"],\n                \"target\": entry.get(\"monitored_domain\", \"\"),\n                \"risk_score\": entry[\"risk_score\"],\n                \"risk_factors\": entry[\"risk_factors\"],\n                \"dns_a\": entry.get(\"dns_a\", []),\n                \"dns_mx\": entry.get(\"dns_mx\", []),\n                \"timestamp\": datetime.now().isoformat(),\n            })\n        return alerts\n\nmonitor = TyposquatMonitor([\"mycompany.com\", \"mycompany.org\"])\nnew_findings = monitor.scan_all_domains()\nalerts = monitor.generate_alert(new_findings)\n```\n\n### Step 4: Export for Blocklist and Takedown\n\n```python\ndef export_blocklist(analysis, output_file=\"blocklist.txt\"):\n    \"\"\"Export high-risk domains as blocklist for firewall\u002Fproxy.\"\"\"\n    domains = []\n    for entry in analysis[\"high\"] + analysis[\"medium\"]:\n        domain = entry.get(\"domain\", \"\")\n        if domain:\n            domains.append(domain)\n\n    with open(output_file, \"w\") as f:\n        f.write(f\"# Typosquatting blocklist generated {datetime.now().isoformat()}\\n\")\n        for d in sorted(set(domains)):\n            f.write(f\"{d}\\n\")\n\n    print(f\"[+] Blocklist saved: {len(domains)} domains -> {output_file}\")\n    return domains\n\ndef generate_takedown_report(high_risk_domains):\n    \"\"\"Generate takedown request report.\"\"\"\n    report = f\"\"\"# Domain Takedown Request\nGenerated: {datetime.now().isoformat()}\n\n## Summary\n{len(high_risk_domains)} domains identified as potential typosquatting\u002Fphishing.\n\n## Domains Requiring Takedown\n\"\"\"\n    for entry in high_risk_domains:\n        report += f\"\"\"\n### {entry['domain']}\n- **Permutation Type**: {entry.get('fuzzer', 'unknown')}\n- **IP Address**: {', '.join(entry.get('dns_a', ['N\u002FA']))}\n- **MX Records**: {', '.join(entry.get('dns_mx', ['N\u002FA']))}\n- **Risk Score**: {entry.get('risk_score', 0)}\n- **Risk Factors**: {'; '.join(entry.get('risk_factors', []))}\n- **Web Similarity**: {entry.get('ssdeep_score', 'N\u002FA')}%\n\"\"\"\n    with open(\"takedown_report.md\", \"w\") as f:\n        f.write(report)\n    print(\"[+] Takedown report generated: takedown_report.md\")\n\nexport_blocklist(analysis)\ngenerate_takedown_report(analysis[\"high\"])\n```\n\n## Validation Criteria\n\n- DNSTwist generates domain permutations for target domain\n- DNS resolution identifies registered lookalike domains\n- Web similarity scoring detects cloned phishing pages\n- Risk scoring prioritizes domains by threat level\n- Continuous monitoring detects newly registered typosquats\n- Blocklist and takedown reports generated correctly\n\n## References\n\n- [dnstwist GitHub Repository](https:\u002F\u002Fgithub.com\u002Felceef\u002Fdnstwist)\n- [dnstwister Online Service](https:\u002F\u002Fdnstwister.report\u002F)\n- [HawkEye: Detect Typosquatting with DNSTwist](https:\u002F\u002Fhawk-eye.io\u002F2022\u002F11\u002Fhow-to-detect-typosquatting-using-dnstwist\u002F)\n- [Darktrace: Monitoring Typosquatting Domains](https:\u002F\u002Fwww.darktrace.com\u002Fblog\u002Fvigilance-in-action-monitoring-typosquatting-domains)\n- [Security Risk Advisors: Domain Monitoring](https:\u002F\u002Fsra.io\u002Fblog\u002Fdomain-monitoring-fast-and-cheap\u002F)\n- [Conscia: How to Detect Typosquatting](https:\u002F\u002Fconscia.com\u002Fblog\u002Fdiving-deep-how-to-detect-typosquatting\u002F)\n","# Analyzing Typosquatting Domains with DNSTwist\n\n## Overview\n\nDNSTwist is a domain name permutation engine that generates similar-looking domain names to detect typosquatting, homograph phishing attacks, and brand impersonation. It creates thousands of domain permutations using techniques like character substitution, transposition, insertion, omission, and homoglyph replacement, then checks DNS records (A, AAAA, NS, MX), calculates web page similarity using fuzzy hashing (ssdeep) and perceptual hashing (pHash), and identifies potentially malicious registered domains.\n\n\n## When to Use\n\n- When investigating security incidents that require analyzing typosquatting domains with dnstwist\n- When building detection rules or threat hunting queries for this domain\n- When SOC analysts need structured procedures for this analysis type\n- When validating security monitoring coverage for related attack techniques\n\n## Prerequisites\n\n- Python 3.9+ with `dnstwist` installed (`pip install dnstwist[full]`)\n- Optional: GeoIP database for IP geolocation\n- Optional: Shodan API key for enrichment\n- Network access to perform DNS queries\n- Understanding of DNS record types and domain registration\n\n## Key Concepts\n\n### Domain Permutation Techniques\n\nDNSTwist generates permutations using: addition (appending characters), bitsquatting (bit-flip errors), homoglyph (visually similar Unicode characters like rn vs m), hyphenation (adding hyphens), insertion (inserting characters), omission (removing characters), repetition (repeating characters), replacement (replacing with adjacent keyboard keys), subdomain (inserting dots), transposition (swapping adjacent characters), vowel-swap (swapping vowels), and dictionary-based (appending common words).\n\n### Fuzzy Hashing and Visual Similarity\n\nDNSTwist uses ssdeep (locality-sensitive hash) to compare HTML content and pHash (perceptual hash) to compare screenshots of web pages. This helps identify cloned phishing sites that visually mimic the legitimate site. A high similarity score indicates a likely phishing page.\n\n### Detection Workflow\n\nThe typical workflow is: generate domain permutations -> resolve DNS records -> check for registered domains -> compare web page similarity -> flag suspicious domains -> alert security team -> request takedown. For a typical corporate domain, dnstwist generates 5,000-10,000 permutations.\n\n## Workflow\n\n### Step 1: Basic Domain Permutation Scan\n\n```python\nimport subprocess\nimport json\nimport csv\nfrom datetime import datetime\n\ndef run_dnstwist_scan(domain, output_file=None):\n    \"\"\"Run dnstwist scan against a target domain.\"\"\"\n    cmd = [\n        \"dnstwist\",\n        \"--registered\",     # Only show registered domains\n        \"--format\", \"json\", # Output in JSON\n        \"--nameservers\", \"8.8.8.8,1.1.1.1\",\n        \"--threads\", \"50\",\n        \"--mxcheck\",        # Check MX records\n        \"--ssdeep\",         # Fuzzy hash comparison\n        \"--geoip\",          # GeoIP lookup\n        domain,\n    ]\n\n    print(f\"[*] Scanning permutations for: {domain}\")\n    result = subprocess.run(cmd, capture_output=True, text=True, timeout=600)\n\n    if result.returncode == 0:\n        results = json.loads(result.stdout)\n        registered = [r for r in results if r.get(\"dns_a\") or r.get(\"dns_aaaa\")]\n        print(f\"[+] Found {len(registered)} registered lookalike domains\")\n\n        if output_file:\n            with open(output_file, \"w\") as f:\n                json.dump(registered, f, indent=2)\n            print(f\"[+] Results saved to {output_file}\")\n\n        return registered\n    else:\n        print(f\"[-] dnstwist error: {result.stderr}\")\n        return []\n\nresults = run_dnstwist_scan(\"example.com\", \"typosquat_results.json\")\n```\n\n### Step 2: Analyze and Prioritize Results\n\n```python\ndef analyze_results(results, legitimate_ips=None):\n    \"\"\"Analyze dnstwist results and prioritize threats.\"\"\"\n    legitimate_ips = legitimate_ips or set()\n    high_risk = []\n    medium_risk = []\n    low_risk = []\n\n    for entry in results:\n        domain = entry.get(\"domain\", \"\")\n        fuzzer = entry.get(\"fuzzer\", \"\")\n        dns_a = entry.get(\"dns_a\", [])\n        dns_mx = entry.get(\"dns_mx\", [])\n        ssdeep_score = entry.get(\"ssdeep_score\", 0)\n\n        risk_score = 0\n        risk_factors = []\n\n        # High similarity to legitimate site\n        if ssdeep_score and ssdeep_score > 50:\n            risk_score += 40\n            risk_factors.append(f\"high web similarity ({ssdeep_score}%)\")\n\n        # Has MX records (can receive email \u002F phishing)\n        if dns_mx:\n            risk_score += 20\n            risk_factors.append(\"has MX records (email capable)\")\n\n        # Recently registered (if whois data available)\n        whois_created = entry.get(\"whois_created\", \"\")\n        if whois_created:\n            try:\n                created = datetime.fromisoformat(whois_created.replace(\"Z\", \"+00:00\"))\n                age_days = (datetime.now(created.tzinfo) - created).days\n                if age_days \u003C 30:\n                    risk_score += 30\n                    risk_factors.append(f\"recently registered ({age_days} days)\")\n                elif age_days \u003C 90:\n                    risk_score += 15\n                    risk_factors.append(f\"registered {age_days} days ago\")\n            except (ValueError, TypeError):\n                pass\n\n        # Homoglyph attacks are highest risk\n        if fuzzer == \"homoglyph\":\n            risk_score += 25\n            risk_factors.append(\"homoglyph (visually identical)\")\n        elif fuzzer in (\"addition\", \"replacement\", \"transposition\"):\n            risk_score += 10\n            risk_factors.append(f\"permutation type: {fuzzer}\")\n\n        # Not pointing to legitimate infrastructure\n        if dns_a and not set(dns_a).intersection(legitimate_ips):\n            risk_score += 10\n            risk_factors.append(\"different IP from legitimate\")\n\n        entry[\"risk_score\"] = risk_score\n        entry[\"risk_factors\"] = risk_factors\n\n        if risk_score >= 50:\n            high_risk.append(entry)\n        elif risk_score >= 25:\n            medium_risk.append(entry)\n        else:\n            low_risk.append(entry)\n\n    high_risk.sort(key=lambda x: x[\"risk_score\"], reverse=True)\n    medium_risk.sort(key=lambda x: x[\"risk_score\"], reverse=True)\n\n    print(f\"\\n=== Typosquatting Analysis ===\")\n    print(f\"High Risk: {len(high_risk)}\")\n    print(f\"Medium Risk: {len(medium_risk)}\")\n    print(f\"Low Risk: {len(low_risk)}\")\n\n    if high_risk:\n        print(f\"\\n--- High Risk Domains ---\")\n        for entry in high_risk[:10]:\n            print(f\"  {entry['domain']} (score: {entry['risk_score']})\")\n            for factor in entry['risk_factors']:\n                print(f\"    - {factor}\")\n\n    return {\"high\": high_risk, \"medium\": medium_risk, \"low\": low_risk}\n\nanalysis = analyze_results(results, legitimate_ips={\"93.184.216.34\"})\n```\n\n### Step 3: Continuous Monitoring Pipeline\n\n```python\nimport time\nimport hashlib\n\nclass TyposquatMonitor:\n    def __init__(self, domains, known_domains_file=\"known_typosquats.json\"):\n        self.domains = domains\n        self.known_file = known_domains_file\n        self.known_domains = self._load_known()\n\n    def _load_known(self):\n        try:\n            with open(self.known_file, \"r\") as f:\n                return json.load(f)\n        except FileNotFoundError:\n            return {}\n\n    def _save_known(self):\n        with open(self.known_file, \"w\") as f:\n            json.dump(self.known_domains, f, indent=2)\n\n    def scan_all_domains(self):\n        \"\"\"Scan all monitored domains for new typosquats.\"\"\"\n        new_findings = []\n        for domain in self.domains:\n            results = run_dnstwist_scan(domain)\n            for entry in results:\n                domain_key = entry.get(\"domain\", \"\")\n                if domain_key not in self.known_domains:\n                    entry[\"first_seen\"] = datetime.now().isoformat()\n                    entry[\"monitored_domain\"] = domain\n                    self.known_domains[domain_key] = entry\n                    new_findings.append(entry)\n                    print(f\"  [NEW] {domain_key} ({entry.get('fuzzer', '')})\")\n\n        self._save_known()\n        print(f\"\\n[+] New typosquatting domains found: {len(new_findings)}\")\n        return new_findings\n\n    def generate_alert(self, findings):\n        \"\"\"Generate alert for new high-risk typosquatting domains.\"\"\"\n        analysis = analyze_results(findings)\n        alerts = []\n        for entry in analysis[\"high\"]:\n            alerts.append({\n                \"severity\": \"HIGH\",\n                \"domain\": entry[\"domain\"],\n                \"target\": entry.get(\"monitored_domain\", \"\"),\n                \"risk_score\": entry[\"risk_score\"],\n                \"risk_factors\": entry[\"risk_factors\"],\n                \"dns_a\": entry.get(\"dns_a\", []),\n                \"dns_mx\": entry.get(\"dns_mx\", []),\n                \"timestamp\": datetime.now().isoformat(),\n            })\n        return alerts\n\nmonitor = TyposquatMonitor([\"mycompany.com\", \"mycompany.org\"])\nnew_findings = monitor.scan_all_domains()\nalerts = monitor.generate_alert(new_findings)\n```\n\n### Step 4: Export for Blocklist and Takedown\n\n```python\ndef export_blocklist(analysis, output_file=\"blocklist.txt\"):\n    \"\"\"Export high-risk domains as blocklist for firewall\u002Fproxy.\"\"\"\n    domains = []\n    for entry in analysis[\"high\"] + analysis[\"medium\"]:\n        domain = entry.get(\"domain\", \"\")\n        if domain:\n            domains.append(domain)\n\n    with open(output_file, \"w\") as f:\n        f.write(f\"# Typosquatting blocklist generated {datetime.now().isoformat()}\\n\")\n        for d in sorted(set(domains)):\n            f.write(f\"{d}\\n\")\n\n    print(f\"[+] Blocklist saved: {len(domains)} domains -> {output_file}\")\n    return domains\n\ndef generate_takedown_report(high_risk_domains):\n    \"\"\"Generate takedown request report.\"\"\"\n    report = f\"\"\"# Domain Takedown Request\nGenerated: {datetime.now().isoformat()}\n\n## Summary\n{len(high_risk_domains)} domains identified as potential typosquatting\u002Fphishing.\n\n## Domains Requiring Takedown\n\"\"\"\n    for entry in high_risk_domains:\n        report += f\"\"\"\n### {entry['domain']}\n- **Permutation Type**: {entry.get('fuzzer', 'unknown')}\n- **IP Address**: {', '.join(entry.get('dns_a', ['N\u002FA']))}\n- **MX Records**: {', '.join(entry.get('dns_mx', ['N\u002FA']))}\n- **Risk Score**: {entry.get('risk_score', 0)}\n- **Risk Factors**: {'; '.join(entry.get('risk_factors', []))}\n- **Web Similarity**: {entry.get('ssdeep_score', 'N\u002FA')}%\n\"\"\"\n    with open(\"takedown_report.md\", \"w\") as f:\n        f.write(report)\n    print(\"[+] Takedown report generated: takedown_report.md\")\n\nexport_blocklist(analysis)\ngenerate_takedown_report(analysis[\"high\"])\n```\n\n## Validation Criteria\n\n- DNSTwist generates domain permutations for target domain\n- DNS resolution identifies registered lookalike domains\n- Web similarity scoring detects cloned phishing pages\n- Risk scoring prioritizes domains by threat level\n- Continuous monitoring detects newly registered typosquats\n- Blocklist and takedown reports generated correctly\n\n## References\n\n- [dnstwist GitHub Repository](https:\u002F\u002Fgithub.com\u002Felceef\u002Fdnstwist)\n- [dnstwister Online Service](https:\u002F\u002Fdnstwister.report\u002F)\n- [HawkEye: Detect Typosquatting with DNSTwist](https:\u002F\u002Fhawk-eye.io\u002F2022\u002F11\u002Fhow-to-detect-typosquatting-using-dnstwist\u002F)\n- [Darktrace: Monitoring Typosquatting Domains](https:\u002F\u002Fwww.darktrace.com\u002Fblog\u002Fvigilance-in-action-monitoring-typosquatting-domains)\n- [Security Risk Advisors: Domain Monitoring](https:\u002F\u002Fsra.io\u002Fblog\u002Fdomain-monitoring-fast-and-cheap\u002F)\n- [Conscia: How to Detect Typosquatting](https:\u002F\u002Fconscia.com\u002Fblog\u002Fdiving-deep-how-to-detect-typosquatting\u002F)\n",{"name":5,"tags":57,"author":62,"domain":46,"license":15,"version":63,"nist_csf":64,"subdomain":49,"description":7,"mitre_attack":69,"atlas_techniques":74},[35,36,58,59,60,61,48,49],"phishing","domain-monitoring","brand-protection","homograph","mahipal","1.0",[65,66,67,68],"ID.RA-01","ID.RA-05","DE.CM-01","DE.AE-02",[70,71,72,73],"T1583.001","T1566.002","T1598.003","T1583.006",[75,76],"AML.T0073","AML.T0052","main","7925716f065257435fdb12e97f7e52842147d5ad",".claude\u002Fskills\u002Fanalyzing-typosquatting-domains-with-dnstwist","https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude","https:\u002F\u002Fclaude.com\u002Fclaude-code","https:\u002F\u002Fgithub.com\u002Fhenriquescastilho","Software · Applied AI · Quantitative Modeling · Building with Claude.","2026-06-10 12:24:46",{"source":8,"skillName":5,"commands":86,"prompt":96,"zipAvailable":97},[87,90,93],{"tool":88,"command":89},"npx","npx skills add henriquescastilho\u002Fmy-claude --skill analyzing-typosquatting-domains-with-dnstwist",{"tool":91,"command":92},"bunx","bunx skills add henriquescastilho\u002Fmy-claude --skill analyzing-typosquatting-domains-with-dnstwist",{"tool":94,"command":95},"pnpm","pnpm dlx skills add henriquescastilho\u002Fmy-claude --skill analyzing-typosquatting-domains-with-dnstwist","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fanalyzing-typosquatting-domains-with-dnstwist\u002FSKILL.md",true,[99,105,110,116],{"path":100,"resourceType":101,"resourceTypeDesc":102,"sizeBytes":103,"sourceHtmlUrl":104},"customize.toml","OTHER","其他",3674,"https:\u002F\u002Fgithub.com\u002Fdeveloperworks\u002Frust-supervisor\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fwds-agent-saga-analyst\u002Fcustomize.toml",{"path":106,"resourceType":106,"resourceTypeDesc":107,"sizeBytes":108,"sourceHtmlUrl":109},"LICENSE","许可证",11255,"https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fanalyzing-typosquatting-domains-with-dnstwist\u002FLICENSE",{"path":111,"resourceType":112,"resourceTypeDesc":113,"sizeBytes":114,"sourceHtmlUrl":115},"references\u002Fapi-reference.md","REFERENCE","参考文档",2155,"https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fanalyzing-typosquatting-domains-with-dnstwist\u002Freferences\u002Fapi-reference.md",{"path":117,"resourceType":118,"resourceTypeDesc":119,"sizeBytes":120,"sourceHtmlUrl":121},"scripts\u002Fagent.py","SCRIPT","脚本",3614,"https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fanalyzing-typosquatting-domains-with-dnstwist\u002Fscripts\u002Fagent.py",[123,161,170,179,201,227],{"skillNo":124,"name":125,"nameZh":6,"description":126,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":127,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":142,"publishedAt":52},"01M6F0B6XPQ65AX2X0DWK8KT3E","markitdown","Convert files and office documents to Markdown. Supports PDF, DOCX, PPTX, XLSX, images (with OCR), audio (with transcription), HTML, CSV, JSON, XML, ZIP, YouTube URLs, EPubs and more.","MIT","https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.codex\u002Fvendor_imports\u002Fclaude\u002Fmarketplaces\u002Fclaude-scientific-writer\u002Fskills\u002Fmarkitdown\u002FSKILL.md",[130,133,136,139],{"categoryNo":131,"categoryName":132,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000002","文档处理",{"categoryNo":134,"categoryName":135,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":137,"categoryName":138,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000004","电子表格",{"categoryNo":140,"categoryName":141,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000034","行政与办公人员",[125,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,32],"docx","PDF","pptx","xlsx","documents","csv","ocr","Audio","Bash","markdown","convert","read","write","edit","html","images","files","youtube",{"skillNo":162,"name":125,"nameZh":6,"description":126,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":127,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":169,"publishedAt":52},"01M6F06SBHR9F0SDWE282Y8075","https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.codex\u002Fvendor_imports\u002Fclaude\u002Fmarketplaces\u002Fclaude-scientific-writer\u002Fscientific_writer\u002F.claude\u002Fskills\u002Fmarkitdown\u002FSKILL.md",[165,166,167,168],{"categoryNo":131,"categoryName":132,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":134,"categoryName":135,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":137,"categoryName":138,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":140,"categoryName":141,"taxonomyType":29,"taxonomyTypeDesc":30},[125,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,32],{"skillNo":171,"name":125,"nameZh":6,"description":126,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":127,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":178,"publishedAt":52},"01M6F02D4R14EJAPBWVDF9J9VQ","https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.codex\u002Fvendor_imports\u002Fclaude\u002Fmarketplaces\u002Fclaude-scientific-writer\u002F.claude\u002Fskills\u002Fmarkitdown\u002FSKILL.md",[174,175,176,177],{"categoryNo":131,"categoryName":132,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":134,"categoryName":135,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":137,"categoryName":138,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":140,"categoryName":141,"taxonomyType":29,"taxonomyTypeDesc":30},[125,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,32],{"skillNo":180,"name":181,"nameZh":6,"description":182,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":127,"licenseFileUrl":6,"sourceHtmlUrl":183,"categories":184,"keywords":185,"publishedAt":52},"01M6F000KS6YB4MKS774G4R8ND","zarr-python","Chunked N-D arrays for cloud storage. Compressed arrays, parallel I\u002FO, S3\u002FGCS integration, NumPy\u002FDask\u002FXarray compatible, for large-scale scientific computing pipelines.","https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.codex\u002Fvendor_imports\u002Fclaude\u002Fmarketplaces\u002Fclaude-scientific-skills\u002Fscientific-skills\u002Fzarr-python\u002FSKILL.md",[],[186,187,188,189,190,191,192,193,194,195,196,197,198,199,200],"python","zarr python","storage","integration","s3","gcs","cloud","dask","parallel","pipelines","arrays","numpy","scientific computing","scale","scientific",{"skillNo":202,"name":203,"nameZh":6,"description":204,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":127,"licenseFileUrl":6,"sourceHtmlUrl":205,"categories":206,"keywords":208,"publishedAt":52},"01M6EZZJWFXM1GR78KTW6J0DN8","what-if-oracle","Run structured What-If scenario analysis with multi-branch possibility exploration. Use this skill when the user asks speculative questions like \"what if...\", \"what would happen if...\", \"what are the possibilities\", \"explore scenarios\", \"scenario analysis\", \"possibility space\", \"what could go wrong\", \"best case \u002F worst case\", \"risk analysis\", \"contingency planning\", \"strategic options\", or any question about uncertain futures. Also trigger when the user faces a fork-in-the-road decision, wants to stress-test an idea, or needs to think through consequences before committing.","https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.codex\u002Fvendor_imports\u002Fclaude\u002Fmarketplaces\u002Fclaude-scientific-skills\u002Fscientific-skills\u002Fwhat-if-oracle\u002FSKILL.md",[207],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[209,210,211,212,213,214,215,216,217,218,219,154,155,220,221,222,223,224,225,226],"oracle","what if oracle","go","run","ux","futures","analysis","explore","decision","branch","question","idea","exploration","options","stress-test","strategies","scenario","stress",{"skillNo":228,"name":229,"nameZh":6,"description":230,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":127,"licenseFileUrl":6,"sourceHtmlUrl":231,"categories":232,"keywords":243,"publishedAt":52},"01M6EZZCXAEB49RXGQCJX5E8GB","venue-templates","Access comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.","https:\u002F\u002Fgithub.com\u002Fhenriquescastilho\u002Fmy-claude\u002Fblob\u002Fmain\u002F.codex\u002Fvendor_imports\u002Fclaude\u002Fmarketplaces\u002Fclaude-scientific-skills\u002Fscientific-skills\u002Fvenue-templates\u002FSKILL.md",[233,236,239,240],{"categoryNo":234,"categoryName":235,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":237,"categoryName":238,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":241,"categoryName":242,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000036","内容创作者",[244,245,246,247,248,249,250,251,151,252,154,155,156,253,254,255,256,257,200,258],"templates","venue templates","research","guidelines","NeurIPS","ICML","LaTeX","science","access","proposals","Academic","requirements","formatting","journal","chi"]