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()