This commit is contained in:
overcuriousity 2025-07-14 23:05:46 +02:00
parent 8540687b47
commit d9c79b3ddc
17 changed files with 1591 additions and 1529 deletions

View File

@ -0,0 +1 @@
export default new Map();

View File

@ -0,0 +1 @@
export default new Map();

199
.astro/content.d.ts vendored Normal file
View File

@ -0,0 +1,199 @@
declare module 'astro:content' {
export interface RenderResult {
Content: import('astro/runtime/server/index.js').AstroComponentFactory;
headings: import('astro').MarkdownHeading[];
remarkPluginFrontmatter: Record<string, any>;
}
interface Render {
'.md': Promise<RenderResult>;
}
export interface RenderedContent {
html: string;
metadata?: {
imagePaths: Array<string>;
[key: string]: unknown;
};
}
}
declare module 'astro:content' {
type Flatten<T> = T extends { [K: string]: infer U } ? U : never;
export type CollectionKey = keyof AnyEntryMap;
export type CollectionEntry<C extends CollectionKey> = Flatten<AnyEntryMap[C]>;
export type ContentCollectionKey = keyof ContentEntryMap;
export type DataCollectionKey = keyof DataEntryMap;
type AllValuesOf<T> = T extends any ? T[keyof T] : never;
type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf<
ContentEntryMap[C]
>['slug'];
export type ReferenceDataEntry<
C extends CollectionKey,
E extends keyof DataEntryMap[C] = string,
> = {
collection: C;
id: E;
};
export type ReferenceContentEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}) = string,
> = {
collection: C;
slug: E;
};
export type ReferenceLiveEntry<C extends keyof LiveContentConfig['collections']> = {
collection: C;
id: string;
};
/** @deprecated Use `getEntry` instead. */
export function getEntryBySlug<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
collection: C,
// Note that this has to accept a regular string too, for SSR
entrySlug: E,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
/** @deprecated Use `getEntry` instead. */
export function getDataEntryById<C extends keyof DataEntryMap, E extends keyof DataEntryMap[C]>(
collection: C,
entryId: E,
): Promise<CollectionEntry<C>>;
export function getCollection<C extends keyof AnyEntryMap, E extends CollectionEntry<C>>(
collection: C,
filter?: (entry: CollectionEntry<C>) => entry is E,
): Promise<E[]>;
export function getCollection<C extends keyof AnyEntryMap>(
collection: C,
filter?: (entry: CollectionEntry<C>) => unknown,
): Promise<CollectionEntry<C>[]>;
export function getLiveCollection<C extends keyof LiveContentConfig['collections']>(
collection: C,
filter?: LiveLoaderCollectionFilterType<C>,
): Promise<
import('astro').LiveDataCollectionResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>
>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
entry: ReferenceContentEntry<C, E>,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
>(
entry: ReferenceDataEntry<C, E>,
): E extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
collection: C,
slug: E,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
>(
collection: C,
id: E,
): E extends keyof DataEntryMap[C]
? string extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]> | undefined
: Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
export function getLiveEntry<C extends keyof LiveContentConfig['collections']>(
collection: C,
filter: string | LiveLoaderEntryFilterType<C>,
): Promise<import('astro').LiveDataEntryResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>>;
/** Resolve an array of entry references from the same collection */
export function getEntries<C extends keyof ContentEntryMap>(
entries: ReferenceContentEntry<C, ValidContentEntrySlug<C>>[],
): Promise<CollectionEntry<C>[]>;
export function getEntries<C extends keyof DataEntryMap>(
entries: ReferenceDataEntry<C, keyof DataEntryMap[C]>[],
): Promise<CollectionEntry<C>[]>;
export function render<C extends keyof AnyEntryMap>(
entry: AnyEntryMap[C][string],
): Promise<RenderResult>;
export function reference<C extends keyof AnyEntryMap>(
collection: C,
): import('astro/zod').ZodEffects<
import('astro/zod').ZodString,
C extends keyof ContentEntryMap
? ReferenceContentEntry<C, ValidContentEntrySlug<C>>
: ReferenceDataEntry<C, keyof DataEntryMap[C]>
>;
// Allow generic `string` to avoid excessive type errors in the config
// if `dev` is not running to update as you edit.
// Invalid collection names will be caught at build time.
export function reference<C extends string>(
collection: C,
): import('astro/zod').ZodEffects<import('astro/zod').ZodString, never>;
type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T;
type InferEntrySchema<C extends keyof AnyEntryMap> = import('astro/zod').infer<
ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']>
>;
type ContentEntryMap = {
};
type DataEntryMap = {
};
type AnyEntryMap = ContentEntryMap & DataEntryMap;
type ExtractLoaderTypes<T> = T extends import('astro/loaders').LiveLoader<
infer TData,
infer TEntryFilter,
infer TCollectionFilter,
infer TError
>
? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError }
: { data: never; entryFilter: never; collectionFilter: never; error: never };
type ExtractDataType<T> = ExtractLoaderTypes<T>['data'];
type ExtractEntryFilterType<T> = ExtractLoaderTypes<T>['entryFilter'];
type ExtractCollectionFilterType<T> = ExtractLoaderTypes<T>['collectionFilter'];
type ExtractErrorType<T> = ExtractLoaderTypes<T>['error'];
type LiveLoaderDataType<C extends keyof LiveContentConfig['collections']> =
LiveContentConfig['collections'][C]['schema'] extends undefined
? ExtractDataType<LiveContentConfig['collections'][C]['loader']>
: import('astro/zod').infer<
Exclude<LiveContentConfig['collections'][C]['schema'], undefined>
>;
type LiveLoaderEntryFilterType<C extends keyof LiveContentConfig['collections']> =
ExtractEntryFilterType<LiveContentConfig['collections'][C]['loader']>;
type LiveLoaderCollectionFilterType<C extends keyof LiveContentConfig['collections']> =
ExtractCollectionFilterType<LiveContentConfig['collections'][C]['loader']>;
type LiveLoaderErrorType<C extends keyof LiveContentConfig['collections']> = ExtractErrorType<
LiveContentConfig['collections'][C]['loader']
>;
export type ContentConfig = typeof import("../src/content.config.mjs");
export type LiveContentConfig = never;
}

