data model overhaul
This commit is contained in:
@@ -9,6 +9,7 @@ const yamlContent = await fs.readFile(yamlPath, 'utf8');
|
||||
const data = load(yamlContent) as any;
|
||||
const tools = data.tools;
|
||||
const phases = data.phases;
|
||||
const domainAgnosticSoftware = data['domain-agnostic-software'] || []; // Add this line
|
||||
---
|
||||
|
||||
<!-- AI Query Interface -->
|
||||
@@ -88,7 +89,7 @@ const phases = data.phases;
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script define:vars={{ tools, phases }}>
|
||||
<script define:vars={{ tools, phases, domainAgnosticSoftware }}>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const aiInterface = document.getElementById('ai-interface');
|
||||
const aiInput = document.getElementById('ai-query-input');
|
||||
@@ -280,8 +281,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
// Group tools by phase
|
||||
const toolsByPhase = {};
|
||||
|
||||
// Replace hardcoded values with dynamic data from YAML
|
||||
const phaseOrder = phases.filter(phase => phase.id !== 'collaboration-general').map(phase => phase.id);
|
||||
const phaseOrder = phases.map(phase => phase.id);
|
||||
const phaseNames = phases.reduce((acc, phase) => {
|
||||
acc[phase.id] = phase.name;
|
||||
return acc;
|
||||
|
||||
@@ -11,72 +11,79 @@ const data = load(yamlContent) as any;
|
||||
const domains = data.domains;
|
||||
const phases = data.phases;
|
||||
const tools = data.tools;
|
||||
const domainAgnosticSoftware = data['domain-agnostic-software'] || [];
|
||||
|
||||
// Separate collaboration tools from domain-specific tools
|
||||
const collaborationTools = tools.filter((tool: any) =>
|
||||
tool.phases && tool.phases.includes('collaboration-general')
|
||||
);
|
||||
// Get tools for each domain-agnostic section based on the tool's domain-agnostic-software field
|
||||
const domainAgnosticTools = domainAgnosticSoftware.map((section: any) => ({
|
||||
section,
|
||||
tools: tools.filter((tool: any) =>
|
||||
tool['domain-agnostic-software'] && tool['domain-agnostic-software'].includes(section.id)
|
||||
)
|
||||
}));
|
||||
|
||||
const domainTools = tools.filter((tool: any) =>
|
||||
!tool.phases || !tool.phases.includes('collaboration-general')
|
||||
);
|
||||
|
||||
// Create matrix structure for domain-specific tools only
|
||||
// Matrix shows ALL tools based on domains × phases (independent of domain-agnostic-software)
|
||||
const matrix: Record<string, Record<string, any[]>> = {};
|
||||
domains.forEach((domain: any) => {
|
||||
matrix[domain.id] = {};
|
||||
phases.filter((phase: any) => phase.id !== 'collaboration-general').forEach((phase: any) => {
|
||||
matrix[domain.id][phase.id] = domainTools.filter((tool: any) =>
|
||||
tool.domains && tool.domains.includes(domain.id) && tool.phases && tool.phases.includes(phase.id)
|
||||
phases.forEach((phase: any) => {
|
||||
matrix[domain.id][phase.id] = tools.filter((tool: any) =>
|
||||
tool.domains && tool.domains.includes(domain.id) &&
|
||||
tool.phases && tool.phases.includes(phase.id)
|
||||
);
|
||||
});
|
||||
});
|
||||
---
|
||||
|
||||
<div id="matrix-container" class="matrix-wrapper" style="display: none;">
|
||||
<div id="collaboration-tools-section" class="collaboration-section-collapsed" style="margin-bottom: 1.5rem;">
|
||||
<div class="collaboration-header" onclick="toggleCollaborationSection()" style="cursor: pointer; display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.1rem;">
|
||||
<h3 style="margin: 0; color: var(--color-text); font-size: 1.125rem;">Übergreifend & Kollaboration</h3>
|
||||
<div class="collaboration-expand-icon">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="6 9 12 15 18 9"></polyline>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collaboration-content" style="display: none;">
|
||||
<div class="collaboration-tools-compact" id="collaboration-tools-container">
|
||||
{collaborationTools.map((tool: any) => {
|
||||
const hasValidProjectUrl = tool.projectUrl !== undefined &&
|
||||
tool.projectUrl !== null &&
|
||||
tool.projectUrl !== "" &&
|
||||
tool.projectUrl.trim() !== "";
|
||||
return (
|
||||
<div class={`collaboration-tool-compact ${hasValidProjectUrl ? 'hosted' : tool.license !== 'Proprietary' ? 'oss' : ''}`}
|
||||
onclick={`window.showToolDetails('${tool.name}')`}>
|
||||
<div class="tool-compact-header">
|
||||
<h4 style="margin: 0; font-size: 0.875rem; font-weight: 600;">{tool.name}</h4>
|
||||
<div style="display: flex; gap: 0.25rem;">
|
||||
{hasValidProjectUrl && <span class="badge badge--mini badge-primary">Self-Hosted</span>}
|
||||
{tool.license !== 'Proprietary' && <span class="badge badge--mini badge-success">OSS</span>}
|
||||
{tool.knowledgebase === true && <span class="badge badge--mini badge-error">Infos 📖</span>}
|
||||
<!-- Domain-Agnostic Software Sections -->
|
||||
{domainAgnosticTools.map((sectionData: any, index: number) => (
|
||||
<div id={`domain-agnostic-section-${sectionData.section.id}`} class="collaboration-section-collapsed" style="margin-bottom: 1.5rem;">
|
||||
<div class="collaboration-header" onclick={`toggleDomainAgnosticSection('${sectionData.section.id}')`} style="cursor: pointer; display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.1rem;">
|
||||
<h3 style="margin: 0; color: var(--color-text); font-size: 1.125rem;">
|
||||
{sectionData.section.name}
|
||||
<span id={`count-${sectionData.section.id}`} class="badge" style="background-color: var(--color-text-secondary); color: var(--color-bg); margin-left: 0.5rem; font-size: 0.75rem;">
|
||||
{sectionData.tools.length}
|
||||
</span>
|
||||
</h3>
|
||||
<div class="collaboration-expand-icon">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="6 9 12 15 18 9"></polyline>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collaboration-content" style="display: none;">
|
||||
<div class="collaboration-tools-compact" id={`domain-agnostic-tools-${sectionData.section.id}`}>
|
||||
{sectionData.tools.map((tool: any) => {
|
||||
const hasValidProjectUrl = tool.projectUrl !== undefined &&
|
||||
tool.projectUrl !== null &&
|
||||
tool.projectUrl !== "" &&
|
||||
tool.projectUrl.trim() !== "";
|
||||
return (
|
||||
<div class={`collaboration-tool-compact ${hasValidProjectUrl ? 'hosted' : tool.license !== 'Proprietary' ? 'oss' : ''}`}
|
||||
onclick={`window.showToolDetails('${tool.name}')`}>
|
||||
<div class="tool-compact-header">
|
||||
<h4 style="margin: 0; font-size: 0.875rem; font-weight: 600;">{tool.name}</h4>
|
||||
<div style="display: flex; gap: 0.25rem;">
|
||||
{hasValidProjectUrl && <span class="badge badge--mini badge-primary">Self-Hosted</span>}
|
||||
{tool.license !== 'Proprietary' && <span class="badge badge--mini badge-success">OSS</span>}
|
||||
{tool.knowledgebase === true && <span class="badge badge--mini badge-error">Infos 📖</span>}
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted">
|
||||
{tool.description}
|
||||
</p>
|
||||
<div style="display: flex; gap: 0.75rem; font-size: 0.6875rem; color: var(--color-text-secondary);">
|
||||
<span>{tool.platforms.join(', ')}</span>
|
||||
<span>•</span>
|
||||
<span>{tool.skillLevel}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted">
|
||||
{tool.description}
|
||||
</p>
|
||||
<div style="display: flex; gap: 0.75rem; font-size: 0.6875rem; color: var(--color-text-secondary);">
|
||||
<span>{tool.platforms.join(', ')}</span>
|
||||
<span>•</span>
|
||||
<span>{tool.skillLevel}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<!-- DFIR Tools Matrix -->
|
||||
<div id="dfir-matrix-section">
|
||||
@@ -85,7 +92,7 @@ domains.forEach((domain: any) => {
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 200px;">Domain / Phase</th>
|
||||
{phases.filter((phase: any) => phase.id !== 'collaboration-general').map((phase: any) => (
|
||||
{phases.map((phase: any) => (
|
||||
<th data-phase={phase.id}>{phase.name}</th>
|
||||
))}
|
||||
</tr>
|
||||
@@ -94,7 +101,7 @@ domains.forEach((domain: any) => {
|
||||
{domains.map((domain: any) => (
|
||||
<tr data-domain={domain.id}>
|
||||
<th>{domain.name}</th>
|
||||
{phases.filter((phase: any) => phase.id !== 'collaboration-general').map((phase: any) => (
|
||||
{phases.map((phase: any) => (
|
||||
<td class="matrix-cell" data-domain={domain.id} data-phase={phase.id}>
|
||||
{matrix[domain.id][phase.id].map((tool: any) => {
|
||||
const hasValidProjectUrl = tool.projectUrl !== undefined &&
|
||||
@@ -122,7 +129,7 @@ domains.forEach((domain: any) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tool Details Modal -->
|
||||
<!-- Tool Details Modal stays the same -->
|
||||
<div class="modal-overlay" id="modal-overlay" onclick="window.hideToolDetails()"></div>
|
||||
<div class="tool-details" id="tool-details">
|
||||
<div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 1rem;">
|
||||
@@ -143,11 +150,10 @@ domains.forEach((domain: any) => {
|
||||
|
||||
<div id="tool-tags" style="margin-bottom: 1rem;"></div>
|
||||
|
||||
<!-- Updated button container for dual buttons -->
|
||||
<div id="tool-links" style="display: flex; gap: 0.5rem; flex-direction: column;"></div>
|
||||
</div>
|
||||
|
||||
<script define:vars={{ toolsData: tools, collaborationTools, domainTools }}>
|
||||
<script define:vars={{ toolsData: tools, domainAgnosticSoftware, domainAgnosticTools }}>
|
||||
// Helper function to get selected phase from active button
|
||||
function getSelectedPhase() {
|
||||
const activePhaseButton = document.querySelector('.phase-button.active');
|
||||
@@ -200,34 +206,35 @@ domains.forEach((domain: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle collaboration section
|
||||
function toggleCollaborationSection() {
|
||||
const section = document.getElementById('collaboration-tools-section');
|
||||
const content = document.querySelector('.collaboration-content');
|
||||
const icon = document.querySelector('.collaboration-expand-icon svg');
|
||||
|
||||
if (!section || !content || !icon) return;
|
||||
|
||||
const isExpanded = section.classList.contains('collaboration-section-expanded');
|
||||
|
||||
if (isExpanded) {
|
||||
// Collapse
|
||||
section.classList.remove('collaboration-section-expanded');
|
||||
section.classList.add('collaboration-section-collapsed');
|
||||
content.style.display = 'none';
|
||||
icon.style.transform = 'rotate(0deg)';
|
||||
} else {
|
||||
// Expand
|
||||
section.classList.remove('collaboration-section-collapsed');
|
||||
section.classList.add('collaboration-section-expanded');
|
||||
content.style.display = 'block';
|
||||
icon.style.transform = 'rotate(180deg)';
|
||||
// Toggle domain-agnostic section
|
||||
function toggleDomainAgnosticSection(sectionId) {
|
||||
const section = document.getElementById(`domain-agnostic-section-${sectionId}`);
|
||||
const content = section?.querySelector('.collaboration-content');
|
||||
const icon = section?.querySelector('.collaboration-expand-icon svg');
|
||||
|
||||
if (!section || !content || !icon) return;
|
||||
|
||||
const isExpanded = section.classList.contains('collaboration-section-expanded');
|
||||
|
||||
if (isExpanded) {
|
||||
// Collapse
|
||||
section.classList.remove('collaboration-section-expanded');
|
||||
section.classList.add('collaboration-section-collapsed');
|
||||
content.style.display = 'none';
|
||||
icon.style.transform = 'rotate(0deg)';
|
||||
} else {
|
||||
// Expand
|
||||
section.classList.remove('collaboration-section-collapsed');
|
||||
section.classList.add('collaboration-section-expanded');
|
||||
content.style.display = 'block';
|
||||
icon.style.transform = 'rotate(180deg)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make function globally available
|
||||
window.toggleCollaborationSection = toggleCollaborationSection;
|
||||
// Helper function to create compact collaboration tool cards for matrix view
|
||||
// Make functions globally available
|
||||
window.toggleDomainAgnosticSection = toggleDomainAgnosticSection;
|
||||
|
||||
// Helper function to create compact tool cards
|
||||
function createCollaborationToolCardCompact(tool) {
|
||||
const hasValidProjectUrl = tool.projectUrl !== undefined &&
|
||||
tool.projectUrl !== null &&
|
||||
@@ -261,7 +268,7 @@ window.toggleCollaborationSection = toggleCollaborationSection;
|
||||
return cardDiv;
|
||||
}
|
||||
|
||||
// Tool details functions
|
||||
// Tool details functions (unchanged)
|
||||
window.showToolDetails = function(toolName) {
|
||||
const tool = toolsData.find(t => t.name === toolName);
|
||||
if (!tool) return;
|
||||
@@ -314,14 +321,12 @@ window.toggleCollaborationSection = toggleCollaborationSection;
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Links - Updated to handle dual buttons for hosted tools AND knowledgebase links
|
||||
// Links
|
||||
const linksContainer = document.getElementById('tool-links');
|
||||
|
||||
let linksHTML = '';
|
||||
|
||||
// Main action buttons
|
||||
if (hasValidProjectUrl) {
|
||||
// Two buttons for tools we're hosting
|
||||
linksHTML += `
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<a href="${tool.url}" target="_blank" rel="noopener noreferrer" class="btn btn-secondary" style="flex: 1;">
|
||||
@@ -333,7 +338,6 @@ window.toggleCollaborationSection = toggleCollaborationSection;
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
// Single button for tools we're not hosting
|
||||
linksHTML += `
|
||||
<a href="${tool.url}" target="_blank" rel="noopener noreferrer" class="btn btn-primary" style="width: 100%;">
|
||||
Software-Homepage
|
||||
@@ -341,7 +345,6 @@ window.toggleCollaborationSection = toggleCollaborationSection;
|
||||
`;
|
||||
}
|
||||
|
||||
// Add knowledgebase link if available
|
||||
if (tool.knowledgebase === true) {
|
||||
const kbId = tool.name.toLowerCase().replace(/\s+/g, '-');
|
||||
linksHTML += `
|
||||
@@ -374,7 +377,6 @@ window.toggleCollaborationSection = toggleCollaborationSection;
|
||||
window.addEventListener('viewChanged', (event) => {
|
||||
const view = event.detail;
|
||||
if (view === 'matrix') {
|
||||
// Delay highlighting to ensure matrix is visible
|
||||
setTimeout(updateMatrixHighlighting, 100);
|
||||
}
|
||||
});
|
||||
@@ -393,56 +395,34 @@ window.toggleCollaborationSection = toggleCollaborationSection;
|
||||
const currentView = document.querySelector('.view-toggle.active')?.getAttribute('data-view');
|
||||
|
||||
if (currentView === 'matrix') {
|
||||
// Get selected phase from active button instead of dropdown
|
||||
const selectedPhase = getSelectedPhase();
|
||||
|
||||
// Handle collaboration tools section
|
||||
const collaborationSection = document.getElementById('collaboration-tools-section');
|
||||
const dfirMatrixSection = document.getElementById('dfir-matrix-section');
|
||||
const collaborationContainer = document.getElementById('collaboration-tools-container');
|
||||
// Get all domain-agnostic phase IDs
|
||||
const domainAgnosticPhaseIds = domainAgnosticSoftware.map(section => section.id);
|
||||
|
||||
if (selectedPhase === 'collaboration-general') {
|
||||
// Show only collaboration tools, hide matrix
|
||||
collaborationSection.style.display = 'block';
|
||||
dfirMatrixSection.style.display = 'none';
|
||||
// Check if selected phase is a domain-agnostic phase
|
||||
const isDomainAgnosticPhase = domainAgnosticPhaseIds.includes(selectedPhase);
|
||||
|
||||
// Handle domain-agnostic sections
|
||||
domainAgnosticSoftware.forEach(sectionData => {
|
||||
const section = document.getElementById(`domain-agnostic-section-${sectionData.id}`);
|
||||
const container = document.getElementById(`domain-agnostic-tools-${sectionData.id}`);
|
||||
|
||||
// Filter collaboration tools
|
||||
const filteredCollaboration = filtered.filter(tool => (tool.phases || []).includes('collaboration-general'));
|
||||
collaborationContainer.innerHTML = '';
|
||||
if (!section || !container) return;
|
||||
|
||||
filteredCollaboration.forEach(tool => {
|
||||
const toolCard = createCollaborationToolCardCompact(tool);
|
||||
collaborationContainer.appendChild(toolCard);
|
||||
});
|
||||
} else {
|
||||
// Show matrix, handle collaboration tools visibility
|
||||
dfirMatrixSection.style.display = 'block';
|
||||
});
|
||||
|
||||
if (!isDomainAgnosticPhase) {
|
||||
// Show matrix for regular phases
|
||||
document.getElementById('dfir-matrix-section').style.display = 'block';
|
||||
|
||||
if (selectedPhase === '' || selectedPhase === null) {
|
||||
// Show collaboration tools when no specific phase is selected
|
||||
collaborationSection.style.display = 'block';
|
||||
|
||||
// Show all collaboration tools that pass general filters
|
||||
const filteredCollaboration = filtered.filter(tool => (tool.phases || []).includes('collaboration-general'));
|
||||
collaborationContainer.innerHTML = '';
|
||||
|
||||
filteredCollaboration.forEach(tool => {
|
||||
const toolCard = createCollaborationToolCardCompact(tool);
|
||||
collaborationContainer.appendChild(toolCard);
|
||||
});
|
||||
} else {
|
||||
// Hide collaboration tools when specific DFIR phase is selected
|
||||
collaborationSection.style.display = 'none';
|
||||
}
|
||||
|
||||
// Clear and update matrix cells with DFIR tools only
|
||||
// Clear and update matrix cells with ALL tools (based on domains × phases)
|
||||
document.querySelectorAll('.matrix-cell').forEach(cell => {
|
||||
cell.innerHTML = '';
|
||||
});
|
||||
|
||||
// Re-populate with filtered DFIR tools - with safe array handling
|
||||
const filteredDfirTools = filtered.filter(tool => !(tool.phases || []).includes('collaboration-general'));
|
||||
filteredDfirTools.forEach(tool => {
|
||||
// Re-populate with filtered tools based on domains × phases
|
||||
filtered.forEach(tool => {
|
||||
const hasValidProjectUrl = tool.projectUrl !== undefined &&
|
||||
tool.projectUrl !== null &&
|
||||
tool.projectUrl !== "" &&
|
||||
@@ -453,22 +433,19 @@ window.toggleCollaborationSection = toggleCollaborationSection;
|
||||
|
||||
domains.forEach(domain => {
|
||||
phases.forEach(phase => {
|
||||
if (phase !== 'collaboration-general') {
|
||||
const cell = document.querySelector(`[data-domain="${domain}"][data-phase="${phase}"]`);
|
||||
if (cell) {
|
||||
const chip = document.createElement('span');
|
||||
chip.className = `tool-chip ${hasValidProjectUrl ? 'tool-chip-hosted' : tool.license !== 'Proprietary' ? 'tool-chip-oss' : ''}`;
|
||||
chip.setAttribute('title', `${tool.name}${tool.knowledgebase === true ? ' (KB verfügbar)' : ''}`);
|
||||
chip.innerHTML = `${tool.name}${tool.knowledgebase === true ? '<span style="margin-left: 0.25rem; font-size: 0.6875rem;">📖</span>' : ''}`;
|
||||
chip.onclick = () => window.showToolDetails(tool.name);
|
||||
cell.appendChild(chip);
|
||||
}
|
||||
const cell = document.querySelector(`[data-domain="${domain}"][data-phase="${phase}"]`);
|
||||
if (cell) {
|
||||
const chip = document.createElement('span');
|
||||
chip.className = `tool-chip ${hasValidProjectUrl ? 'tool-chip-hosted' : tool.license !== 'Proprietary' ? 'tool-chip-oss' : ''}`;
|
||||
chip.setAttribute('title', `${tool.name}${tool.knowledgebase === true ? ' (KB verfügbar)' : ''}`);
|
||||
chip.innerHTML = `${tool.name}${tool.knowledgebase === true ? '<span style="margin-left: 0.25rem; font-size: 0.6875rem;">📖</span>' : ''}`;
|
||||
chip.onclick = () => window.showToolDetails(tool.name);
|
||||
cell.appendChild(chip);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Update highlighting after matrix content is updated
|
||||
setTimeout(updateMatrixHighlighting, 50);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ tools:
|
||||
platforms:
|
||||
- Windows
|
||||
- Linux
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: download
|
||||
url: https://www.autopsy.com/
|
||||
@@ -50,6 +51,7 @@ tools:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
skillLevel: advanced
|
||||
accessType: download
|
||||
url: https://www.volatilityfoundation.org/
|
||||
@@ -73,9 +75,10 @@ tools:
|
||||
- data-collection
|
||||
- examination
|
||||
- analysis
|
||||
- collaboration-general
|
||||
platforms:
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
- collaboration-general
|
||||
skillLevel: intermediate
|
||||
accessType: self-hosted
|
||||
url: https://github.com/TheHive-Project/TheHive
|
||||
@@ -104,6 +107,7 @@ tools:
|
||||
- analysis
|
||||
platforms:
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: self-hosted
|
||||
url: https://misp-project.org/
|
||||
@@ -129,6 +133,7 @@ tools:
|
||||
- reporting
|
||||
platforms:
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: self-hosted
|
||||
url: https://timesketch.org/
|
||||
@@ -159,6 +164,7 @@ tools:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: download
|
||||
url: https://www.wireshark.org/
|
||||
@@ -185,6 +191,7 @@ tools:
|
||||
- reporting
|
||||
platforms:
|
||||
- Windows
|
||||
domain-agnostic-software:
|
||||
skillLevel: beginner
|
||||
accessType: commercial
|
||||
url: https://www.magnetforensics.com/products/magnet-axiom/
|
||||
@@ -210,6 +217,7 @@ tools:
|
||||
- reporting
|
||||
platforms:
|
||||
- Windows
|
||||
domain-agnostic-software:
|
||||
skillLevel: beginner
|
||||
accessType: commercial
|
||||
url: https://cellebrite.com/en/ufed/
|
||||
@@ -231,6 +239,7 @@ tools:
|
||||
platforms:
|
||||
- Linux
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
skillLevel: advanced
|
||||
accessType: self-hosted
|
||||
url: https://github.com/cert-ee/cuckoo3
|
||||
@@ -252,6 +261,7 @@ tools:
|
||||
platforms:
|
||||
- Windows
|
||||
- Linux
|
||||
domain-agnostic-software:
|
||||
skillLevel: expert
|
||||
accessType: download
|
||||
url: https://github.com/NationalSecurityAgency/ghidra
|
||||
@@ -276,6 +286,7 @@ tools:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: download
|
||||
url: https://plaso.readthedocs.io/
|
||||
@@ -301,6 +312,7 @@ tools:
|
||||
- analysis
|
||||
platforms:
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
skillLevel: beginner
|
||||
accessType: self-hosted
|
||||
url: https://gchq.github.io/CyberChef/
|
||||
@@ -335,6 +347,7 @@ tools:
|
||||
- Linux
|
||||
- macOS
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
skillLevel: advanced
|
||||
accessType: self-hosted
|
||||
url: https://www.velociraptor.app/
|
||||
@@ -364,6 +377,7 @@ tools:
|
||||
- Linux
|
||||
- macOS
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
skillLevel: advanced
|
||||
accessType: self-hosted
|
||||
url: https://github.com/google/grr
|
||||
@@ -389,6 +403,7 @@ tools:
|
||||
- analysis
|
||||
platforms:
|
||||
- Linux
|
||||
domain-agnostic-software:
|
||||
skillLevel: expert
|
||||
accessType: self-hosted
|
||||
url: https://arkime.com/
|
||||
@@ -414,6 +429,7 @@ tools:
|
||||
- analysis
|
||||
platforms:
|
||||
- Windows
|
||||
domain-agnostic-software:
|
||||
skillLevel: beginner
|
||||
accessType: download
|
||||
url: https://www.netresec.com/?page=NetworkMiner
|
||||
@@ -438,6 +454,7 @@ tools:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
skillLevel: novice
|
||||
accessType: download
|
||||
url: https://exiftool.org/
|
||||
@@ -462,6 +479,7 @@ tools:
|
||||
- reporting
|
||||
platforms:
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
skillLevel: advanced
|
||||
accessType: commercial
|
||||
url: https://www.chainalysis.com/
|
||||
@@ -490,6 +508,7 @@ tools:
|
||||
- Linux
|
||||
- macOS
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: self-hosted
|
||||
url: https://neo4j.com/
|
||||
@@ -516,6 +535,7 @@ tools:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: download
|
||||
url: https://qgis.org/
|
||||
@@ -543,9 +563,10 @@ tools:
|
||||
- ics-forensics
|
||||
phases:
|
||||
- reporting
|
||||
- collaboration-general
|
||||
platforms:
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
- collaboration-general
|
||||
skillLevel: novice
|
||||
accessType: self-hosted
|
||||
url: https://nextcloud.com/
|
||||
@@ -562,9 +583,10 @@ tools:
|
||||
- incident-response
|
||||
- malware-analysis
|
||||
phases:
|
||||
- collaboration-general
|
||||
platforms:
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
- collaboration-general
|
||||
skillLevel: beginner
|
||||
accessType: self-hosted
|
||||
url: https://gitea.io/
|
||||
@@ -586,6 +608,7 @@ tools:
|
||||
platforms:
|
||||
- Linux
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
skillLevel: advanced
|
||||
accessType: download
|
||||
url: https://github.com/ReFirmLabs/binwalk
|
||||
@@ -611,11 +634,12 @@ tools:
|
||||
- ics-forensics
|
||||
phases:
|
||||
- reporting
|
||||
- collaboration-general
|
||||
platforms:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
- collaboration-general
|
||||
skillLevel: novice
|
||||
accessType: download
|
||||
url: https://www.libreoffice.org/
|
||||
@@ -643,12 +667,13 @@ tools:
|
||||
- ics-forensics
|
||||
phases:
|
||||
- reporting
|
||||
- collaboration-general
|
||||
platforms:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
- collaboration-general
|
||||
skillLevel: novice
|
||||
accessType: commercial
|
||||
url: https://www.office.com/
|
||||
@@ -675,6 +700,7 @@ tools:
|
||||
- reporting
|
||||
platforms:
|
||||
- Web
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: self-hosted
|
||||
url: https://graphsense.org/
|
||||
@@ -694,6 +720,7 @@ tools:
|
||||
- data-collection
|
||||
platforms:
|
||||
- Windows
|
||||
domain-agnostic-software:
|
||||
skillLevel: beginner
|
||||
accessType: commercial
|
||||
url: https://www.exterro.com/digital-forensics-software/ftk-imager
|
||||
@@ -714,6 +741,7 @@ tools:
|
||||
- data-collection
|
||||
platforms:
|
||||
- Linux
|
||||
domain-agnostic-software:
|
||||
skillLevel: novice
|
||||
accessType: download
|
||||
url: https://guymager.sourceforge.io/
|
||||
@@ -732,6 +760,7 @@ tools:
|
||||
- data-collection
|
||||
platforms:
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
skillLevel: novice
|
||||
accessType: download
|
||||
url: https://github.com/Lazza/Fuji
|
||||
@@ -754,6 +783,7 @@ tools:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: download
|
||||
url: https://github.com/abrignoni/ALEAPP
|
||||
@@ -776,6 +806,7 @@ tools:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: download
|
||||
url: https://github.com/abrignoni/iLEAPP
|
||||
@@ -798,6 +829,7 @@ tools:
|
||||
- Windows
|
||||
- Linux
|
||||
- macOS
|
||||
domain-agnostic-software:
|
||||
skillLevel: intermediate
|
||||
accessType: download
|
||||
url: https://github.com/abrignoni/VLEAPP
|
||||
@@ -805,6 +837,30 @@ tools:
|
||||
license: MIT
|
||||
knowledgebase: false
|
||||
tags: [vehicle-forensics, car-data, infotainment-analysis, embedded-systems, automotive]
|
||||
- name: Kali Linux
|
||||
description: >-
|
||||
Spezielle Linux-Distribution, die sich an Pentester richtet. Hat aber auch zahlreiche Forensik-Software an Bord.
|
||||
domains:
|
||||
- incident-response
|
||||
- law-enforcement
|
||||
- malware-analysis
|
||||
- fraud-investigation
|
||||
- network-forensics
|
||||
- mobile-forensics
|
||||
- cloud-forensics
|
||||
- ics-forensics
|
||||
phases:
|
||||
platforms:
|
||||
- OS
|
||||
domain-agnostic-software:
|
||||
- specific-os
|
||||
skillLevel: novice
|
||||
accessType: OS
|
||||
url: https://kali.org/
|
||||
projectUrl:
|
||||
license: GPL-3
|
||||
knowledgebase: true
|
||||
tags: [pentesting, OS, Linux]
|
||||
domains:
|
||||
- id: incident-response
|
||||
name: Incident Response & Breach-Untersuchung
|
||||
@@ -835,6 +891,10 @@ phases:
|
||||
- id: reporting
|
||||
name: Bericht & Präsentation
|
||||
description: "Documentation, Visualization, Presentation Tools (z.B. QGIS für Geodaten, Timeline-Tools)"
|
||||
domain-agnostic-software:
|
||||
- id: collaboration-general
|
||||
name: Übergreifend & Kollaboration
|
||||
description: "Cross-cutting tools and collaboration platforms"
|
||||
description: "Cross-cutting tools and collaboration platforms"
|
||||
- id: specific-os
|
||||
name: Betriebssysteme
|
||||
description: "Operating Systems which focus on forensics"
|
||||
@@ -97,8 +97,19 @@ function createSystemPrompt(toolsData: any): string {
|
||||
projectUrl: tool.projectUrl ? 'self-hosted' : 'external'
|
||||
}));
|
||||
|
||||
// Dynamically build phases list from configuration
|
||||
const phasesDescription = toolsData.phases.map((phase: any) =>
|
||||
// Get regular phases (no more filtering needed)
|
||||
const regularPhases = toolsData.phases || [];
|
||||
|
||||
// Get domain-agnostic software phases
|
||||
const domainAgnosticSoftware = toolsData['domain-agnostic-software'] || [];
|
||||
|
||||
// Combine all phases for the description
|
||||
const allPhaseItems = [
|
||||
...regularPhases,
|
||||
...domainAgnosticSoftware
|
||||
];
|
||||
|
||||
const phasesDescription = allPhaseItems.map((phase: any) =>
|
||||
`- ${phase.id}: ${phase.name}`
|
||||
).join('\n');
|
||||
|
||||
@@ -107,10 +118,28 @@ function createSystemPrompt(toolsData: any): string {
|
||||
`- ${domain.id}: ${domain.name}`
|
||||
).join('\n');
|
||||
|
||||
const phaseDescriptions = toolsData.phases
|
||||
.filter((phase: any) => phase.id !== 'collaboration-general')
|
||||
.map((phase: any) => `- ${phase.name}: ${phase.description || 'Tools for this phase'}`)
|
||||
.join('\n');
|
||||
// Build dynamic phase descriptions for tool selection
|
||||
const phaseDescriptions = regularPhases.map((phase: any) => {
|
||||
// Create generic descriptions or you could add a 'description' field to the YAML
|
||||
const descriptions = {
|
||||
'data-collection': 'Imaging, Acquisition, Remote Collection Tools',
|
||||
'examination': 'Parsing, Extraction, Initial Analysis Tools',
|
||||
'analysis': 'Deep Analysis, Correlation, Visualization Tools',
|
||||
'reporting': 'Documentation, Visualization, Presentation Tools (z.B. QGIS für Geodaten, Timeline-Tools)'
|
||||
};
|
||||
return `- ${phase.name}: ${phase.description || descriptions[phase.id] || 'Tools for this phase'}`;
|
||||
}).join('\n');
|
||||
|
||||
// Add domain-agnostic software descriptions
|
||||
const domainAgnosticDescriptions = domainAgnosticSoftware.map((section: any) =>
|
||||
`- ${section.name}: ${section.description || 'Cross-cutting tools and platforms'}`
|
||||
).join('\n');
|
||||
|
||||
// Create valid phase values for JSON schema
|
||||
const validPhases = [
|
||||
...regularPhases.map((p: any) => p.id),
|
||||
...domainAgnosticSoftware.map((s: any) => s.id)
|
||||
].join('|');
|
||||
|
||||
return `Du bist ein DFIR (Digital Forensics and Incident Response) Experte, der Ermittlern bei der Toolauswahl hilft.
|
||||
|
||||
@@ -135,6 +164,9 @@ WICHTIGE REGELN:
|
||||
TOOL-AUSWAHL NACH PHASE:
|
||||
${phaseDescriptions}
|
||||
|
||||
DOMAIN-AGNOSTIC SOFTWARE:
|
||||
${domainAgnosticDescriptions}
|
||||
|
||||
ANTWORT-FORMAT (strict JSON):
|
||||
{
|
||||
"scenario_analysis": "Detaillierte Analyse des Szenarios auf Deutsch/English",
|
||||
@@ -142,7 +174,7 @@ ANTWORT-FORMAT (strict JSON):
|
||||
{
|
||||
"name": "EXAKTER Name aus der Database",
|
||||
"priority": "high|medium|low",
|
||||
"phase": "${toolsData.phases.filter((p: any) => p.id !== 'collaboration-general').map((p: any) => p.id).join('|')}",
|
||||
"phase": "${validPhases}",
|
||||
"justification": "Warum dieses Tool für diese Phase und Szenario geeignet ist"
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user