0) { $phishingScore += min($foundContentKeywords, 3); log_message("Phishing check: Found " . $foundContentKeywords . " keywords."); } $fromDomain = ''; if (preg_match('/@([^>]+)/', $from, $fromDomainMatch)) { $fromDomain = trim($fromDomainMatch[1]); } $foundSuspiciousLinks = 0; if (preg_match_all('/https?:\/\/[^\s"\']+/i', $emailContent, $matches)) { log_message("Phishing check: Found " . count($matches[0]) . " URLs."); foreach (array_unique($matches[0]) as $url) { $urlParts = parse_url($url); $urlDomain = isset($urlParts['host']) ? mb_strtolower($urlParts['host']) : ''; if (filter_var($urlDomain, FILTER_VALIDATE_IP)) { $warnings[] = "Kritische Warnung (Inhalt/Links): Ein Link enthält eine direkte IP-Adresse ('" . htmlspecialchars($url) . "'). Dies ist oft verdächtig."; $phishingScore += 2; $foundSuspiciousLinks++; } if ($urlDomain && $fromDomain && !empty($fromDomain)) { if (mb_strpos($urlDomain, $fromDomain) === false && mb_strpos($fromDomain, $urlDomain) === false) { $warnings[] = "Kritische Warnung (Inhalt/Links): Die Domain im Link ('" . htmlspecialchars($urlDomain) . "') weicht von der Absenderdomain ('" . htmlspecialchars($fromDomain) . "') ab. Vorsicht!"; $phishingScore += 3; $foundSuspiciousLinks++; } } $shortenerDomains = ['bit.ly', 'goo.gl', 'tinyurl.com', 'ow.ly', 't.co', 'cutt.ly', 'is.gd', 's.id']; foreach ($shortenerDomains as $shortener) { if (mb_strpos($urlDomain, $shortener) !== false) { $warnings[] = "Hinweis (Inhalt/Links): Ein Link verwendet einen URL-Shortener ('" . htmlspecialchars($url) . "'). Dies kann zur Verschleierung bösartiger Ziele genutzt werden."; $phishingScore += 1; $foundSuspiciousLinks++; break; } } } } if ($foundSuspiciousLinks > 0) { $phishingScore += 2; log_message("Phishing check: Found " . $foundSuspiciousLinks . " suspicious links."); } // --- Prüfung der Header-Daten - Priorität 2 --- $returnPathDomain = ''; if (preg_match('/@([^>]+)/', $returnPath, $returnPathDomainMatch)) { $returnPathDomain = trim($returnPathDomainMatch[1]); } $replyToDomain = ''; if (preg_match('/@([^>]+)/', $replyTo, $replyToDomainMatch)) { $replyToDomain = trim($replyToDomainMatch[1]); } if ($fromDomain && $returnPathDomain && $fromDomain !== $returnPathDomain) { $warnings[] = "Warnung (Header): Die Absenderdomain ('" . htmlspecialchars($fromDomain) . "') stimmt nicht mit der 'Return-Path'-Domain ('" . htmlspecialchars($returnPathDomain) . "') überein. Dies könnte ein Indikator für Spoofing sein."; $phishingScore += 2; log_message("Phishing check: From vs Return-Path mismatch."); } if ($fromDomain && $replyToDomain && $fromDomain !== $replyToDomain) { $warnings[] = "Warnung (Header): Die Absenderdomain ('" . htmlspecialchars($fromDomain) . "') stimmt nicht mit der 'Reply-To'-Domain ('" . htmlspecialchars($replyToDomain) . "') überein. Eine Diskrepanz kann auf Betrug hindeuten."; $phishingScore += 2; log_message("Phishing check: From vs Reply-To mismatch."); } $importantHeaders = ['From', 'To', 'Subject', 'Date', 'Message-ID']; foreach ($importantHeaders as $header) { if (!isset($headers[$header]) || empty($headers[$header])) { $warnings[] = "Hinweis (Header): Der wichtige Header '" . htmlspecialchars($header) . "' fehlt oder ist leer."; $phishingScore += 0.5; log_message("Phishing check: Missing/empty important header: " . $header); } } if (empty($xMailer) && empty($userAgent)) { $warnings[] = "Hinweis (Header): 'X-Mailer' oder 'User-Agent' Header fehlen. Dies ist manchmal bei automatisierten oder ungewöhnlichen Mail-Systemen der Fall."; $phishingScore += 0.5; log_message("Phishing check: Missing X-Mailer/User-Agent."); } else { $foundUnusualMailer = false; $commonMailers = ['microsoft outlook', 'thunderbird', 'mail.app', 'gmail']; if (!empty($xMailer)) { $isCommon = false; foreach($commonMailers as $mailer) { if (mb_strpos(mb_strtolower($xMailer), $mailer) !== false) { $isCommon = true; break; } } if (!$isCommon) { $foundUnusualMailer = true; } } if (!$foundUnusualMailer && !empty($userAgent)) { $isCommon = false; foreach($commonMailers as $mailer) { if (mb_strpos(mb_strtolower($userAgent), $mailer) !== false) { $isCommon = true; break; } } if (!$isCommon) { $foundUnusualMailer = true; } } if ($foundUnusualMailer) { $warnings[] = "Hinweis (Header): Ungewöhnlicher oder unbekannter E-Mail-Client im 'X-Mailer'/'User-Agent' Header erkannt ('" . htmlspecialchars($xMailer . $userAgent) . "'). Kann ein Indikator für Massenversand oder Phishing sein."; $phishingScore += 1; log_message("Phishing check: Unusual X-Mailer/User-Agent."); } } if (!empty($authResults)) { if (mb_stripos($authResults, 'spf=fail') !== false || mb_stripos($authResults, 'spf=softfail') !== false) { $warnings[] = "Kritische Warnung (Header): SPF-Authentifizierung fehlgeschlagen oder Softfail. Die Absenderdomain ist möglicherweise gefälscht."; $phishingScore += 3; log_message("Phishing check: SPF fail/softfail."); } if (mb_stripos($authResults, 'dkim=fail') !== false) { $warnings[] = "Kritische Warnung (Header): DKIM-Authentifizierung fehlgeschlagen. Die E-Mail wurde möglicherweise manipuliert oder ist gefälscht."; $phishingScore += 3; log_message("Phishing check: DKIM fail."); } if (mb_stripos($authResults, 'dmarc=fail') !== false || mb_stripos($authResults, 'dmarc=quarantine') !== false || mb_stripos($authResults, 'dmarc=reject') !== false) { $warnings[] = "Kritische Warnung (Header): DMARC-Authentifizierung fehlgeschlagen oder Aktion ausgelöst (Quarantine/Reject). Dies ist ein starkes Anzeichen für Phishing."; $phishingScore += 4; log_message("Phishing check: DMARC fail/quarantine/reject."); } } else { $warnings[] = "Hinweis (Header): 'Authentication-Results' Header fehlen. Dies kann auf eine fehlende oder nicht standardmäßige E-Mail-Authentifizierung hindeuten."; $phishingScore += 1; log_message("Phishing check: Missing Authentication-Results."); } $isPhishingTendency = $phishingScore >= 3.0; log_message("Finished checkPhishing function. Phishing Score: " . $phishingScore . ", Tendency: " . ($isPhishingTendency ? "HIGH" : "LOW")); return ['warnings' => $warnings, 'is_phishing_tendency' => $isPhishingTendency]; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { log_message("Script started via POST request."); try { if (isset($_FILES['email_file']) && $_FILES['email_file']['error'] === UPLOAD_ERR_OK) { $fileTmpPath = $_FILES['email_file']['tmp_name']; $fileName = $_FILES['email_file']['name']; $fileSize = $_FILES['email_file']['size']; $fileType = $_FILES['email_file']['type']; log_message("File uploaded: " . $fileName . ", size: " . $fileSize . " bytes."); $fileExtension = ''; $fileNameParts = explode(".", $fileName); if (count($fileNameParts) > 1) { $fileExtension = mb_strtolower(end($fileNameParts)); } $allowedfileExtensions = array('eml', 'txt'); if (in_array($fileExtension, $allowedfileExtensions)) { log_message("File extension is allowed: " . $fileExtension); $emailContent = @file_get_contents($fileTmpPath); if ($emailContent === false) { log_message("ERROR: Failed to read file content from " . $fileTmpPath); header('Location: index.php?error=' . rawurlencode('Fehler beim Lesen der hochgeladenen Datei oder Datei ist leer.')); exit(); } log_message("File content read successfully. Length: " . mb_strlen($emailContent) . " bytes."); if (!mb_check_encoding($emailContent, 'UTF-8')) { log_message("WARNING: Email content not initially UTF-8. Attempting conversion."); $emailContent = mb_convert_encoding($emailContent, 'UTF-8', 'auto'); if (!mb_check_encoding($emailContent, 'UTF-8')) { log_message("ERROR: Failed to convert email content to UTF-8 after attempt."); } else { log_message("Successfully converted email content to UTF-8."); } } $headers = parseEmailHeaders($emailContent); $phishingResult = checkPhishing($headers, $emailContent); $fullEmailPreview = mb_substr($emailContent, 0, 2000); $fullEmailPreview = preg_replace('/[^\x{0009}\x{000A}\x{000D}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]/u', '', $fullEmailPreview); $result = [ 'headers' => $headers, 'phishing_check' => $phishingResult['warnings'], 'is_phishing_tendency' => $phishingResult['is_phishing_tendency'], 'full_email_preview' => $fullEmailPreview ]; // --- NEUE LOGIK: Ergebnis in temporäre Datei schreiben --- $tempDir = __DIR__ . '/temp_results/'; // Temporäres Verzeichnis if (!is_dir($tempDir)) { mkdir($tempDir, 0755, true); // Verzeichnis erstellen, wenn es nicht existiert log_message("Created temp_results directory: " . $tempDir); } $resultId = uniqid('email_analysis_', true) . '.json'; // Eindeutiger Dateiname $tempFilePath = $tempDir . $resultId; // Speichern des JSON-Ergebnisses in der temporären Datei $jsonResult = json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR); if ($jsonResult === false) { log_message("ERROR: JSON encoding failed: " . json_last_error_msg()); throw new Exception("Fehler beim Kodieren der Analyseergebnisse."); } if (file_put_contents($tempFilePath, $jsonResult) === false) { log_message("ERROR: Failed to write result to temp file: " . $tempFilePath); throw new Exception("Fehler beim Speichern der Analyseergebnisse."); } log_message("Analysis result saved to temp file: " . $tempFilePath); // Weiterleitung mit dem Dateinamen als Parameter log_message("Analysis completed. Redirecting to index.php with result ID: " . $resultId); header('Location: index.php?result_id=' . rawurlencode($resultId)); exit(); } else { log_message("ERROR: Invalid file type uploaded: " . $fileExtension); header('Location: index.php?error=' . rawurlencode('Ungültiger Dateityp. Bitte laden Sie eine .eml- oder .txt-Datei hoch.')); exit(); } } else { $uploadError = 'Unbekannter Fehler beim Hochladen der Datei.'; if (isset($_FILES['email_file']) && $_FILES['email_file']['error'] !== UPLOAD_ERR_NO_FILE) { switch ($_FILES['email_file']['error']) { case UPLOAD_ERR_INI_SIZE: $uploadError = 'Die hochgeladene Datei überschreitet die in der php.ini festgelegte maximale Dateigröße.'; break; case UPLOAD_ERR_FORM_SIZE: $uploadError = 'Die hochgeladene Datei überschreitet die im HTML-Formular festgelegte maximale Dateigröße.'; break; case UPLOAD_ERR_PARTIAL: $uploadError = 'Die Datei wurde nur teilweise hochgeladen.'; break; case UPLOAD_ERR_NO_FILE: $uploadError = 'Es wurde keine Datei hochgeladen.'; break; case UPLOAD_ERR_NO_TMP_DIR: $uploadError = 'Temporäres Verzeichnis fehlt.'; break; case UPLOAD_ERR_CANT_WRITE: $uploadError = 'Fehler beim Schreiben der Datei auf die Festplatte.'; break; case UPLOAD_ERR_EXTENSION: $uploadError = 'Eine PHP-Erweiterung hat das Hochladen der Datei gestoppt.'; break; } } log_message("ERROR: File upload error: " . $uploadError); header('Location: index.php?error=' . rawurlencode('Fehler beim Hochladen der Datei: ' . $uploadError)); exit(); } } catch (Throwable $e) { log_message("FATAL ERROR CAUGHT: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine()); header('Location: index.php?error=' . rawurlencode('Ein unerwarteter Fehler ist aufgetreten: ' . $e->getMessage())); exit(); } } else { log_message("Script accessed directly without POST data."); header('Location: index.php'); exit(); }