Files
litterbox/app/templates/dynamic_info.html
T
2025-01-28 03:18:20 -08:00

427 lines
25 KiB
HTML

<!-- app/templates/dynamic_results.html -->
{% extends "base.html" %}
{% block content %}
<div class="max-w-6xl mx-auto px-4 py-6">
<!-- Header -->
<div class="flex items-center justify-between mb-6">
<div>
<h1 class="text-xl font-medium text-gray-100">Analysis Summary</h1>
<p class="text-base text-gray-500 mb-6">Comprehensive overview of all scan results.</p>
</div>
{% if file_info %}
<button onclick="window.location.href='/results/{{ file_info.md5 }}/info'"
class="px-4 py-2 bg-blue-500/10 text-blue-500 border border-blue-500 rounded-lg hover:bg-blue-500/20 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50 transition-colors"
aria-label="Navigate back to file information">
Back to File Info
</button>
{% else %}
<button onclick="window.location.href='/summary'"
class="px-4 py-2 bg-blue-500/10 text-blue-500 border border-blue-500 rounded-lg hover:bg-blue-500/20 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50 transition-colors"
aria-label="Navigate back to summary">
Back to Summary
</button>
{% endif %}
</div>
<!-- Target Details -->
<div id="targetDetails" class="mb-6">
<div class="bg-gray-900/30 rounded-lg border border-gray-800 p-4 mb-4">
<h4 class="text-base font-medium text-gray-100 mb-2">Target Process</h4>
{% if analysis_results.moneta and analysis_results.moneta.findings.process_info %}
{% set info = analysis_results.moneta.findings.process_info %}
<p class="text-gray-300">
<span class="font-semibold">Name:</span> {{ info.name }}<br>
<span class="font-semibold">PID:</span> {{ info.pid }}<br>
<span class="font-semibold">Path:</span> <span class="text-gray-400">{{ info.path }}</span>
</p>
{% endif %}
</div>
</div>
<!-- Overall Status Grid -->
<div class="grid grid-cols-3 gap-4 mb-6">
<div class="bg-gray-900/30 rounded-lg border border-gray-800 p-4">
<div class="text-sm text-gray-500">Overall Status</div>
<div id="overallStatus" class="text-2xl font-semibold {{ 'text-red-500' if yara_detections + pesieve_detections + moneta_detections + patriot_detections + hsb_detections > 0 else 'text-green-500' }}">
{{ 'Threats Detected' if yara_detections + pesieve_detections + moneta_detections + patriot_detections + hsb_detections > 0 else 'Clean' }}
</div>
</div>
<div class="bg-gray-900/30 rounded-lg border border-gray-800 p-4">
<div class="text-sm text-gray-500">Total Detections</div>
<div id="totalDetections" class="text-2xl font-semibold text-gray-300">{{ yara_detections + pesieve_detections + moneta_detections + patriot_detections + hsb_detections }}</div>
</div>
<div class="bg-gray-900/30 rounded-lg border border-gray-800 p-4">
<div class="text-sm text-gray-500">Total Analysis Duration</div>
<div id="scanDuration" class="text-2xl font-semibold text-gray-300">
{{ "%.2f"|format(analysis_results.analysis_metadata.total_duration if analysis_results.analysis_metadata else 0) }}s
</div>
</div>
</div>
<!-- Scanner Results Table -->
<div class="bg-gray-900/30 rounded-lg border border-gray-800 overflow-hidden">
<table class="w-full">
<thead>
<tr class="border-b border-gray-800">
<th class="px-6 py-3 text-left text-base font-medium text-gray-300">Scanner</th>
<th class="px-6 py-3 text-left text-base font-medium text-gray-300">Status</th>
<th class="px-6 py-3 text-left text-base font-medium text-gray-300">Detections</th>
<th class="px-6 py-3 text-left text-base font-medium text-gray-300">Details</th>
</tr>
</thead>
<tbody id="scannerResultsBody" class="divide-y divide-gray-800">
<!-- YARA Results Row -->
<tr>
<td class="px-6 py-4 text-base text-gray-300">YARA</td>
<td class="px-6 py-4">
<span class="px-2 py-1 text-base rounded {{ 'bg-red-500/10 text-red-500' if yara_detections else 'bg-green-500/10 text-green-500' }}">
{{ 'Suspicious' if yara_detections else 'Clean' }}
</span>
</td>
<td class="px-6 py-4 text-base {{ 'text-red-500' if yara_detections else 'text-gray-400' }}">{{ yara_detections }}</td>
<td class="px-6 py-4">
{% if yara_detections %}
<div class="text-base text-gray-400">
{% for match in analysis_results.yara.matches %}
<div class="mb-1">
Rule: <span class="text-red-400">{{ match.rule }}</span>
{% if match.metadata %}
(Severity: {{ match.metadata.severity }})
{% endif %}
</div>
{% endfor %}
</div>
{% else %}
<span class="text-base text-gray-400">No threats detected</span>
{% endif %}
</td>
</tr>
<!-- PE-sieve Results Row -->
<tr>
<td class="px-6 py-4 text-base text-gray-300">PE-sieve</td>
<td class="px-6 py-4">
<span class="px-2 py-1 text-base rounded {{ 'bg-red-500/10 text-red-500' if pesieve_detections else 'bg-green-500/10 text-green-500' }}">
{{ 'Suspicious' if pesieve_detections else 'Clean' }}
</span>
</td>
<td class="px-6 py-4 text-base {{ 'text-red-500' if pesieve_detections else 'text-gray-400' }}">{{ pesieve_detections }}</td>
<td class="px-6 py-4">
{% if pesieve_detections %}
{% set findings = analysis_results.pe_sieve.findings %}
<div class="text-base text-gray-400">
{% if findings.total_scanned > 0 %}
<div>Total Scanned: {{ findings.total_scanned }}</div>
{% endif %}
{% if findings.skipped > 0 %}
<div>Skipped: {{ findings.skipped }}</div>
{% endif %}
{% if findings.hooked > 0 %}
<div>Hooked: {{ findings.hooked }}</div>
{% endif %}
{% if findings.replaced > 0 %}
<div>Replaced: {{ findings.replaced }}</div>
{% endif %}
{% if findings.hdrs_modified > 0 %}
<div>Headers Modified: {{ findings.hdrs_modified }}</div>
{% endif %}
{% if findings.iat_hooks > 0 %}
<div>IAT Hooks: {{ findings.iat_hooks }}</div>
{% endif %}
{% if findings.implanted > 0 %}
<div>Implanted: {{ findings.implanted }}</div>
{% endif %}
{% if findings.implanted_pe > 0 %}
<div>Implanted PE: {{ findings.implanted_pe }}</div>
{% endif %}
{% if findings.implanted_shc > 0 %}
<div>Implanted Shellcode: {{ findings.implanted_shc }}</div>
{% endif %}
{% if findings.unreachable > 0 %}
<div>Unreachable Files: {{ findings.unreachable }}</div>
{% endif %}
{% if findings.other > 0 %}
<div>Other: {{ findings.other }}</div>
{% endif %}
{% if findings.total_suspicious > 0 %}
<div>Total Suspicious: {{ findings.total_suspicious }}</div>
{% endif %}
</div>
{% else %}
<span class="text-base text-gray-400">No modifications detected</span>
{% endif %}
</td>
</tr>
<!-- Moneta Results Row -->
<tr>
<td class="px-6 py-4 text-base text-gray-300">Moneta</td>
<td class="px-6 py-4">
<span class="px-2 py-1 text-base rounded {{ 'bg-red-500/10 text-red-500' if moneta_detections else 'bg-green-500/10 text-green-500' }}">
{{ 'Suspicious' if moneta_detections else 'Clean' }}
</span>
</td>
<td class="px-6 py-4 text-base {{ 'text-red-500' if moneta_detections else 'text-gray-400' }}">{{ moneta_detections }}</td>
<td class="px-6 py-4">
{% if moneta_detections %}
<div class="text-base text-gray-400">
{% for key, value in analysis_results.moneta.findings.items() %}
{% if value is number and value > 0 and key != 'scan_duration' %}
<div class="mb-1">
{% if key == 'total_regions' %}
Total Regions: {{ value }}
{% elif key == 'total_private_rx' %}
Private RX: {{ value }}
{% elif key == 'total_private_rwx' %}
Private RWX: {{ value }}
{% elif key == 'total_abnormal_private_exec' %}
Abnormal Private Executable: {{ value }}
{% elif key == 'total_heap_executable' %}
Heap Executable: {{ value }}
{% elif key == 'total_modified_code' %}
Modified Code: {{ value }}
{% elif key == 'total_modified_pe_header' %}
Modified PE Headers: {{ value }}
{% elif key == 'total_inconsistent_x' %}
Inconsistent Execute Flags: {{ value }}
{% elif key == 'total_missing_peb' %}
Missing PEB: {{ value }}
{% elif key == 'total_mismatching_peb' %}
Mismatching PEB: {{ value }}
{% elif key == 'total_threads_non_image' %}
Threads in Non-Image Memory: {{ value }}
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>
{% else %}
<span class="text-base text-gray-400">No anomalies detected</span>
{% endif %}
</td>
</tr>
<!-- Patriot Results Row -->
<tr>
<td class="px-6 py-4 text-base text-gray-300">Patriot</td>
<td class="px-6 py-4">
<span class="px-2 py-1 text-base rounded {{ 'bg-red-500/10 text-red-500' if patriot_detections else 'bg-green-500/10 text-green-500' }}">
{{ 'Suspicious' if patriot_detections else 'Clean' }}
</span>
</td>
<td class="px-6 py-4 text-base {{ 'text-red-500' if patriot_detections else 'text-gray-400' }}">{{ patriot_detections }}</td>
<td class="px-6 py-4">
{% if patriot_detections %}
<div class="text-base text-gray-400">
{% for finding in analysis_results.patriot.findings.findings %}
<div class="mb-1">
{{ finding.type }} ({{ finding.level }})
</div>
{% endfor %}
</div>
{% else %}
<span class="text-base text-gray-400">No suspicious activities</span>
{% endif %}
</td>
</tr>
<!-- HSB Results Row -->
<tr>
<td class="px-6 py-4 text-base text-gray-300">Hunt-Sleeping-Beacons</td>
<td class="px-6 py-4">
<span class="px-2 py-1 text-base rounded {{ 'bg-red-500/10 text-red-500' if hsb_detections else 'bg-green-500/10 text-green-500' }}">
{{ 'Suspicious' if hsb_detections else 'Clean' }}
</span>
</td>
<td class="px-6 py-4 text-base {{ 'text-red-500' if hsb_detections else 'text-gray-400' }}">{{ hsb_detections }}</td>
<td class="px-6 py-4">
{% if hsb_detections %}
<div class="text-base text-gray-400">
{% for detection in analysis_results.hsb.findings.detections %}
{% for finding in detection.findings %}
<div class="mb-1">{{ finding.type }} ({{ finding.severity }})</div>
{% endfor %}
{% endfor %}
</div>
{% else %}
<span class="text-base text-gray-400">No suspicious behavior</span>
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
<!-- RedEdr Summary Section - Add this after the scanner results table -->
<div class="mt-8">
<h2 class="text-xl font-medium text-gray-100 mb-4">Process Telemetry Summary</h2>
<!-- Event Statistics Grid -->
<div class="grid grid-cols-3 gap-4 mb-6">
{% if analysis_results.rededr and analysis_results.rededr.findings %}
{% set findings = analysis_results.rededr.findings %}
{% set summary = findings.summary %}
<!-- Basic Stats -->
<div class="bg-gray-900/30 rounded-lg border border-gray-800 p-4">
<div class="flex items-center space-x-2 mb-4">
<svg class="w-5 h-5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
</svg>
<h3 class="text-lg font-medium text-gray-200">Activity Stats</h3>
</div>
<div class="space-y-2">
<div class="flex justify-between">
<span class="text-gray-400">Total Events:</span>
<span class="text-gray-200">{{ summary.total_events }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-400">DLLs Loaded:</span>
<span class="text-gray-200">{{ summary.total_dlls }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-400">Images Loaded:</span>
<span class="text-gray-200">{{ summary.total_image_loads }}</span>
</div>
</div>
</div>
<!-- Process Information -->
<div class="bg-gray-900/30 rounded-lg border border-gray-800 p-4">
<div class="flex items-center space-x-2 mb-4">
<svg class="w-5 h-5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
</svg>
<h3 class="text-lg font-medium text-gray-200">Process Info</h3>
</div>
<div class="space-y-2">
<div class="flex justify-between">
<span class="text-gray-400">Child Processes:</span>
<span class="text-gray-200">{{ summary.total_child_processes }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-400">Active Threads:</span>
<span class="text-gray-200">{{ summary.total_threads }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-400">Image Unloads:</span>
<span class="text-gray-200">{{ summary.total_image_unloads }}</span>
</div>
</div>
</div>
<!-- Process Details -->
<div class="bg-gray-900/30 rounded-lg border border-gray-800 p-4">
<div class="flex items-center space-x-2 mb-4">
<svg class="w-5 h-5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<h3 class="text-lg font-medium text-gray-200">Process Details</h3>
</div>
<div class="space-y-2 text-sm">
<div class="flex flex-col">
<span class="text-gray-400">PID:</span>
<span class="text-gray-200">{{ findings.process_info.pid }}</span>
</div>
<div class="flex flex-col">
<span class="text-gray-400">Parent PID:</span>
<span class="text-gray-200">{{ findings.process_info.parent_pid }}</span>
</div>
<div class="flex flex-col">
<span class="text-gray-400">Status:</span>
<span class="text-gray-200">{{ 'Protected' if findings.process_info.is_protected_process else 'Standard' }}</span>
</div>
</div>
</div>
{% else %}
<div class="col-span-3 bg-gray-900/30 rounded-lg border border-gray-800 p-4">
<p class="text-gray-400">No RedEdr telemetry data available.</p>
</div>
{% endif %}
</div>
</div>
<!-- Payload Output Section -->
<div class="mt-8">
<h2 class="text-xl font-medium text-gray-100 mb-4">Process Output</h2>
<div class="bg-gray-900/30 rounded-lg border border-gray-800 overflow-hidden">
<div class="p-4">
<button id="togglePayloadOutput"
class="w-full flex items-center justify-between text-left">
<div class="flex items-center space-x-2">
<svg id="payloadChevron"
class="w-5 h-5 text-gray-400 transform transition-transform duration-200"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24">
<path stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7" />
</svg>
<span class="text-base font-medium text-gray-300">Captured Output</span>
</div>
<span class="text-sm px-2 py-1 rounded-full {{ 'bg-green-500/10 text-green-500' if analysis_results.get('process_output', {}).get('stdout') or analysis_results.get('process_output', {}).get('stderr') else 'bg-gray-800 text-gray-400' }}">
{{ 'Output Available' if analysis_results.get('process_output', {}).get('stdout') or analysis_results.get('process_output', {}).get('stderr') else 'No Output' }}
</span>
</button>
</div>
<!-- Collapsible Content -->
<div id="payloadOutputContent"
class="hidden border-t border-gray-800">
<div class="p-4 space-y-4">
<!-- STDOUT Section -->
{% if analysis_results.get('process_output', {}).get('stdout') %}
<div class="space-y-2">
<h5 class="text-sm font-medium text-gray-400">Standard Output</h5>
<div class="bg-black/30 rounded p-4 font-mono text-sm">
<pre class="text-gray-300 whitespace-pre-wrap">{{ analysis_results.get('process_output', {}).get('stdout') }}</pre>
</div>
</div>
{% endif %}
<!-- STDERR Section -->
{% if analysis_results.get('process_output', {}).get('stderr') %}
<div class="space-y-2">
<h5 class="text-sm font-medium text-gray-400">Standard Error</h5>
<div class="bg-black/30 rounded p-4 font-mono text-sm">
<pre class="text-red-300 whitespace-pre-wrap">{{ analysis_results.get('process_output', {}).get('stderr') }}</pre>
</div>
</div>
{% endif %}
<!-- Additional Info -->
{% if analysis_results.get('process_output', {}) %}
<div class="text-sm text-gray-500 italic">
{% if analysis_results.get('process_output', {}).get('output_truncated') %}
Output was truncated due to size limitations
{% if analysis_results.get('process_output', {}).get('exit_code') is not none %} • {% endif %}
{% endif %}
{% if analysis_results.get('process_output', {}).get('exit_code') is not none %}
Process exit code: {{ analysis_results.get('process_output', {}).get('exit_code') }}
{% endif %}
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const toggleBtn = document.getElementById('togglePayloadOutput');
const content = document.getElementById('payloadOutputContent');
const chevron = document.getElementById('payloadChevron');
if (toggleBtn && content && chevron) {
toggleBtn.addEventListener('click', function() {
content.classList.toggle('hidden');
chevron.classList.toggle('rotate-90');
});
}
});
</script>
{% endblock %}