process_email.php aktualisiert
This commit is contained in:
@ -53,15 +53,82 @@ function parseEmailHeaders($emailContent) {
|
|||||||
|
|
||||||
function checkPhishing($headers, $emailContent) {
|
function checkPhishing($headers, $emailContent) {
|
||||||
$warnings = [];
|
$warnings = [];
|
||||||
|
$phishingScore = 0; // Ein einfacher Zähler für Phishing-Indikatoren
|
||||||
|
|
||||||
// 1. Absenderprüfung (From vs. Return-Path vs. Reply-To)
|
// --- Prüfung des E-Mail-Inhalts (Body und Betreff) - Priorität 1 ---
|
||||||
|
|
||||||
|
// 1. Häufige Phishing-Keywords im Betreff oder Body
|
||||||
|
$keywords = ['bestätigung', 'konto', 'passwort', 'sicherheit', 'aktualisieren', 'blockiert', 'dringend', 'zahlung', 'rechnung', 'gewinn', 'glückwunsch', 'probleme', 'verifizierung', 'warnung'];
|
||||||
|
$foundContentKeywords = 0;
|
||||||
|
foreach ($keywords as $keyword) {
|
||||||
|
if (stripos($headers['Subject'] ?? '', $keyword) !== false) {
|
||||||
|
$warnings[] = "Hinweis (Inhalt): Das Wort '" . htmlspecialchars($keyword) . "' wurde im Betreff gefunden. Dies ist oft in Phishing-Mails zu finden.";
|
||||||
|
$foundContentKeywords++;
|
||||||
|
}
|
||||||
|
if (stripos($emailContent, $keyword) !== false) {
|
||||||
|
$warnings[] = "Hinweis (Inhalt): Das Wort '" . htmlspecialchars($keyword) . "' wurde im E-Mail-Text gefunden. Dies ist oft in Phishing-Mails zu finden.";
|
||||||
|
$foundContentKeywords++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($foundContentKeywords > 0) $phishingScore += min($foundContentKeywords, 3); // Max 3 Punkte für Keywords
|
||||||
|
|
||||||
|
// 2. Ungewöhnliche Zeichen oder Encoding im Betreff (könnte auf Verschleierung hindeuten)
|
||||||
|
$subject = isset($headers['Subject']) ? $headers['Subject'] : '';
|
||||||
|
if (preg_match('/=\?UTF-8\?B\?/', $subject) || preg_match('/=\?UTF-8\?Q\?/', $subject)) {
|
||||||
|
// Dies ist oft legitimes Encoding, aber bei Phishing wird es manchmal missbraucht.
|
||||||
|
// Keine direkte Warnung hier, da es zu viele False-Positives gäbe, aber ein leichter Punkt.
|
||||||
|
// $warnings[] = "Hinweis (Inhalt): Der Betreff enthält codierte Zeichen (Quoted-Printable oder Base64).";
|
||||||
|
// $phishingScore += 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 3. Links prüfen (verbessert: prüft auf offensichtliche URL-Diskrepanzen, IPs, Shortener)
|
||||||
$from = isset($headers['From']) ? strtolower($headers['From']) : '';
|
$from = isset($headers['From']) ? strtolower($headers['From']) : '';
|
||||||
$returnPath = isset($headers['Return-Path']) ? strtolower($headers['Return-Path']) : '';
|
|
||||||
$replyTo = isset($headers['Reply-To']) ? strtolower($headers['Reply-To']) : '';
|
|
||||||
|
|
||||||
// Extrahieren der Domain
|
|
||||||
preg_match('/@([^>]+)/', $from, $fromDomainMatch);
|
preg_match('/@([^>]+)/', $from, $fromDomainMatch);
|
||||||
$fromDomain = isset($fromDomainMatch[1]) ? trim($fromDomainMatch[1]) : '';
|
$fromDomain = isset($fromDomainMatch[1]) ? trim($fromDomainMatch[1]) : '';
|
||||||
|
$foundSuspiciousLinks = 0;
|
||||||
|
|
||||||
|
if (preg_match_all('/https?:\/\/[^\s"\']+/i', $emailContent, $matches)) {
|
||||||
|
foreach (array_unique($matches[0]) as $url) { // Einzigartige URLs prüfen
|
||||||
|
$urlParts = parse_url($url);
|
||||||
|
$urlDomain = isset($urlParts['host']) ? strtolower($urlParts['host']) : '';
|
||||||
|
|
||||||
|
// Check for direct IP address in URL
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the URL domain is significantly different from the From domain
|
||||||
|
if ($urlDomain && $fromDomain && !empty($fromDomain)) {
|
||||||
|
// Eine robustere Prüfung könnte hier auch Subdomain-Tricks erkennen
|
||||||
|
// z.B. bank.com.malicious.example.com
|
||||||
|
if (strpos($urlDomain, $fromDomain) === false && 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add check for URL shorteners (simple regex)
|
||||||
|
$shortenerDomains = ['bit.ly', 'goo.gl', 'tinyurl.com', 'ow.ly', 't.co', 'cutt.ly', 'is.gd', 's.id']; // Add more as needed
|
||||||
|
foreach ($shortenerDomains as $shortener) {
|
||||||
|
if (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; // Zusätzlicher Punkt für Links
|
||||||
|
|
||||||
|
// --- Prüfung der Header-Daten - Priorität 2 ---
|
||||||
|
|
||||||
|
// 4. Absenderprüfung (From vs. Return-Path vs. Reply-To)
|
||||||
|
$returnPath = isset($headers['Return-Path']) ? strtolower($headers['Return-Path']) : '';
|
||||||
|
$replyTo = isset($headers['Reply-To']) ? strtolower($headers['Reply-To']) : '';
|
||||||
|
|
||||||
preg_match('/@([^>]+)/', $returnPath, $returnPathDomainMatch);
|
preg_match('/@([^>]+)/', $returnPath, $returnPathDomainMatch);
|
||||||
$returnPathDomain = isset($returnPathDomainMatch[1]) ? trim($returnPathDomainMatch[1]) : '';
|
$returnPathDomain = isset($returnPathDomainMatch[1]) ? trim($returnPathDomainMatch[1]) : '';
|
||||||
@ -71,57 +138,12 @@ function checkPhishing($headers, $emailContent) {
|
|||||||
|
|
||||||
|
|
||||||
if ($fromDomain && $returnPathDomain && $fromDomain !== $returnPathDomain) {
|
if ($fromDomain && $returnPathDomain && $fromDomain !== $returnPathDomain) {
|
||||||
$warnings[] = "Achtung: Die Absenderdomain ('" . htmlspecialchars($fromDomain) . "') stimmt nicht mit der 'Return-Path'-Domain ('" . htmlspecialchars($returnPathDomain) . "') überein. Dies könnte ein Indikator für Spoofing sein.";
|
$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;
|
||||||
}
|
}
|
||||||
if ($fromDomain && $replyToDomain && $fromDomain !== $replyToDomain) {
|
if ($fromDomain && $replyToDomain && $fromDomain !== $replyToDomain) {
|
||||||
$warnings[] = "Warnung: Die Absenderdomain ('" . htmlspecialchars($fromDomain) . "') stimmt nicht mit der 'Reply-To'-Domain ('" . htmlspecialchars($replyToDomain) . "') überein. Eine Diskrepanz kann auf Betrug hindeuten.";
|
$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;
|
||||||
|
|
||||||
// 2. Ungewöhnliche Zeichen oder Encoding im Betreff oder Absender
|
|
||||||
$subject = isset($headers['Subject']) ? $headers['Subject'] : '';
|
|
||||||
// Eine tiefergehende Prüfung würde hier das Decodieren des Betreffs erfordern
|
|
||||||
// und dann die Prüfung auf Homoglyphen oder ungewöhnliche Zeichen.
|
|
||||||
|
|
||||||
// 3. Häufige Phishing-Keywords im Betreff oder Body (sehr rudimentär)
|
|
||||||
$keywords = ['bestätigung', 'konto', 'passwort', 'sicherheit', 'aktualisieren', 'blockiert', 'dringend', 'zahlung', 'rechnung', 'gewinn', 'glückwunsch'];
|
|
||||||
foreach ($keywords as $keyword) {
|
|
||||||
if (stripos($subject, $keyword) !== false) {
|
|
||||||
$warnings[] = "Hinweis: Das Wort '" . htmlspecialchars($keyword) . "' wurde im Betreff gefunden. Dies ist oft in Phishing-Mails zu finden.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach ($keywords as $keyword) {
|
|
||||||
if (stripos($emailContent, $keyword) !== false) {
|
|
||||||
$warnings[] = "Hinweis: Das Wort '" . htmlspecialchars($keyword) . "' wurde im E-Mail-Text gefunden. Dies ist oft in Phishing-Mails zu finden.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 4. Links prüfen (verbessert: prüft auf offensichtliche URL-Diskrepanzen)
|
|
||||||
if (preg_match_all('/https?:\/\/[^\s"\']+/i', $emailContent, $matches)) {
|
|
||||||
foreach ($matches[0] as $url) {
|
|
||||||
$urlParts = parse_url($url);
|
|
||||||
$urlDomain = isset($urlParts['host']) ? strtolower($urlParts['host']) : '';
|
|
||||||
|
|
||||||
// Check for direct IP address in URL
|
|
||||||
if (filter_var($urlDomain, FILTER_VALIDATE_IP)) {
|
|
||||||
$warnings[] = "Warnung: Ein Link enthält eine direkte IP-Adresse ('" . htmlspecialchars($url) . "'). Dies ist oft verdächtig.";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the URL domain is significantly different from the From/Return-Path domain
|
|
||||||
if ($urlDomain && $fromDomain && !empty($fromDomain) && strpos($urlDomain, $fromDomain) === false && strpos($fromDomain, $urlDomain) === false) {
|
|
||||||
$warnings[] = "Warnung: Die Domain im Link ('" . htmlspecialchars($urlDomain) . "') weicht von der Absenderdomain ('" . htmlspecialchars($fromDomain) . "') ab. Vorsicht!";
|
|
||||||
}
|
|
||||||
// Add check for URL shorteners (simple regex)
|
|
||||||
$shortenerDomains = ['bit.ly', 'goo.gl', 'tinyurl.com', 'ow.ly', 't.co']; // Add more as needed
|
|
||||||
foreach ($shortenerDomains as $shortener) {
|
|
||||||
if (strpos($urlDomain, $shortener) !== false) {
|
|
||||||
$warnings[] = "Hinweis: Ein Link verwendet einen URL-Shortener ('" . htmlspecialchars($url) . "'). Dies kann zur Verschleierung bösartiger Ziele genutzt werden.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -129,7 +151,8 @@ function checkPhishing($headers, $emailContent) {
|
|||||||
$importantHeaders = ['From', 'To', 'Subject', 'Date', 'Message-ID'];
|
$importantHeaders = ['From', 'To', 'Subject', 'Date', 'Message-ID'];
|
||||||
foreach ($importantHeaders as $header) {
|
foreach ($importantHeaders as $header) {
|
||||||
if (!isset($headers[$header])) {
|
if (!isset($headers[$header])) {
|
||||||
$warnings[] = "Warnung: Der wichtige Header '" . htmlspecialchars($header) . "' fehlt.";
|
$warnings[] = "Hinweis (Header): Der wichtige Header '" . htmlspecialchars($header) . "' fehlt.";
|
||||||
|
$phishingScore += 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,35 +161,44 @@ function checkPhishing($headers, $emailContent) {
|
|||||||
$userAgent = isset($headers['User-Agent']) ? strtolower($headers['User-Agent']) : '';
|
$userAgent = isset($headers['User-Agent']) ? strtolower($headers['User-Agent']) : '';
|
||||||
|
|
||||||
if (empty($xMailer) && empty($userAgent)) {
|
if (empty($xMailer) && empty($userAgent)) {
|
||||||
$warnings[] = "Hinweis: 'X-Mailer' oder 'User-Agent' Header fehlen. Dies ist manchmal bei automatisierten oder ungewöhnlichen Mail-Systemen der Fall.";
|
$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;
|
||||||
} elseif (
|
} elseif (
|
||||||
(strpos($xMailer, 'microsoft outlook') === false && strpos($xMailer, 'thunderbird') === false &&
|
(strpos($xMailer, 'microsoft outlook') === false && strpos($xMailer, 'thunderbird') === false &&
|
||||||
strpos($xMailer, 'mail.app') === false && strpos($xMailer, 'gmail') === false && !empty($xMailer)) ||
|
strpos($xMailer, 'mail.app') === false && strpos($xMailer, 'gmail') === false && !empty($xMailer)) ||
|
||||||
(strpos($userAgent, 'microsoft outlook') === false && strpos($userAgent, 'thunderbird') === false &&
|
(strpos($userAgent, 'microsoft outlook') === false && strpos($userAgent, 'thunderbird') === false &&
|
||||||
strpos($userAgent, 'mail.app') === false && strpos($userAgent, 'gmail') === false && !empty($userAgent))
|
strpos($userAgent, 'mail.app') === false && strpos($userAgent, 'gmail') === false && !empty($userAgent))
|
||||||
) {
|
) {
|
||||||
$warnings[] = "Hinweis: Ungewöhnlicher oder unbekannter E-Mail-Client ('" . htmlspecialchars($xMailer . $userAgent) . "') im 'X-Mailer'/'User-Agent' Header erkannt. Kann ein Indikator für Massenversand oder Phishing sein.";
|
$warnings[] = "Hinweis (Header): Ungewöhnlicher oder unbekannter E-Mail-Client ('" . htmlspecialchars($xMailer . $userAgent) . "') im 'X-Mailer'/'User-Agent' Header erkannt. Kann ein Indikator für Massenversand oder Phishing sein.";
|
||||||
|
$phishingScore += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 7. Prüfung von Authentication-Results Header (SPF, DKIM, DMARC)
|
||||||
// 7. Prüfung von Authentication-Results Header (SPF, DKIM, DMARC) - NEU!
|
|
||||||
$authResults = isset($headers['Authentication-Results']) ? $headers['Authentication-Results'] : '';
|
$authResults = isset($headers['Authentication-Results']) ? $headers['Authentication-Results'] : '';
|
||||||
if (!empty($authResults)) {
|
if (!empty($authResults)) {
|
||||||
if (stripos($authResults, 'spf=fail') !== false || stripos($authResults, 'spf=softfail') !== false) {
|
if (stripos($authResults, 'spf=fail') !== false || stripos($authResults, 'spf=softfail') !== false) {
|
||||||
$warnings[] = "Kritische Warnung: SPF-Authentifizierung fehlgeschlagen oder Softfail. Die Absenderdomain ist möglicherweise gefälscht.";
|
$warnings[] = "Kritische Warnung (Header): SPF-Authentifizierung fehlgeschlagen oder Softfail. Die Absenderdomain ist möglicherweise gefälscht.";
|
||||||
|
$phishingScore += 3;
|
||||||
}
|
}
|
||||||
if (stripos($authResults, 'dkim=fail') !== false) {
|
if (stripos($authResults, 'dkim=fail') !== false) {
|
||||||
$warnings[] = "Kritische Warnung: DKIM-Authentifizierung fehlgeschlagen. Die E-Mail wurde möglicherweise manipuliert oder ist gefälscht.";
|
$warnings[] = "Kritische Warnung (Header): DKIM-Authentifizierung fehlgeschlagen. Die E-Mail wurde möglicherweise manipuliert oder ist gefälscht.";
|
||||||
|
$phishingScore += 3;
|
||||||
}
|
}
|
||||||
if (stripos($authResults, 'dmarc=fail') !== false || stripos($authResults, 'dmarc=quarantine') !== false || stripos($authResults, 'dmarc=reject') !== false) {
|
if (stripos($authResults, 'dmarc=fail') !== false || stripos($authResults, 'dmarc=quarantine') !== false || stripos($authResults, 'dmarc=reject') !== false) {
|
||||||
$warnings[] = "Kritische Warnung: DMARC-Authentifizierung fehlgeschlagen oder Aktion ausgelöst (Quarantine/Reject). Dies ist ein starkes Anzeichen für Phishing.";
|
$warnings[] = "Kritische Warnung (Header): DMARC-Authentifizierung fehlgeschlagen oder Aktion ausgelöst (Quarantine/Reject). Dies ist ein starkes Anzeichen für Phishing.";
|
||||||
|
$phishingScore += 4; // Höchster Wert für DMARC Fail
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$warnings[] = "Hinweis: 'Authentication-Results' Header fehlen. Dies kann auf eine fehlende oder nicht standardmäßige E-Mail-Authentifizierung hindeuten.";
|
$warnings[] = "Hinweis (Header): 'Authentication-Results' Header fehlen. Dies kann auf eine fehlende oder nicht standardmäßige E-Mail-Authentifizierung hindeuten.";
|
||||||
|
$phishingScore += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Bestimmung der Phishing-Tendenz ---
|
||||||
|
// Dies ist ein einfacher Schwellenwert. Sie können die Werte und Schwellenwerte anpassen.
|
||||||
|
// Ein Wert > 3 deutet auf eine hohe Phishing-Wahrscheinlichkeit hin.
|
||||||
|
$isPhishingTendency = $phishingScore >= 3.0; // Schwellenwert für "hoch"
|
||||||
|
|
||||||
return $warnings;
|
return ['warnings' => $warnings, 'is_phishing_tendency' => $isPhishingTendency];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -190,14 +222,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$headers = parseEmailHeaders($emailContent);
|
$headers = parseEmailHeaders($emailContent);
|
||||||
$phishingChecks = checkPhishing($headers, $emailContent);
|
$phishingResult = checkPhishing($headers, $emailContent); // Holt jetzt Array mit Warnings und Tendenz
|
||||||
|
|
||||||
// Eine Vorschau des E-Mail-Inhalts für die Debugging-Zwecke
|
// Eine Vorschau des E-Mail-Inhalts für die Debugging-Zwecke
|
||||||
$fullEmailPreview = substr($emailContent, 0, 2000); // Max. 2000 Zeichen
|
$fullEmailPreview = substr($emailContent, 0, 2000); // Max. 2000 Zeichen
|
||||||
|
|
||||||
$result = [
|
$result = [
|
||||||
'headers' => $headers,
|
'headers' => $headers,
|
||||||
'phishing_check' => $phishingChecks,
|
'phishing_check' => $phishingResult['warnings'],
|
||||||
|
'is_phishing_tendency' => $phishingResult['is_phishing_tendency'],
|
||||||
'full_email_preview' => $fullEmailPreview
|
'full_email_preview' => $fullEmailPreview
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user