1
.astro/types.d.ts vendored
View File

@ -1 +1,2 @@
/// <reference types="astro/client" /> /// <reference types="astro/client" />
/// <reference path="content.d.ts" />

View File

@ -89,8 +89,8 @@ tools:
- "Filesystem Forensics" - "Filesystem Forensics"
- "Network Forensics" - "Network Forensics"
phases: # DFIR phases phases: # DFIR phases
- "Data Collection" - "Datensammlung"
- "Analysis" - "Analyse"
platforms: # Supported platforms platforms: # Supported platforms
- "Linux" - "Linux"
- "Windows" - "Windows"
@ -122,7 +122,7 @@ services:
name: "Service Name" name: "Service Name"
description: "Service description" description: "Service description"
url: "https://service.lab.local" url: "https://service.lab.local"
category: "Analysis Tools" category: "Analyse Tools"
status: "operational" # operational|degraded|maintenance|down status: "operational" # operational|degraded|maintenance|down
uptime: "99.9%" uptime: "99.9%"
responseTime: "245ms" responseTime: "245ms"
@ -133,18 +133,18 @@ services:
Tools are organized according to the standard DFIR framework: Tools are organized according to the standard DFIR framework:
### Domains ### Domains
- **Filesystem Forensics**: File system analysis and recovery - **Filesystem Forensics**: File system Analyse and recovery
- **Network Forensics**: Network traffic and protocol analysis - **Network Forensics**: Network traffic and protocol Analyse
- **Memory Forensics**: RAM and memory artifact analysis - **Memory Forensics**: RAM and memory artifact Analyse
- **Live Forensics**: Real-time system analysis - **Live Forensics**: Real-time system Analyse
- **Malware Analysis**: Malicious software examination - **Malware Analyse**: Malicious software Auswertung
- **Cryptocurrency**: Blockchain and crypto investigations - **Cryptocurrency**: Blockchain and crypto investigations
### Phases ### Phases
- **Data Collection**: Evidence acquisition and preservation - **Datensammlung**: Evidence acquisition and preservation
- **Examination**: Data extraction and parsing - **Auswertung**: Data extraction and parsing
- **Analysis**: Evidence correlation and interpretation - **Analyse**: Evidence correlation and interpretation
- **Reporting**: Documentation and timeline creation - **Bericht & Präsentation**: Documentation and timeline creation
## Service Status Integration ## Service Status Integration
@ -223,7 +223,7 @@ EXPOSE 80
For lab environments, consider deploying alongside: For lab environments, consider deploying alongside:
- **Timesketch**: Timeline analysis platform - **Timesketch**: Timeline Analyse platform
- **MISP**: Threat intelligence sharing - **MISP**: Threat intelligence sharing
- **Neo4j**: Graph database for relationships - **Neo4j**: Graph database for relationships
@ -240,7 +240,7 @@ Features gracefully degrade in older browsers.
3. Test locally with `npm start` 3. Test locally with `npm start`
4. Submit a pull request 4. Submit a pull request
### Issue Reporting ### Issue Bericht & Präsentation
Report bugs or suggest features via GitHub Issues. Report bugs or suggest features via GitHub Issues.

View File

@ -1,37 +1,23 @@
// astro.config.mjs - Static deployment configuration
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({ export default defineConfig({
// No integrations needed - keeping it minimal // Static site generation - no adapter needed
integrations: [], output: 'static',
// Build configuration // Build configuration
build: { build: {
// Inline styles for better performance assets: '_astro'
inlineStylesheets: 'auto',
// Generate static site
format: 'file'
}, },
// Disable telemetry for privacy // Development server
telemetry: false,
// Server configuration for development
server: { server: {
port: 3000, port: 4321,
host: true host: true
}, },
// Vite configuration // Ensure all pages are pre-rendered
vite: { experimental: {
build: { prerender: true
// Optimize for speed
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
},
},
},
} }
}); });

