CTF Intelligence Logger
Shared 11/26/2025
1 views
Visual Workflow
JSON Code
{
"id": "d7MqOii25oa081rK",
"meta": {
"instanceId": "b4787eb171de34ac12b600a6a5ff5617324ffcb61f922c9059728f0d025e9bea"
},
"name": "CTF Intelligence Logger",
"tags": [],
"nodes": [
{
"id": "dac2f652-d19d-4ef1-95f4-a81c57458b75",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1024,
0
],
"parameters": {
"text": "=# OVERVIEW\n\nYou are a cybersecurity documentation assistant specialized in CTF (Capture The Flag) and penetration testing engagements. Your role is to maintain and update structured penetration testing notes based on new reconnaissance and exploitation data.\n\n## INPUTS\nYou will receive two inputs:\n\nINPUT1 - New information from reconnaissance activities, which may include:\n\n* Command-line tool outputs (nmap, gobuster, nikto, etc.)\n* HTTP requests and responses\n* Exploit attempts and results\n* Credentials discovered\n* File contents\n* Error messages\n* Any other relevant findings\n\n\nINPUT2 - Existing documentation in markdown format, either:\n\n* An empty/unfilled CTF/pentest template\n* A partially completed template from previous updates\n\n### INPUT1\n\n#### CTF NAME\n\n{{ $json.body.ctf }}\n\n#### EXERCISE\n\n{{ $json.body.exercise }}\n\n#### Analyst Input\n{{ $json.body.log_chunk }}\n\n### INPUT2\n\n{{ $json.data }}\n\n\n# YOUR TASK\n\nAnalyze the new information in INPUT1 and intelligently merge it into INPUT2, following these principles:\nData Extraction\n\nParse command outputs to extract key findings (open ports, services, versions, vulnerabilities)\nIdentify credentials, usernames, passwords, tokens, API keys\nExtract URLs, endpoints, directories, and file paths\nNote version numbers, technologies, and frameworks\nCapture error messages that reveal information\nIdentify potential attack vectors\n\nDocumentation Updates\n\nPopulate empty template sections with relevant findings\nAppend new discoveries to existing sections without removing prior data\nMaintain chronological order of activities where applicable\nCross-reference related findings across sections\nUpdate status indicators (e.g., \"In Progress\" → \"Exploited\")\n\nFormatting Preservation\n\nMaintain the exact markdown structure of INPUT2\nPreserve existing headers, lists, tables, and code blocks\nUse consistent formatting for new entries\nKeep section organization intact\n\nIntelligence Integration\n\nAdd context to raw data (e.g., \"Port 445 open suggests SMB may be exploitable\")\nFlag high-priority findings\nNote relationships between discoveries\nSuggest next steps based on findings\n\n# OUTPUT REQUIREMENTS\n\nCRITICAL: Output ONLY the updated markdown document. Do not include:\n\nExplanatory text before or after the document\nComments about what you changed\nSuggestions or recommendations outside the document structure\nAny wrapper text or metadata\n\nThe output must be a valid, complete markdown document that can directly replace what's in INPUT2.\n\n## Recommendations\n\nWhere appropriate, suggest recommended next steps that the analyst should pursue; try to keep recommendations within relevant sections/subsections of the markdown output (vs. at the very end). Try to be prescriptive in the tools/arguments to use as well as what they should be looking for. Highlight these recommendations by wrapping them in \"==\" tags in accordance with Obsidian syntax (e.g. ==This is a recommendation==). Update any existing recommendations based on new context.\n\n# TYPICAL TEMPLATE SECTIONS\nYour output should maintain sections commonly found in pentest documentation:\n\nTarget Information\nReconnaissance/Enumeration\nService Discovery (ports, versions, technologies)\nWeb Application Analysis\nVulnerability Assessment\nExploitation Attempts\nCredentials/Access\nPrivilege Escalation\nPost-Exploitation\nFlags/Objectives\nTimeline/Activity Log\nNotes/Observations\n\nAdapt to whatever structure exists in INPUT2.",
"options": {},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "74ef8816-8d3c-40fa-be98-6248bb992f23",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1024,
176
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "nCN8EEmRAo7xJyZd",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "821119df-65db-48fb-be69-d0cfb45f4a4e",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
864,
0
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "f66daa97-56e5-452c-a71f-948f15a6ae30",
"name": "HTTP Request",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
288,
192
],
"parameters": {
"url": "=http://127.0.0.1:27123/vault/{{ $json.body.ctf }}.md",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth"
},
"credentials": {
"httpBearerAuth": {
"id": "N8y4TJOzhaL2lgCf",
"name": "Bearer Auth account"
}
},
"typeVersion": 4.3,
"alwaysOutputData": true
},
{
"id": "e15ae14d-3c1c-4f0f-88cb-5f844cfbe371",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
432,
192
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "5d94189e-0073-4cf1-89a3-c1a9dfc12e6b",
"operator": {
"type": "object",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.error }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "5d948a2d-ec32-4e1c-972f-ebcbbb577c57",
"name": "HTTP Request1",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
576,
64
],
"parameters": {
"url": "=http://127.0.0.1:27123/vault/{{ $('Webhook').item.json.body.ctf }}.md",
"body": "# (REPLACE WITH CTF NAME)\n\n## (REPLACE WITH NETWORK NAME / ADDRESS SPACE)\nList any relevant network enumeration details here\n### (REPLACE WITH HOST #1)\nList any relevant host enumeration details here\n### (REPLACE HOST #2)\nList any relevant host enumeration details here\n### (REPLACE HOST #3)\nList any relevant host enumeration details here",
"method": "PUT",
"options": {},
"sendBody": true,
"contentType": "raw",
"authentication": "genericCredentialType",
"rawContentType": "text/html",
"genericAuthType": "httpBearerAuth"
},
"credentials": {
"httpBearerAuth": {
"id": "N8y4TJOzhaL2lgCf",
"name": "Bearer Auth account"
}
},
"typeVersion": 4.3,
"alwaysOutputData": true
},
{
"id": "153e0cba-3762-48ed-89a9-cf8be4a24323",
"name": "HTTP Request3",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
1360,
0
],
"parameters": {
"url": "=http://127.0.0.1:27123/vault/{{ $('Webhook').item.json.body.ctf }}.md",
"body": "={{ $json.output }}",
"method": "PUT",
"options": {},
"sendBody": true,
"contentType": "raw",
"authentication": "genericCredentialType",
"rawContentType": "text/html",
"genericAuthType": "httpBearerAuth"
},
"credentials": {
"httpBearerAuth": {
"id": "N8y4TJOzhaL2lgCf",
"name": "Bearer Auth account"
}
},
"typeVersion": 4.3,
"alwaysOutputData": true
},
{
"id": "ffd8f478-39ec-4f66-a027-8bd6a71928f5",
"name": "AI Agent1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1024,
336
],
"parameters": {
"text": "=# OVERVIEW\nYou are a cybersecurity documentation assistant specialized in CTF (Capture The Flag) and penetration testing engagements. Your role is to analyze HTTP traffic and update structured penetration testing notes with relevant findings.\n\n## INPUTS\nYou will receive two inputs:\n\n**INPUT1** - HTTP traffic data containing:\n* CTF Challenge Name\n* Raw HTTP Request\n* Raw HTTP Response\n\n**INPUT2** - Existing documentation in markdown format, either:\n* An empty/unfilled CTF/pentest template\n* A partially completed template from previous updates\n\n### INPUT1\n#### CTF CHALLENGE NAME\n{{ $json.headers['x-burp-challenge'] }}\n\n#### HTTP REQUEST\n{{ $json.body.request_raw }}\n\n#### HTTP RESPONSE\n{{ $json.body.response_raw }}\n\n### INPUT2\n{{ $json.data }}\n\n# YOUR TASK\n\n## Step 1: Relevance Assessment\nFirst, determine if this HTTP request/response contains information of interest for solving the CTF challenge. Consider it relevant if it:\n\n**High Priority Indicators:**\n- Reveals sensitive information (credentials, tokens, API keys, session IDs)\n- Contains flags or parts of flags\n- Exposes system information (versions, paths, configurations)\n- Shows error messages revealing internal workings\n- Demonstrates successful exploitation or authentication\n- Reveals hidden endpoints, parameters, or functionality\n- Contains authentication/authorization mechanisms\n- Shows SQL errors, stack traces, or debug information\n\n**Medium Priority Indicators:**\n- Unique response codes (especially 403, 401, 500, etc.)\n- New endpoints or URL patterns not previously documented\n- Interesting headers (e.g. X-Powered-By, Server, X-Custom headers)\n- Cookie structures and session management details\n- Form fields, input validation behavior\n- Comments in HTML/JavaScript revealing information\n- Technology fingerprints (frameworks, libraries, CMS)\n\n**Ignore if:**\n- Exact duplicate of previously documented request/response\n- Standard static asset requests (CSS, JS, images) with no unusual characteristics\n- Routine requests with generic successful responses containing no new information\n- Health checks or monitoring endpoints with expected responses\n- Requests you can confirm have already been analyzed based on INPUT2 content\n\n## Step 2: Information Extraction\nIf the request/response is relevant, extract:\n\n**From Request:**\n- HTTP method and full URL path\n- Unique parameters and their values\n- Authentication headers (Authorization, Cookie)\n- Custom headers\n- Request body content (especially for POST/PUT)\n- File uploads or multipart data\n\n**From Response:**\n- Status code and reason phrase\n- Revealing headers (Server, X-Powered-By, Set-Cookie, Location, etc.)\n- Body content with security implications\n- Error messages and stack traces\n- Comments in HTML/JavaScript\n- Hidden form fields\n- API responses with sensitive data\n- Redirect chains\n\n**Key Artifacts:**\n- Credentials, tokens, API keys\n- Version numbers and technology fingerprints\n- Directory/file paths\n- Usernames, email addresses\n- Database information from errors\n- Potential injection points\n- Authorization/access control issues\n\n## Step 3: Documentation Updates\nIntegrate relevant findings into INPUT2:\n\n**Populate appropriate sections:**\n- **Web Application Analysis**: Endpoints, parameters, technologies detected\n- **Vulnerability Assessment**: Potential vulnerabilities identified (SQLi, XSS, auth bypass, etc.)\n- **Credentials/Access**: Any authentication material discovered\n- **Flags/Objectives**: If flag or flag components found\n- **Service Discovery**: Technology versions and frameworks\n- **Notes/Observations**: Interesting behaviors or patterns\n- **Timeline/Activity Log**: Timestamp of significant discoveries\n\n**Documentation Guidelines:**\n- Add findings under relevant existing sections\n- Append to existing content without removing prior data, unless it's to update any recommendations.\n- Use code blocks for raw HTTP data when illustrative; Use \"...SNIP...\" when/where appropriate to make content more concise and removing out unnecessarily verbose request/response data.\n- Maintain chronological order within sections\n- Cross-reference related findings\n- Update status indicators as appropriate\n\n## Step 4: Intelligent Context\nAdd analytical value:\n- Explain why a finding matters for the CTF\n- Note potential attack vectors revealed\n- Identify technology-specific vulnerabilities\n- Connect findings to known CVEs when applicable\n- Highlight unusual behaviors or misconfigurations\n\n## Step 5: Recommendations\nProvide actionable next steps using \"==\" highlighting:\n- Specific tools and commands to run (e.g., `sqlmap -u \"URL\" --param`)\n- Additional endpoints to probe\n- Parameters to fuzz or test\n- Credentials to attempt\n- Technologies to research for known exploits\n\nExample: ==Try SQL injection on the 'id' parameter: `sqlmap -u \"http://target/page?id=1\" --batch`==\n\n# OUTPUT REQUIREMENTS\n\n**CRITICAL**: Output ONLY the updated markdown document. Do not include:\n- Explanatory text before or after the document\n- Statements like \"I've analyzed...\" or \"The request appears...\"\n- Comments about what you changed\n- Suggestions or recommendations outside the document structure\n- Any wrapper text, metadata, or conversational responses\n- Add \"http\" to triple backticks (i.e. do not do ```http) to log requests/responses. Obsidian does not process that appropriately. Just use generic triple backtick blocks (i.e. ```)\n- Duplicate information already in INPUT2\n\n**The output must be:**\n- A valid, complete markdown document; if you choose to include the request/response, simply include them in triple backtick blocks (i.e. ```)\n- Ready to directly replace INPUT2\n- Contains only new/updated information if the HTTP traffic was relevant\n- Identical to INPUT2 if the HTTP traffic was not relevant or was a duplicate\n\n# TYPICAL TEMPLATE SECTIONS\nMaintain and populate these common pentest documentation sections:\n- Target Information\n- Reconnaissance/Enumeration\n- Service Discovery\n- Web Application Analysis (endpoints, parameters, forms, cookies, sitemap of discovered endpoints/subdomains)\n- Vulnerability Assessment\n- Exploitation Attempts\n- Credentials/Access\n- Privilege Escalation\n- Post-Exploitation\n- Flags/Objectives\n- Timeline/Activity Log\n- Notes/Observations\n\nAdapt to whatever structure exists in INPUT2.",
"options": {},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "491a172f-729e-4bce-bc02-c048df0b43e1",
"name": "Google Gemini Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1024,
512
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"id": "nCN8EEmRAo7xJyZd",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "d3feabbb-71e1-432a-a8e3-895e52758e12",
"name": "Merge1",
"type": "n8n-nodes-base.merge",
"position": [
864,
336
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "86a9901e-7df8-49a0-8a63-42558f8b2d70",
"name": "HTTP Request4",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
288,
496
],
"parameters": {
"url": "=http://127.0.0.1:27123/vault/{{ $json.headers['x-burp-challenge'] }}.md",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth"
},
"credentials": {
"httpBearerAuth": {
"id": "N8y4TJOzhaL2lgCf",
"name": "Bearer Auth account"
}
},
"typeVersion": 4.3,
"alwaysOutputData": true
},
{
"id": "2f916053-e55a-41d0-b9df-b7f0867fa43a",
"name": "If1",
"type": "n8n-nodes-base.if",
"position": [
432,
496
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "5d94189e-0073-4cf1-89a3-c1a9dfc12e6b",
"operator": {
"type": "object",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.error }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "84dbbfda-62ad-4b53-be9c-9ba1e38bb0a3",
"name": "HTTP Request5",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
576,
368
],
"parameters": {
"url": "=http://127.0.0.1:27123/vault/{{ $('Webhook').item.json.headers['x-burp-challenge'] }}.md",
"body": "# (REPLACE WITH CTF NAME)\n\n## (REPLACE WITH NETWORK NAME / ADDRESS SPACE)\nList any relevant network enumeration details here\n### (REPLACE WITH HOST #1)\nList any relevant host enumeration details here\n### (REPLACE HOST #2)\nList any relevant host enumeration details here\n### (REPLACE HOST #3)\nList any relevant host enumeration details here",
"method": "PUT",
"options": {},
"sendBody": true,
"contentType": "raw",
"authentication": "genericCredentialType",
"rawContentType": "text/html",
"genericAuthType": "httpBearerAuth"
},
"credentials": {
"httpBearerAuth": {
"id": "N8y4TJOzhaL2lgCf",
"name": "Bearer Auth account"
}
},
"typeVersion": 4.3,
"alwaysOutputData": true
},
{
"id": "6610baf8-bec0-4f33-8268-60ffcaf05b25",
"name": "HTTP Request7",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
1360,
336
],
"parameters": {
"url": "=http://127.0.0.1:27123/vault/{{ $('Webhook').item.json.headers['x-burp-challenge'] }}.md",
"body": "={{ $json.output }}",
"method": "PUT",
"options": {},
"sendBody": true,
"contentType": "raw",
"authentication": "genericCredentialType",
"rawContentType": "text/html",
"genericAuthType": "httpBearerAuth"
},
"credentials": {
"httpBearerAuth": {
"id": "N8y4TJOzhaL2lgCf",
"name": "Bearer Auth account"
}
},
"typeVersion": 4.3,
"alwaysOutputData": true
},
{
"id": "4918900f-4944-4771-9ac7-f331598c85bd",
"name": "If2",
"type": "n8n-nodes-base.if",
"onError": "continueRegularOutput",
"position": [
-384,
208
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "5d94189e-0073-4cf1-89a3-c1a9dfc12e6b",
"operator": {
"type": "string",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.body.ctf }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2,
"alwaysOutputData": false
},
{
"id": "4a392375-c970-4cc7-b1c7-82fa10d48c99",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-624,
208
],
"webhookId": "459effc4-533e-47bf-8a15-c2799faf6ef2",
"parameters": {
"path": "459effc4-533e-47bf-8a15-c2799faf6ef2",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
}
],
"active": true,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "0ca3a7b8-914a-4318-8cd4-57a3ed7bcef3",
"connections": {
"If": {
"main": [
[
{
"node": "HTTP Request1",
"type": "main",
"index": 0
}
],
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"If1": {
"main": [
[
{
"node": "HTTP Request5",
"type": "main",
"index": 0
}
],
[
{
"node": "Merge1",
"type": "main",
"index": 1
}
]
]
},
"If2": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
},
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
],
[
{
"node": "HTTP Request4",
"type": "main",
"index": 0
},
{
"node": "Merge1",
"type": "main",
"index": 0
}
]
]
},
"Merge": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Merge1": {
"main": [
[
{
"node": "AI Agent1",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "If2",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "HTTP Request3",
"type": "main",
"index": 0
}
]
]
},
"AI Agent1": {
"main": [
[
{
"node": "HTTP Request7",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request1": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"HTTP Request4": {
"main": [
[
{
"node": "If1",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request5": {
"main": [
[
{
"node": "Merge1",
"type": "main",
"index": 1
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Google Gemini Chat Model1": {
"ai_languageModel": [
[
{
"node": "AI Agent1",
"type": "ai_languageModel",
"index": 0
}
]
]
}
}
}