EnumX : Requête DNS automatique des sous-domaines et export Markdown
Ceci est unSecOpsworkflow d'automatisation du domainecontenant 13 nœuds.Utilise principalement des nœuds comme Set, Code, Gmail, Merge, HttpRequest. Requête automatisée d'enregistrements DNS de sous-domaines avec HackerTarget API et rapport Gmail
- •Compte Google et informations d'identification Gmail API
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
Nœuds utilisés (13)
Catégorie
{
"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": "Lors du clic sur 'Exécuter le workflow'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-2120,
20
],
"parameters": {},
"typeVersion": 1
},
{
"id": "2ec4a837-11f3-4af3-ac37-345ce4fa9947",
"name": "🌐 Domaine Cible",
"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": "📡 Énumération des Sous-domaines",
"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": "🧠 Analyse des Sous-domaines",
"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": "🌐 Enregistrements 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": "📝 Formatage Markdown DNS",
"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": "🔗 Fusion DNS + Sous-domaine",
"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": "🧠 Analyse des Enregistrements 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": "🧩 Fusion de Tous les 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": "Note",
"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": "Note1",
"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": "Note2",
"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
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Intermédiaire - Opérations de sécurité
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
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
Partager ce workflow