124
deploy-static.sh Normal file
View File

@ -0,0 +1,124 @@
#!/bin/bash
# DFIR Tools Hub - Node.js Deployment Script
set -e
PROJECT_DIR="/var/www/dfir-tools-hub"
SERVICE_NAME="dfir-tools-hub"
SERVICE_PORT="3000"
echo "🔧 Setting up Node.js deployment..."
cd $PROJECT_DIR
# Install PM2 globally if not present
if ! command -v pm2 &> /dev/null; then
sudo npm install -g pm2
fi
# Install dependencies
npm ci --production
# Update astro.config.mjs for Node.js adapter
cat > astro.config.mjs << 'EOF'
import { defineConfig } from 'astro/config';
export default defineConfig({
output: 'server',
adapter: '@astrojs/node',
server: {
port: 3000,
host: '127.0.0.1'
}
});
EOF
# Install Node.js adapter
npm install @astrojs/node
# Build for Node.js
npm run build
# Create PM2 ecosystem file
cat > ecosystem.config.js << EOF
module.exports = {
apps: [{
name: '$SERVICE_NAME',
script: './dist/server/entry.mjs',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'production',
PORT: $SERVICE_PORT,
HOST: '127.0.0.1'
},
error_file: '/var/log/pm2/$SERVICE_NAME-error.log',
out_file: '/var/log/pm2/$SERVICE_NAME-out.log',
log_file: '/var/log/pm2/$SERVICE_NAME.log',
time: true,
max_memory_restart: '1G'
}]
};
EOF
# Create log directory
sudo mkdir -p /var/log/pm2
sudo chown -R $(whoami):$(whoami) /var/log/pm2
# Start/restart with PM2
pm2 delete $SERVICE_NAME 2>/dev/null || true
pm2 start ecosystem.config.js
pm2 save
pm2 startup
echo "🔧 Configuring nginx reverse proxy..."
# Create nginx configuration for Node.js
sudo tee /etc/nginx/sites-available/$SERVICE_NAME << EOF
upstream dfir_backend {
server 127.0.0.1:$SERVICE_PORT;
}
server {
listen 80;
server_name dfir-tools.yourdomain.com; # Replace with your domain
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Proxy to Node.js application
location / {
proxy_pass http://dfir_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_cache_bypass \$http_upgrade;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Health check endpoint
location /health {
access_log off;
proxy_pass http://dfir_backend/health;
}
}
EOF
# Enable site and reload nginx
sudo ln -sf /etc/nginx/sites-available/$SERVICE_NAME /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
echo "✅ Node.js deployment completed!"
echo "🔍 Status: pm2 status"
echo "📋 Logs: pm2 logs $SERVICE_NAME"

View File

@ -1,42 +1,42 @@
Proposed Framework Categories (Y-axis): Proposed Framework Categories (Y-axis):
1. Storage & File System Artifacts 1. Storage & File System Artifacts
Static file system analysis (encrypted/unencrypted) Static file system Analyse (encrypted/unencrypted)
Registry analysis Registry Analyse
Database forensics Database forensics
2. Memory & Runtime Artifacts 2. Memory & Runtime Artifacts
Memory forensics of live systems Memory forensics of live systems
Process analysis Process Analyse
Virtualization forensics Virtualization forensics
3. Network & Communication Artifacts 3. Network & Communication Artifacts
Webserver log analysis Webserver log Analyse
System log analysis System log Analyse
PKI examination PKI Auswertung
Radio signal analysis Radio signal Analyse
VoIP forensics VoIP forensics
Network packet analysis (PCAP) Network packet Analyse (PCAP)
4. Application & Code Artifacts 4. Application & Code Artifacts
Malware analysis Malware Analyse
Darknet website source code analysis Darknet website source code Analyse
Browser forensics Browser forensics
Email forensics Email forensics
5. Multimedia & Content Artifacts 5. Multimedia & Content Artifacts
Video/image/audio authenticity analysis Video/image/audio authenticity Analyse
Steganography detection Steganography detection
Content recovery Content recovery
6. Transaction & Financial Artifacts 6. Transaction & Financial Artifacts
Blockchain payment analysis Blockchain payment Analyse
Cryptocurrency exchange analysis Cryptocurrency exchange Analyse
Financial transaction forensics Financial transaction forensics
7. Platform & Infrastructure Artifacts 7. Platform & Infrastructure Artifacts
@ -44,4 +44,4 @@ Financial transaction forensics
Mobile forensics Mobile forensics
Cloud forensics Cloud forensics
IoT device forensics IoT device forensics
Social media/OSINT analysis Social media/OSINT Analyse

2452
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,23 +2,27 @@
"name": "dfir-tools-hub", "name": "dfir-tools-hub",
"type": "module", "type": "module",
"version": "1.0.0", "version": "1.0.0",
"description": "Fast, self-hosted DFIR tools hub for academic and lab environments",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
"start": "astro dev", "start": "astro dev",
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro" "astro": "astro",
"deploy:static": "./scripts/deploy-static.sh",
"deploy:node": "./scripts/deploy-node.sh",
"check:health": "curl -f http://localhost:3000/health || exit 1"
}, },
"dependencies": { "dependencies": {
"astro": "^4.0.0", "astro": "^5.3.0",
"js-yaml": "^4.1.0" "js-yaml": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^24.0.13", "@types/js-yaml": "^4.0.9"
"terser": "^5.27.0" },
"optionalDependencies": {
"@astrojs/node": "^9.3.0"
}, },
"engines": { "engines": {
"node": ">=18.0.0" "node": ">=18.0.0"
} }
} }

