EnumX: Consulta automática de DNS de subdominios y exportación a Markdown
Este es unSecOpsflujo de automatización del dominio deautomatización que contiene 13 nodos.Utiliza principalmente nodos como Set, Code, Gmail, Merge, HttpRequest. Consulta automatizada de registros de DNS de subdominios usando HackerTarget API y informes de Gmail
- •Cuenta de Google y credenciales de API de Gmail
- •Pueden requerirse credenciales de autenticación para la API de destino
Nodos utilizados (13)
Categoría
{
"id": "RNNkYFKdsO7f3dSi",
"meta": {
"instanceId": "6feff41aadeb8409737e26476f9d0a45f95eec6a9c16afff8ef87a662455b6df",
"templateCredsSetupCompleted": true
},
"name": "EnumX: Auto DNS Lookup for Subdomains with Markdown Export",
"tags": [
{
"id": "gGA3sGFynnEJEGfZ",
"name": "Enumeration Engine",
"createdAt": "2025-07-24T00:23:37.375Z",
"updatedAt": "2025-07-24T00:23:37.375Z"
}
],
"nodes": [
{
"id": "18df8e48-3d79-413e-bac0-a08fdd167866",
"name": "Al hacer clic en 'Ejecutar flujo de trabajo'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-2120,
20
],
"parameters": {},
"typeVersion": 1
},
{
"id": "2ec4a837-11f3-4af3-ac37-345ce4fa9947",
"name": "🌐 Dominio Objetivo",
"type": "n8n-nodes-base.set",
"position": [
-1920,
20
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "0383ffe1-377f-48ad-a476-8e67eabdfefa",
"name": "domain",
"type": "string",
"value": "example.com"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "8d9989c2-4f04-4a12-8eae-04a89152bae2",
"name": "📡 Enumeración de Subdominios",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1700,
20
],
"parameters": {
"url": "=https://api.hackertarget.com/hostsearch/?q={{$json[\"domain\"]}}",
"options": {
"response": {
"response": {
"responseFormat": "text",
"outputPropertyName": ""
}
}
}
},
"typeVersion": 4.2
},
{
"id": "1b26f151-215a-4898-b5a0-5e6f0ed2d39d",
"name": "🧠 Analizar Subdominios",
"type": "n8n-nodes-base.code",
"position": [
-1480,
20
],
"parameters": {
"jsCode": "// Get the first item (raw output from Subdomain Enum)\nconst item = $items(\"📡 Subdomain Enum\")[0];\nconst rawText = Object.values(item.json)[0]; // the unnamed field\n\nconst lines = rawText.split(\"\\n\");\n\nreturn lines\n .filter(line => line.trim() !== \"\")\n .map(line => {\n const [subdomain, ip] = line.split(\",\");\n return { json: { subdomain, ip } };\n });"
},
"typeVersion": 2
},
{
"id": "e9c560c3-4cb9-42f2-9cac-000f71c700d6",
"name": "🌐 Registros DNS",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1240,
160
],
"parameters": {
"url": "=https://api.hackertarget.com/dnslookup/?q={{$json[\"subdomain\"]}}",
"options": {
"response": {
"response": {
"responseFormat": "text",
"outputPropertyName": "dns"
}
}
}
},
"typeVersion": 4.2,
"alwaysOutputData": true
},
{
"id": "3e10f83e-3ec6-41fe-8a9f-c2a62d077f72",
"name": "📝 Formatear DNS en Markdown",
"type": "n8n-nodes-base.code",
"position": [
-640,
40
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const input = $input.item.json;\nconst subdomain = input.subdomain || \"unknown.subdomain\";\n\n// Explicitly access each DNS record type\nconst dnsRecords = {\n A: input.a || [],\n AAAA: input.aaaa || [],\n CNAME: input.cname || [],\n TXT: input.txt || [],\n MX: input.mx || [],\n NS: input.ns || [],\n SOA: input.soa || []\n};\n\nlet markdown = `### DNS Records for: ${subdomain}\\n\\n`;\n\nfor (const [type, records] of Object.entries(dnsRecords)) {\n if (Array.isArray(records) && records.length > 0) {\n const formatted = records.map(r => `- ${r}`).join('\\n');\n markdown += `**${type}**:\\n${formatted}\\n\\n`;\n } else {\n markdown += `**${type}**:\\n- No records found.\\n\\n`;\n }\n}\n\nreturn {\n json: {\n subdomain,\n dns_markdown: markdown.trim()\n }\n};\n"
},
"typeVersion": 2
},
{
"id": "c25357fb-a67b-49dc-8614-28d2d0760884",
"name": "🔗 Fusionar DNS + Subdominio",
"type": "n8n-nodes-base.merge",
"position": [
-840,
40
],
"parameters": {
"mode": "combine",
"options": {},
"joinMode": "keepEverything",
"fieldsToMatchString": "subdomain"
},
"typeVersion": 3.2
},
{
"id": "c55d3e8f-0d07-4e57-a2e7-6658f74edba7",
"name": "🧠 Analizar Registros DNS",
"type": "n8n-nodes-base.code",
"position": [
-1020,
160
],
"parameters": {
"jsCode": "// Get raw text from DNS Lookup node\nconst dnsText = $json.dns || \"No data\";\n\n// Prepare output object\nconst recordTypes = ['A', 'AAAA', 'CNAME', 'TXT', 'MX', 'NS', 'SOA'];\nconst result = {\n subdomain: $json.subdomain || \"unknown.subdomain\"\n};\n\n// Initialize arrays for each type\nfor (const type of recordTypes) {\n result[type.toLowerCase()] = [];\n}\n\n// Parse each line\ndnsText.split('\\n').forEach(line => {\n const match = line.match(/^(\\w+)\\s*:\\s*(.*)$/);\n if (match) {\n const type = match[1].toUpperCase();\n const value = match[2].trim();\n if (recordTypes.includes(type)) {\n result[type.toLowerCase()].push(value);\n }\n }\n});\n\n// If no values found, insert \"No records found\"\nfor (const type of recordTypes) {\n if (result[type.toLowerCase()].length === 0) {\n result[type.toLowerCase()].push(\"No records found.\");\n }\n}\n\nreturn [ { json: result } ];"
},
"typeVersion": 2
},
{
"id": "b4878f12-57b1-48ed-8662-d84227209abe",
"name": "Gmail",
"type": "n8n-nodes-base.gmail",
"position": [
-240,
40
],
"webhookId": "e825199e-fc30-4a63-8b93-8a874b7755a7",
"parameters": {
"sendTo": "security-team@example.com",
"message": "=<pre style=\"font-family: monospace; white-space: pre-wrap;\">{{$json[\"full_report\"]}}</pre>\n<p>—<br>This email was sent automatically with n8n<br><a href=\"https://n8n.io\">https://n8n.io</a></p>",
"options": {},
"subject": "=🧠 DNS Report: All Subdomains"
},
"credentials": {
"gmailOAuth2": {
"id": "wbHKmSEka16PTXzD",
"name": "xiantani"
}
},
"typeVersion": 2.1
},
{
"id": "ff036e1c-a60a-471d-a094-9dad49df4b82",
"name": "🧩 Fusionar Todo el Markdown",
"type": "n8n-nodes-base.code",
"position": [
-440,
40
],
"parameters": {
"jsCode": "const combinedMarkdown = items\n .map(item => item.json.dns_markdown)\n .join('\\n\\n---\\n\\n'); // separator for readability\n\nreturn [\n {\n json: {\n full_report: combinedMarkdown.trim()\n }\n }\n];"
},
"typeVersion": 2
},
{
"id": "77583a90-95c4-4150-893f-c35c280e67d7",
"name": "Nota Adhesiva",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"color": 7,
"width": 700,
"height": 1280,
"content": "\n\n🎯 Purpose\n\nThis workflow automatically scans and collects DNS records for all known subdomains associated with a given domain (e.g., example.com) and emails a formatted markdown report.\n\n🛠️ What It Does\nTakes a list of subdomains\n\nPerforms DNS lookups for records like:\n\nA\n\nAAAA\n\nCNAME\n\nTXT\n\nMX\n\nNS\n\nSOA\n\nFormats the result in Markdown\n\nSends an email report to a designated recipient\n\n🌟 Benefits\nVisibility: Provides ongoing awareness of DNS configurations for each subdomain\n\nSecurity: Helps detect misconfigured, stale, or malicious DNS records\n\nAutomation: Reduces manual checking or use of third-party services\n\nAudit-ready: Output can be stored or forwarded to SOC or IT security\n\nEasy to read: Markdown formatting allows both tech and non-tech users to review reports\n\n🔒 Compliance Alignment\nThis workflow supports compliance and best practices across multiple frameworks:\n| Framework | Relevance |\n| ------------------- | --------------------------------------------------------------------------- |\n| **ISO 27001** | A.12.6.1: Technical vulnerability management (external exposure monitoring) |\n| **NIST CSF** | DE.CM-7: Monitoring for unauthorized connections |\n| **Essential Eight** | Supports vulnerability awareness and passive monitoring |\n| **SOC 2** | Security & Availability — monitoring of system components |\n| **CIS Controls** | Control 1 & 8: Inventory and DNS monitoring of assets |\n\n📬 Current Output Destination\nEmail: abc@gmail.com\n(Editable for any internal SOC, DevOps, or security contact)\n\n📅 Recommended Schedule\nDaily or weekly execution via Cron node\n\nOptional Slack or SIEM integration (future scope)\n\n📌 Tags\n#dns-monitoring #compliance #email-report #subdomain-check #automation #n8n\n"
},
"typeVersion": 1
},
{
"id": "c732eca8-5fb8-439b-900e-567e8f00f86e",
"name": "Nota Adhesiva1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1980,
-140
],
"parameters": {
"color": 7,
"width": 260,
"height": 340,
"content": "\n\n\n✏️ Set your target domain here. \nDefault is \"example.com\". \nYou can also connect this to an external trigger or cron node for periodic scans.\n"
},
"typeVersion": 1
},
{
"id": "9f7c3150-286d-4c67-9230-312c72c119e3",
"name": "Nota Adhesiva2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-300,
-120
],
"parameters": {
"color": 7,
"width": 280,
"height": 360,
"content": "\n\n\n📧 This sends the final DNS Markdown report via email. \nUpdate the recipient address to your own inbox. \nYou can replace Gmail with Slack, Notion, or webhook as needed.\n"
},
"typeVersion": 1
}
],
"active": false,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "beedf29e-0d17-4c06-bb30-fdb9e35053bf",
"connections": {
"e9c560c3-4cb9-42f2-9cac-000f71c700d6": {
"main": [
[
{
"node": "c55d3e8f-0d07-4e57-a2e7-6658f74edba7",
"type": "main",
"index": 0
}
]
]
},
"2ec4a837-11f3-4af3-ac37-345ce4fa9947": {
"main": [
[
{
"node": "8d9989c2-4f04-4a12-8eae-04a89152bae2",
"type": "main",
"index": 0
}
]
]
},
"8d9989c2-4f04-4a12-8eae-04a89152bae2": {
"main": [
[
{
"node": "1b26f151-215a-4898-b5a0-5e6f0ed2d39d",
"type": "main",
"index": 0
}
]
]
},
"1b26f151-215a-4898-b5a0-5e6f0ed2d39d": {
"main": [
[
{
"node": "e9c560c3-4cb9-42f2-9cac-000f71c700d6",
"type": "main",
"index": 0
},
{
"node": "c25357fb-a67b-49dc-8614-28d2d0760884",
"type": "main",
"index": 0
}
]
]
},
"c55d3e8f-0d07-4e57-a2e7-6658f74edba7": {
"main": [
[
{
"node": "c25357fb-a67b-49dc-8614-28d2d0760884",
"type": "main",
"index": 1
}
]
]
},
"ff036e1c-a60a-471d-a094-9dad49df4b82": {
"main": [
[
{
"node": "b4878f12-57b1-48ed-8662-d84227209abe",
"type": "main",
"index": 0
}
]
]
},
"3e10f83e-3ec6-41fe-8a9f-c2a62d077f72": {
"main": [
[
{
"node": "ff036e1c-a60a-471d-a094-9dad49df4b82",
"type": "main",
"index": 0
}
]
]
},
"c25357fb-a67b-49dc-8614-28d2d0760884": {
"main": [
[
{
"node": "3e10f83e-3ec6-41fe-8a9f-c2a62d077f72",
"type": "main",
"index": 0
}
]
]
},
"18df8e48-3d79-413e-bac0-a08fdd167866": {
"main": [
[
{
"node": "2ec4a837-11f3-4af3-ac37-345ce4fa9947",
"type": "main",
"index": 0
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Intermedio - Operaciones de seguridad
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Adnan Tariq
@adnantariqFounder of CYBERPULSE AI — helping security teams and SMEs eliminate repetitive tasks through modular n8n automations. I build workflows for vulnerability triage, compliance reporting, threat intel, and Red/Blue/GRC ops. Book a session if you'd like custom automation for your use case. https://linkedin.com/in/adnan-tariq-4b2a1a47
Compartir este flujo de trabajo