File size: 7,454 Bytes
ee79fef bd30f76 ee79fef 3535c75 ee79fef 6d857a0 ee79fef 7e33bcd ee79fef 6d857a0 ee79fef 3535c75 bd30f76 3535c75 bd30f76 3535c75 bd30f76 3535c75 bd30f76 3535c75 bd30f76 3535c75 bd30f76 3535c75 bd30f76 ee79fef 3535c75 bd30f76 ee79fef 3535c75 ee79fef bd30f76 ee79fef 3535c75 ee79fef bd30f76 ee79fef 3535c75 ee79fef bd30f76 ee79fef 3535c75 ee79fef 32af315 ee79fef 3535c75 bd30f76 ee79fef 7e33bcd ee79fef 3535c75 ee79fef bd30f76 ee79fef bd30f76 ee79fef bd30f76 ee79fef 3535c75 bd30f76 ee79fef 7e33bcd ee79fef 3535c75 bd30f76 3535c75 bd30f76 3535c75 bd30f76 3535c75 bd30f76 ee79fef 3535c75 bd30f76 ee79fef |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
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("<li>SPF FAIL: Сервер не разрешен для этого домена (+10)</li>")
if re.search(r"DKIM.*FAIL", headers, re.IGNORECASE):
score += 10
findings.append("<li>DKIM FAIL: Подпись DKIM фальшивая (+10)</li>")
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"<li>Отправитель ({from_email}) не совпадает с Return-Path ({return_email}) (+5)</li>")
# анализ самого текста
# словарь срочности и запугивания
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"<li>Психологическое давление: '{word}' (+2)</li>")
# проверка на действия
for word in keywords_action:
if word in body_lower:
score += 1
findings.append(f"<li>Запрос данных/действий: '{word}' (+1)</li>")
# проверка на жадность
for word in keywords_greed:
if word in body_lower:
score += 2
findings.append(f"<li>Приманка/Выигрыш: '{word}' (+2)</li>")
# анализ самих ссылок
ip_links = re.findall(r'https?://(?:[0-9]{1,3}\.){3}[0-9]{1,3}', body)
if ip_links:
score += 5
findings.append(f"<li>IP в ссылке: ({ip_links[0]}) (+5)</li>")
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"<li>Подозрительный домен '{tld}' (+2)</li>")
# вердикт
if score == 0:
verdict_text = "🟢 Уровень угрозы: НИЗКИЙ. Явных признаков фишинга не обнаружено."
findings_html = "Угроз не найдено."
elif score < 5:
verdict_text = f"🟡 Уровень угрозы: СРЕДНИЙ. Счет: {score}."
findings_html = f"<ul>{''.join(findings)}</ul>"
else:
verdict_text = f"🔴 Уровень угрозы: ВЫСОКИЙ. Счет: {score}."
findings_html = f"<ul>{''.join(findings)}</ul>"
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 <security@bank.com>\nReturn-Path: hacker@evil.ru",
"Ваш аккаунт будет заблокирован через 24 часа. Срочно подтвердите данные карты по ссылке: http://secure-login-update.ru"],
# нормальное письмо
["SPF: PASS\nDKIM: PASS\nFrom: University <edu@uni.ru>\nReturn-Path: edu@uni.ru",
"Уважаемый студент, напоминаем о необходимости оплатить обучение до 25 числа. Оплату можно произвести через личный кабинет университета."],
# реклама
["SPF: PASS\nFrom: Promo <promo@shop.com>",
"Только сегодня! Вы выбраны среди 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() |