View File

@ -15,17 +15,17 @@ const currentPath = Astro.url.pathname;
<ul class="nav-links"> <ul class="nav-links">
<li> <li>
<a href="/" class={`nav-link ${currentPath === '/' ? 'active' : ''}`}> <a href="/" class={`nav-link ${currentPath === '/' ? 'active' : ''}`}>
Home ~/
</a> </a>
</li> </li>
<li> <li>
<a href="/status" class={`nav-link ${currentPath === '/status' ? 'active' : ''}`}> <a href="/status" class={`nav-link ${currentPath === '/status' ? 'active' : ''}`}>
Status ~/status
</a> </a>
</li> </li>
<li> <li>
<a href="/about" class={`nav-link ${currentPath === '/about' ? 'active' : ''}`}> <a href="/about" class={`nav-link ${currentPath === '/about' ? 'active' : ''}`}>
About ~/about
</a> </a>
</li> </li>
<li> <li>

View File

@ -31,7 +31,7 @@ const sortedTags = Object.entries(tagFrequency)
<input <input
type="text" type="text"
id="search-input" id="search-input"
placeholder="Search tools by name, description, or tags..." placeholder="Suchfeld: Name der Software, Beschreibung oder Tags..."
style="width: 100%;" style="width: 100%;"
/> />
</div> </div>
@ -41,10 +41,10 @@ const sortedTags = Object.entries(tagFrequency)
<!-- Domain Selection --> <!-- Domain Selection -->
<div class="domain-section"> <div class="domain-section">
<label for="domain-select" style="display: block; margin-bottom: 0.5rem; font-weight: 500;"> <label for="domain-select" style="display: block; margin-bottom: 0.5rem; font-weight: 500;">
Forensic Domain Forensische Domäne
</label> </label>
<select id="domain-select" style="max-width: 300px;"> <select id="domain-select" style="max-width: 300px;">
<option value="">All Domains</option> <option value="">Alle Domänen</option>
{domains.map((domain: any) => ( {domains.map((domain: any) => (
<option value={domain.id}>{domain.name}</option> <option value={domain.id}>{domain.name}</option>
))} ))}
@ -54,7 +54,7 @@ const sortedTags = Object.entries(tagFrequency)
<!-- Phase Selection Buttons --> <!-- Phase Selection Buttons -->
<div class="phase-section"> <div class="phase-section">
<label style="display: block; margin-bottom: 0.75rem; font-weight: 500;"> <label style="display: block; margin-bottom: 0.75rem; font-weight: 500;">
Investigation Phase Untersuchungsphase
</label> </label>
<div class="phase-buttons"> <div class="phase-buttons">
{phases.map((phase: any) => ( {phases.map((phase: any) => (
@ -73,22 +73,22 @@ const sortedTags = Object.entries(tagFrequency)
<!-- Additional Filters --> <!-- Additional Filters -->
<div style="margin-bottom: 1.5rem;"> <div style="margin-bottom: 1.5rem;">
<div class="checkbox-wrapper" style="margin-bottom: 1rem;"> <div class="checkbox-wrapper" style="margin-bottom: 1rem;">
<input type="checkbox" id="include-proprietary" checked /> <input type="checkbox" id="include-proprietary" !checked />
<label for="include-proprietary">Include Proprietary Software</label> <label for="include-proprietary">Proprietäre Software mit einschließen</label>
</div> </div>
<!-- Tag Cloud --> <!-- Tag Cloud -->
<div style="margin-bottom: 1rem;"> <div style="margin-bottom: 1rem;">
<div class="tag-header"> <div class="tag-header">
<label style="font-weight: 500;"> <label style="font-weight: 500;">
Filter by Tags Nach Tags filtern
</label> </label>
<button <button
id="tag-cloud-toggle" id="tag-cloud-toggle"
class="btn-tag-toggle" class="btn-tag-toggle"
data-expanded="false" data-expanded="false"
> >
Show More Mehr zeigen
</button> </button>
</div> </div>
<div class="tag-cloud" id="tag-cloud"> <div class="tag-cloud" id="tag-cloud">
@ -109,9 +109,8 @@ const sortedTags = Object.entries(tagFrequency)
<!-- View Toggle --> <!-- View Toggle -->
<div style="display: flex; gap: 1rem; margin-bottom: 1.5rem;"> <div style="display: flex; gap: 1rem; margin-bottom: 1.5rem;">
<button class="btn btn-secondary view-toggle active" data-view="grid">Grid View</button> <button class="btn btn-secondary view-toggle active" data-view="grid">Kachelansicht</button>
<button class="btn btn-secondary view-toggle" data-view="matrix">Matrix View</button> <button class="btn btn-secondary view-toggle" data-view="matrix">Matrix-Ansicht</button>
<button class="btn btn-secondary view-toggle" data-view="hosted">Self-Hosted Only</button>
</div> </div>
</div> </div>
@ -138,7 +137,7 @@ const sortedTags = Object.entries(tagFrequency)
// Initialize tag cloud state // Initialize tag cloud state
function initTagCloud() { function initTagCloud() {
const visibleCount = 12; // Show first 12 tags initially const visibleCount = 22; // Show first 12 tags initially
tagCloudItems.forEach((item, index) => { tagCloudItems.forEach((item, index) => {
if (index >= visibleCount) { if (index >= visibleCount) {
item.style.display = 'none'; item.style.display = 'none';
@ -149,11 +148,11 @@ const sortedTags = Object.entries(tagFrequency)
// Toggle tag cloud expansion // Toggle tag cloud expansion
function toggleTagCloud() { function toggleTagCloud() {
isTagCloudExpanded = !isTagCloudExpanded; isTagCloudExpanded = !isTagCloudExpanded;
const visibleCount = 12; const visibleCount = 22;
if (isTagCloudExpanded) { if (isTagCloudExpanded) {
tagCloud.classList.add('expanded'); tagCloud.classList.add('expanded');
tagCloudToggle.textContent = 'Show Less'; tagCloudToggle.textContent = 'Weniger zeigen';
tagCloudToggle.setAttribute('data-expanded', 'true'); tagCloudToggle.setAttribute('data-expanded', 'true');
// Show all filtered tags // Show all filtered tags
@ -164,7 +163,7 @@ const sortedTags = Object.entries(tagFrequency)
}); });
} else { } else {
tagCloud.classList.remove('expanded'); tagCloud.classList.remove('expanded');
tagCloudToggle.textContent = 'Show More'; tagCloudToggle.textContent = 'Mehr zeigen';
tagCloudToggle.setAttribute('data-expanded', 'false'); tagCloudToggle.setAttribute('data-expanded', 'false');
// Show only first visible tags // Show only first visible tags
@ -186,7 +185,7 @@ const sortedTags = Object.entries(tagFrequency)
function filterTagCloud() { function filterTagCloud() {
const searchTerm = searchInput.value.toLowerCase(); const searchTerm = searchInput.value.toLowerCase();
let visibleCount = 0; let visibleCount = 0;
const maxVisibleWhenCollapsed = 12; const maxVisibleWhenCollapsed = 22;
tagCloudItems.forEach(item => { tagCloudItems.forEach(item => {
const tagName = item.getAttribute('data-tag').toLowerCase(); const tagName = item.getAttribute('data-tag').toLowerCase();

View File

@ -36,7 +36,7 @@ domains.forEach((domain: any) => {
<div id="matrix-container" class="matrix-wrapper" style="display: none;"> <div id="matrix-container" class="matrix-wrapper" style="display: none;">
<!-- Collaboration Tools Section (compact horizontal layout for matrix view) --> <!-- Collaboration Tools Section (compact horizontal layout for matrix view) -->
<div id="collaboration-tools-section" style="margin-bottom: 1.5rem;"> <div id="collaboration-tools-section" style="margin-bottom: 1.5rem;">
<h3 style="margin-bottom: 0.75rem; color: var(--color-text); font-size: 1.125rem;">General Tools for Collaboration</h3> <h3 style="margin-bottom: 0.75rem; color: var(--color-text); font-size: 1.125rem;">Übergreifend & Kollaboration</h3>
<div class="collaboration-tools-compact" id="collaboration-tools-container"> <div class="collaboration-tools-compact" id="collaboration-tools-container">
{collaborationTools.map((tool: any) => { {collaborationTools.map((tool: any) => {
const hasValidProjectUrl = tool.projectUrl !== undefined && const hasValidProjectUrl = tool.projectUrl !== undefined &&

View File

@ -9,8 +9,8 @@ tools:
- "storage-file-system" - "storage-file-system"
- "application-code" - "application-code"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
platforms: ["Windows", "Linux", "macOS"] platforms: ["Windows", "Linux", "macOS"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "download" accessType: "download"
@ -24,8 +24,8 @@ tools:
domains: domains:
- "memory-runtime" - "memory-runtime"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
platforms: ["Windows", "Linux", "macOS"] platforms: ["Windows", "Linux", "macOS"]
skillLevel: "advanced" skillLevel: "advanced"
accessType: "download" accessType: "download"
@ -42,9 +42,9 @@ tools:
- "application-code" - "application-code"
phases: phases:
- "data-collection" - "data-collection"
- "examination" - "Auswertung"
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Web"] platforms: ["Web"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "self-hosted" accessType: "self-hosted"
@ -61,8 +61,8 @@ tools:
- "application-code" - "application-code"
phases: phases:
- "data-collection" - "data-collection"
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Web"] platforms: ["Web"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "self-hosted" accessType: "self-hosted"
@ -78,8 +78,8 @@ tools:
- "storage-file-system" - "storage-file-system"
- "network-communication" - "network-communication"
phases: phases:
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Web"] platforms: ["Web"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "self-hosted" accessType: "self-hosted"
@ -95,8 +95,8 @@ tools:
- "network-communication" - "network-communication"
phases: phases:
- "data-collection" - "data-collection"
- "examination" - "Auswertung"
- "analysis" - "Analyse"
platforms: ["Windows", "Linux", "macOS"] platforms: ["Windows", "Linux", "macOS"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "download" accessType: "download"
@ -112,9 +112,9 @@ tools:
- "memory-runtime" - "memory-runtime"
phases: phases:
- "data-collection" - "data-collection"
- "examination" - "Auswertung"
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Windows"] platforms: ["Windows"]
skillLevel: "advanced" skillLevel: "advanced"
accessType: "commercial" accessType: "commercial"
@ -129,15 +129,15 @@ tools:
- "application-code" - "application-code"
- "network-communication" - "network-communication"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
platforms: ["Linux"] platforms: ["Linux"]
skillLevel: "advanced" skillLevel: "advanced"
accessType: "self-hosted" accessType: "self-hosted"
url: "https://cuckoosandbox.org/" url: "https://cuckoosandbox.org/"
projectUrl: "" projectUrl: ""
license: "GPL-3.0" license: "GPL-3.0"
tags: ["malware", "sandbox", "dynamic-analysis", "automation"] tags: ["malware", "sandbox", "dynamic-Analyse", "automation"]
statusUrl: "" statusUrl: ""
- name: "FTK Imager" - name: "FTK Imager"
@ -146,7 +146,7 @@ tools:
- "storage-file-system" - "storage-file-system"
phases: phases:
- "data-collection" - "data-collection"
- "examination" - "Auswertung"
platforms: ["Windows"] platforms: ["Windows"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "download" accessType: "download"
@ -162,7 +162,7 @@ tools:
- "storage-file-system" - "storage-file-system"
phases: phases:
- "data-collection" - "data-collection"
- "examination" - "Auswertung"
platforms: ["Linux", "Windows"] platforms: ["Linux", "Windows"]
skillLevel: "advanced" skillLevel: "advanced"
accessType: "self-hosted" accessType: "self-hosted"
@ -178,7 +178,7 @@ tools:
- "storage-file-system" - "storage-file-system"
- "application-code" - "application-code"
phases: phases:
- "analysis" - "Analyse"
platforms: ["Linux", "Windows", "macOS"] platforms: ["Linux", "Windows", "macOS"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "download" accessType: "download"
@ -192,8 +192,8 @@ tools:
domains: domains:
- "network-communication" - "network-communication"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
platforms: ["Windows", "Linux (Mono)"] platforms: ["Windows", "Linux (Mono)"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "download" accessType: "download"
@ -208,8 +208,8 @@ tools:
- "memory-runtime" - "memory-runtime"
- "application-code" - "application-code"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
platforms: ["Windows"] platforms: ["Windows"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "download" accessType: "download"
@ -225,7 +225,7 @@ tools:
- "platform-infrastructure" - "platform-infrastructure"
phases: phases:
- "data-collection" - "data-collection"
- "analysis" - "Analyse"
platforms: ["Windows"] platforms: ["Windows"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "download" accessType: "download"
@ -241,7 +241,7 @@ tools:
- "storage-file-system" - "storage-file-system"
phases: phases:
- "data-collection" - "data-collection"
- "examination" - "Auswertung"
platforms: ["Windows", "Linux", "macOS"] platforms: ["Windows", "Linux", "macOS"]
skillLevel: "advanced" skillLevel: "advanced"
accessType: "self-hosted" accessType: "self-hosted"
@ -257,7 +257,7 @@ tools:
- "network-communication" - "network-communication"
phases: phases:
- "data-collection" - "data-collection"
- "analysis" - "Analyse"
platforms: ["Linux"] platforms: ["Linux"]
skillLevel: "advanced" skillLevel: "advanced"
accessType: "self-hosted" accessType: "self-hosted"
@ -272,9 +272,9 @@ tools:
domains: domains:
- "storage-file-system" - "storage-file-system"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Windows"] platforms: ["Windows"]
skillLevel: "advanced" skillLevel: "advanced"
accessType: "commercial" accessType: "commercial"
@ -289,9 +289,9 @@ tools:
domains: domains:
- "multimedia-content" - "multimedia-content"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Windows"] platforms: ["Windows"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "commercial" accessType: "commercial"
@ -305,16 +305,16 @@ tools:
domains: domains:
- "multimedia-content" - "multimedia-content"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Windows"] platforms: ["Windows"]
skillLevel: "advanced" skillLevel: "advanced"
accessType: "commercial" accessType: "commercial"
url: "https://cognitech.com/" url: "https://cognitech.com/"
projectUrl: "" projectUrl: ""
license: "Proprietary" license: "Proprietary"
tags: ["video", "3d-analysis", "photogrammetry", "measurement"] tags: ["video", "3d-Analyse", "photogrammetry", "measurement"]
- name: "ExifTool" - name: "ExifTool"
description: "Plattformunabhängiges Tool zum Lesen, Schreiben und Bearbeiten von Metadaten in über 200 Dateiformaten" description: "Plattformunabhängiges Tool zum Lesen, Schreiben und Bearbeiten von Metadaten in über 200 Dateiformaten"
@ -323,8 +323,8 @@ tools:
- "storage-file-system" - "storage-file-system"
phases: phases:
- "data-collection" - "data-collection"
- "examination" - "Auswertung"
- "analysis" - "Analyse"
platforms: ["Windows", "Linux", "macOS"] platforms: ["Windows", "Linux", "macOS"]
skillLevel: "beginner" skillLevel: "beginner"
accessType: "download" accessType: "download"
@ -338,8 +338,8 @@ tools:
domains: domains:
- "multimedia-content" - "multimedia-content"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
platforms: ["Windows"] platforms: ["Windows"]
skillLevel: "advanced" skillLevel: "advanced"
accessType: "commercial" accessType: "commercial"
@ -356,16 +356,16 @@ tools:
- "storage-file-system" - "storage-file-system"
phases: phases:
- "data-collection" - "data-collection"
- "examination" - "Auswertung"
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Windows"] platforms: ["Windows"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "commercial" accessType: "commercial"
url: "https://www.caseware.com/us/products/idea/" url: "https://www.caseware.com/us/products/idea/"
projectUrl: "" projectUrl: ""
license: "Proprietary" license: "Proprietary"
tags: ["audit", "compliance", "data-analysis", "automation"] tags: ["audit", "compliance", "data-Analyse", "automation"]
- name: "Chainalysis" - name: "Chainalysis"
description: "Blockchain-Intelligence-Plattform für Kryptowährungs-Ermittlungen und Geldflussanalyse über verschiedene Chains" description: "Blockchain-Intelligence-Plattform für Kryptowährungs-Ermittlungen und Geldflussanalyse über verschiedene Chains"
@ -374,9 +374,9 @@ tools:
- "network-communication" - "network-communication"
phases: phases:
- "data-collection" - "data-collection"
- "examination" - "Auswertung"
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Web"] platforms: ["Web"]
skillLevel: "advanced" skillLevel: "advanced"
accessType: "commercial" accessType: "commercial"
@ -390,25 +390,25 @@ tools:
domains: domains:
- "transaction-financial" - "transaction-financial"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Web"] platforms: ["Web"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "commercial" accessType: "commercial"
url: "https://fraudfindr.com/" url: "https://fraudfindr.com/"
projectUrl: "" projectUrl: ""
license: "Proprietary" license: "Proprietary"
tags: ["fraud-detection", "transaction", "reporting", "automation"] tags: ["fraud-detection", "transaction", "Bericht & Präsentation", "automation"]
- name: "Valid8 Financial" - name: "Valid8 Financial"
description: "Verifizierte Financial-Intelligence-Plattform für Transaktions-Tracing und forensische Buchhaltungsanalyse" description: "Verifizierte Financial-Intelligence-Plattform für Transaktions-Tracing und forensische Buchhaltungsanalyse"
domains: domains:
- "transaction-financial" - "transaction-financial"
phases: phases:
- "examination" - "Auswertung"
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Web"] platforms: ["Web"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "commercial" accessType: "commercial"
@ -424,7 +424,7 @@ tools:
- "storage-file-system" - "storage-file-system"
phases: phases:
- "data-collection" - "data-collection"
- "analysis" - "Analyse"
platforms: ["Web"] platforms: ["Web"]
skillLevel: "beginner" skillLevel: "beginner"
accessType: "commercial" accessType: "commercial"
@ -433,7 +433,7 @@ tools:
license: "Proprietary" license: "Proprietary"
tags: ["ocr", "bank-statements", "extraction", "ai"] tags: ["ocr", "bank-statements", "extraction", "ai"]
# Visualization and Analysis Tools # Visualization and Analyse Tools
- name: "Neo4j" - name: "Neo4j"
description: "Graph-Datenbank für Visualisierung komplexer Beziehungen und Netzwerkanalyse in forensischen Untersuchungen" description: "Graph-Datenbank für Visualisierung komplexer Beziehungen und Netzwerkanalyse in forensischen Untersuchungen"
domains: domains:
@ -441,8 +441,8 @@ tools:
- "application-code" - "application-code"
- "transaction-financial" - "transaction-financial"
phases: phases:
- "analysis" - "Analyse"
- "reporting" - "Bericht & Präsentation"
platforms: ["Web", "Windows", "Linux", "macOS"] platforms: ["Web", "Windows", "Linux", "macOS"]
skillLevel: "intermediate" skillLevel: "intermediate"
accessType: "self-hosted" accessType: "self-hosted"
@ -501,12 +501,12 @@ domains:
# Phase definitions for reference # Phase definitions for reference
phases: phases:
- id: "data-collection" - id: "data-collection"
name: "Data Collection" name: "Datensammlung"
- id: "examination" - id: "Auswertung"
name: "Examination" name: "Auswertung"
- id: "analysis" - id: "Analyse"
name: "Analysis" name: "Analyse"
- id: "reporting" - id: "Bericht & Präsentation"
name: "Reporting" name: "Bericht & Präsentation"
- id: "collaboration" - id: "collaboration"
name: "General Tools for Collaboration" name: "Übergreifend & Kollaboration"

View File

@ -20,10 +20,10 @@ import BaseLayout from '../layouts/BaseLayout.astro';
<h2>DFIR Methodology</h2> <h2>DFIR Methodology</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit:</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit:</p>
<ul style="margin-left: 1.5rem; margin-bottom: 1rem;"> <ul style="margin-left: 1.5rem; margin-bottom: 1rem;">
<li><strong>Data Collection:</strong> Lorem ipsum dolor sit amet</li> <li><strong>Datensammlung:</strong> Lorem ipsum dolor sit amet</li>
<li><strong>Examination:</strong> Consectetur adipiscing elit</li> <li><strong>Auswertung:</strong> Consectetur adipiscing elit</li>
<li><strong>Analysis:</strong> Sed do eiusmod tempor incididunt</li> <li><strong>Analyse:</strong> Sed do eiusmod tempor incididunt</li>
<li><strong>Reporting:</strong> Ut labore et dolore magna aliqua</li> <li><strong>Bericht & Präsentation:</strong> Ut labore et dolore magna aliqua</li>
</ul> </ul>
</div> </div>

View File

@ -14,17 +14,51 @@ const data = load(yamlContent) as any;
const tools = data.tools; const tools = data.tools;
--- ---
<BaseLayout title="Home"> <BaseLayout title="~/">
<!-- Hero Section --> <!-- Hero Section -->
<section style="text-align: center; padding: 3rem 0; border-bottom: 1px solid var(--color-border);"> <section style="text-align: center; padding: 3rem 0; border-bottom: 1px solid var(--color-border);">
<h1 style="margin-bottom: 1rem;">DFIR Tools Hub</h1> <h1 style="margin-bottom: 1.5rem;">CC24 Incident Response Framework</h1>
<p class="text-muted" style="font-size: 1.125rem; max-width: 800px; margin: 0 auto;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation. <div style="max-width: 900px; margin: 0 auto;">
<p style="font-size: 1.25rem; margin-bottom: 1.5rem; color: var(--color-text);">
<strong>Das richtige Werkzeug zur richtigen Zeit</strong> in der digitalen Forensik entscheidet oft die Wahl des passenden Tools über Erfolg oder Misserfolg einer Untersuchung.
</p> </p>
</section>
<p class="text-muted" style="font-size: 1.125rem; margin-bottom: 1.5rem; line-height: 1.7;">
Unser kuratiertes Verzeichnis bietet euch eine strukturierte Übersicht über bewährte DFIR-Tools,
kategorisiert nach forensischen Domänen und Untersuchungsphasen nach Kent, Chevalier, Grance & Dang.
</p>
<p class="text-muted" style="font-size: 1rem; margin-bottom: 2rem; line-height: 1.6;">
<span style="color: var(--color-primary); font-weight: 500;">Besonders praktisch:</span>
Viele Plattformen sind über das Single-Sign-On der CC24-Cloud direkt zugänglich.
Teilnehmer der Seminargruppe CC24-w1 können die gehostete Infrastruktur
kostenfrei für ihre Projekte nutzen.
</p>
<div style="display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;">
<a href="/about" class="btn btn-primary" style="padding: 0.75rem 1.5rem;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
<circle cx="12" cy="12" r="10"></circle>
<path d="M12 16v-4"></path>
<path d="M12 8h.01"></path>
</svg>
SSO & Zugang erfahren
</a>
<a href="#filters-section" class="btn btn-secondary" style="padding: 0.75rem 1.5rem;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path>
<polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline>
<line x1="12" y1="22.08" x2="12" y2="12"></line>
</svg>
Tools entdecken
</a>
</div>
</div>
</section>
<!-- Filters Section --> <!-- Filters Section -->
<section style="padding: 2rem 0;"> <section id="filters-section" style="padding: 2rem 0;">
<ToolFilters /> <ToolFilters />
</section> </section>

View File

@ -135,7 +135,7 @@ nav {
.nav-links { .nav-links {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 2rem; gap: 5rem;
list-style: none; list-style: none;
} }
@ -143,6 +143,7 @@ nav {
color: var(--color-text); color: var(--color-text);
font-weight: 500; font-weight: 500;
transition: color 0.2s ease; transition: color 0.2s ease;
font-size: 1.2rem;
} }
.nav-link:hover { .nav-link:hover {