import gradio as gr
import re
def extract_email(text):
"""Вытаскивает email"""
match = re.search(r'[\w\.-]+@[\w\.-]+', text)
return match.group(0) if match else None
def analyze_email(headers, body):
score = 0
findings = []
# анализ самих заголовков
if re.search(r"SPF.*FAIL", headers, re.IGNORECASE):
score += 10
findings.append("
SPF FAIL: Сервер не разрешен для этого домена (+10)")
if re.search(r"DKIM.*FAIL", headers, re.IGNORECASE):
score += 10
findings.append("DKIM FAIL: Подпись DKIM фальшивая (+10)")
from_match = re.search(r"^From:(.*)", headers, re.MULTILINE | re.IGNORECASE)
return_match = re.search(r"^Return-Path:(.*)", headers, re.MULTILINE | re.IGNORECASE)
if from_match and return_match:
from_email = extract_email(from_match.group(1))
return_email = extract_email(return_match.group(1))
if from_email and return_email and from_email != return_email:
score += 5
findings.append(f"Отправитель ({from_email}) не совпадает с Return-Path ({return_email}) (+5)")
# анализ самого текста
# словарь срочности и запугивания
keywords_urgency = [
"заблокирован", "срочно", "удаление", "ограничен", "suspension", "urgent", "immediate",
"остановлен", "удален", "удалён", "удалена", "остановлена", "ограничена", "заморожена",
"заморожен", "suspended",
# добавлено из тз учителя:
"немедленно", "аккаунт будет заблокирован", "блокировка счета", "блокировка аккаунта",
"служба безопасности"
]
# словарь требуемых действий
keywords_action = [
"verify", "update", "login", "вход", "пароль", "password", "аутентификация",
"authentication", "войдите", "требуется", "confirm", "confirmation",
# добавлено из тз учителя:
"подтвердите", "подтвердить", "данные карты", "конфиденциальная информация",
"подтвердите личность", "перевод средств", "поддержка банка"
]
# словарь жадности
keywords_greed = [
"freespin", "фриспин", "casino", "казино", "lottery", "1xbet", "лотерея", "бонус",
"распродажа", "бесплатно", "раздача", "подарок", "гифт", "giveaway", "выигрыш",
"скидка", "prize", "gift", "win", "победитель", "winner", "поздравляем", "congratulations",
# Добавлено из тз учителя:
"вы выиграли", "приз", "выбран случайным образом"
]
body_lower = body.lower()
# проверка на срочность
found_urgency = False
for word in keywords_urgency:
if word in body_lower:
# чтобы не начислять баллы за каждое слово много раз можно ограничить
# но в рамках задания суммируем
score += 2
findings.append(f"Психологическое давление: '{word}' (+2)")
# проверка на действия
for word in keywords_action:
if word in body_lower:
score += 1
findings.append(f"Запрос данных/действий: '{word}' (+1)")
# проверка на жадность
for word in keywords_greed:
if word in body_lower:
score += 2
findings.append(f"Приманка/Выигрыш: '{word}' (+2)")
# анализ самих ссылок
ip_links = re.findall(r'https?://(?:[0-9]{1,3}\.){3}[0-9]{1,3}', body)
if ip_links:
score += 5
findings.append(f"IP в ссылке: ({ip_links[0]}) (+5)")
suspicious_tlds = [".xyz", ".top", ".info", ".club", ".shop", ".site"] # добавил .shop из тз учителя
for tld in suspicious_tlds:
if tld in body_lower:
if re.search(rf"\w{tld}/\w", body_lower) or re.search(rf"\w{tld}\b", body_lower):
score += 2
findings.append(f"Подозрительный домен '{tld}' (+2)")
# вердикт
if score == 0:
verdict_text = "🟢 Уровень угрозы: НИЗКИЙ. Явных признаков фишинга не обнаружено."
findings_html = "Угроз не найдено."
elif score < 5:
verdict_text = f"🟡 Уровень угрозы: СРЕДНИЙ. Счет: {score}."
findings_html = f""
else:
verdict_text = f"🔴 Уровень угрозы: ВЫСОКИЙ. Счет: {score}."
findings_html = f""
return str(score), verdict_text, findings_html
# интерфейс
headers_input = gr.Textbox(label="1. Служебные заголовки", lines=5, placeholder="Вставьте заголовки (SPF, DKIM, From...)")
body_input = gr.Textbox(label="2. Текст письма", lines=10, placeholder="Вставьте текст письма...")
score_output = gr.Textbox(label="Итоговый счет угрозы", type="text", max_lines=1)
verdict_output = gr.Textbox(label="Финальный вердикт", type="text", max_lines=3)
findings_output = gr.HTML(label="Детализация обнаруженных угроз")
# примеры по тз учителя
examples_list = [
# фишинг
["SPF: FAIL\nFrom: Bank \nReturn-Path: hacker@evil.ru",
"Ваш аккаунт будет заблокирован через 24 часа. Срочно подтвердите данные карты по ссылке: http://secure-login-update.ru"],
# нормальное письмо
["SPF: PASS\nDKIM: PASS\nFrom: University \nReturn-Path: edu@uni.ru",
"Уважаемый студент, напоминаем о необходимости оплатить обучение до 25 числа. Оплату можно произвести через личный кабинет университета."],
# реклама
["SPF: PASS\nFrom: Promo ",
"Только сегодня! Вы выбраны среди 100 счастливчиков! Вы выиграли приз! Заберите свой приз на странице акции: https://promo-super-win.shop"]
]
gr.Interface(
fn=analyze_email,
inputs=[headers_input, body_input],
outputs=[score_output, verdict_output, findings_output],
title="Email Security Analyzer (Практика 3). Нуритдинов Марат (USE-26)",
description="Инструмент для оценки фишинга.",
examples=examples_list
).launch()