1
0
Fork 0
security-lab/src/apps/yandex/Yandex.tsx

422 lines
19 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from 'react';
import './Yandex.css';
const YandexApp: React.FC = () => {
const [currentPage, setCurrentPage] = useState<'yandex' | 'email' | 'gosuslugi' | 'fakeSite' | 'telelitra' | 'searchResults'>('yandex');
const [selectedEmail, setSelectedEmail] = useState<number | null>(null);
const [login, setLogin] = useState('');
const [password, setPassword] = useState('');
const [showPhishingModal, setShowPhishingModal] = useState(false);
const [showSuccessModal, setShowSuccessModal] = useState(false);
const [showVirusModal, setShowVirusModal] = useState(false);
const [searchQuery, setSearchQuery] = useState('');
const [showFakeSiteWarning, setShowFakeSiteWarning] = useState(false);
const emails = [
{ id: 1, from: 'security@bank.ru', subject: 'Ваш аккаунт Госуслуги заблокирован', body: 'Уважаемый клиент! Ваш аккаунт был заблокирован. Для разблокировки перейдите по ссылке и подтвердите данные.' },
{ id: 2, from: 'noreply@gosuslugi.ru', subject: 'Подтверждение записи на портале Госуслуги', body: 'Ваша запись подтверждена. Для просмотра перейдите на сайт госуслуг.' }
];
const handlePhishingSubmit = () => {
if (login && password) {
setShowPhishingModal(true);
}
};
const handleGosuslugiLogin = () => {
if (login && password) {
setShowSuccessModal(true);
}
};
const handleSearch = () => {
if (searchQuery.toLowerCase().includes('телелитр')) {
setCurrentPage('searchResults');
} else {
alert('Ничего не найдено. Попробуйте найти "ТелеЛитр"');
}
};
const handleFakeLink = () => {
setCurrentPage('fakeSite');
};
const handleOfficialLink = () => {
setCurrentPage('telelitra');
};
const handleDownloadVirus = () => {
setShowVirusModal(true);
};
const MailIcon = () => (
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 4H4C2.9 4 2 4.9 2 6V18C2 19.1 2.9 20 4 20H20C21.1 20 22 19.1 22 18V6C22 4.9 21.1 4 20 4Z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
<path d="M22 7L12 13L2 7" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
</svg>
);
const GosuslugiIcon = () => (
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L2 7L12 12L22 7L12 2Z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
<path d="M2 17L12 22L22 17" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
<path d="M2 12L12 17L22 12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
</svg>
);
const BackIcon = () => (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 18L9 12L15 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
);
const EmailIcon = () => (
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 4H4C2.9 4 2 4.9 2 6V18C2 19.1 2.9 20 4 20H20C21.1 20 22 19.1 22 18V6C22 4.9 21.1 4 20 4Z" stroke="#666" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
<path d="M22 7L12 13L2 7" stroke="#666" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
</svg>
);
const WarningIcon = () => (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 8V12M12 16H12.01M3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12Z" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
);
const SecureIcon = () => (
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L3 7L12 12L21 7L12 2Z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
<path d="M12 12V21" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
<path d="M18 9.5V12C18 16 15 19 12 19C9 19 6 16 6 12V9.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
</svg>
);
if (currentPage === 'yandex') {
return (
<div className="app">
<div className="yandex-page">
<h1 className="yandex-logo">Яндекс</h1>
<div className="search-container">
<input
type="text"
placeholder="Найти..."
className="yandex-search"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && handleSearch()}
/>
<button className="yandex-btn" onClick={handleSearch}>Найти</button>
</div>
<div className="services-icons">
<div className="service-icon" onClick={() => setCurrentPage('email')}>
<div className="icon-circle">
<MailIcon />
</div>
<span>Почта</span>
</div>
<div className="service-icon" onClick={() => setCurrentPage('gosuslugi')}>
<div className="icon-circle">
<GosuslugiIcon />
</div>
<span>Госуслуги</span>
</div>
</div>
<p className="yandex-hint">Найдется всё. Например, ТелеЛитр</p>
</div>
</div>
);
}
// Страница результатов поиска
if (currentPage === 'searchResults') {
return (
<div className="app">
<div className="header-with-back">
<button className="back-btn" onClick={() => setCurrentPage('yandex')}>
<BackIcon />
Назад к поиску
</button>
</div>
<div className="search-results-page">
<div className="search-info">
<p>Результаты поиска: <strong>ТелеЛитр</strong></p>
<p className="results-count">Найдено 2 результата</p>
</div>
<div className="search-results-list">
{/* Официальный сайт */}
<div className="search-result official" onClick={handleOfficialLink}>
<div className="result-icon">🔒</div>
<div className="result-content">
<div className="result-title">ТелеЛитр - Официальный сайт</div>
<div className="result-url">https://tele-litra.gov.ru</div>
<div className="result-description">Крупнейшая библиотека электронных книг. Более 1 миллиона книг. Официальный сайт с лицензионными книгами.</div>
<div className="result-badge secure">Защищенное соединение</div>
</div>
</div>
{/* Поддельный сайт */}
<div className="search-result fake" onClick={handleFakeLink}>
<div className="result-icon"></div>
<div className="result-content">
<div className="result-title">ТелеЛитр - Скачать бесплатно</div>
<div className="result-url">http://tele-litra-free.download</div>
<div className="result-description">Скачай любую книгу бесплатно без регистрации! Все книги в открытом доступе.</div>
<div className="result-badge dangerous">Незащищенное соединение</div>
</div>
</div>
</div>
</div>
</div>
);
}
// Страница Госуслуг
if (currentPage === 'gosuslugi') {
return (
<div className="app">
<div className="header-with-back">
<button className="back-btn" onClick={() => setCurrentPage('yandex')}>
<BackIcon />
Назад к Яндекс
</button>
</div>
<div className="gosuslugi-page">
<div className="gosuslugi-header">
<GosuslugiIcon />
<h1 className="gosuslugi-title">Госуслуги</h1>
</div>
<p className='colorGos'>Добро пожаловать на портал государственных услуг</p>
<div className="login-form">
<input
type="text"
placeholder="Логин"
className="input-field"
value={login}
onChange={(e) => setLogin(e.target.value)}
/>
<input
type="password"
placeholder="Пароль"
className="input-field"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button className="login-btn" onClick={handleGosuslugiLogin}>Войти</button>
</div>
<p className="gosuslugi-note">Официальный сайт. Ваши данные в безопасности</p>
</div>
{showSuccessModal && (
<div className="modal-overlay">
<div className="modal success-modal">
<h3 className="success-title">Поздравляем!</h3>
<p>Вы успешно вошли на официальный сайт Госуслуг!</p>
<p>Все ваши данные в безопасности. Вы выполнили задание правильно!</p>
<div className="modal-data success-data">
<strong>Ваши данные:</strong><br/>
Логин: {login}<br/>
Пароль: {password}
</div>
<button onClick={() => { setShowSuccessModal(false); setCurrentPage('yandex'); }} className="modal-btn success-btn">Отлично!</button>
</div>
</div>
)}
</div>
);
}
if (currentPage === 'fakeSite') {
return (
<div className="app">
<div className="header-with-back warning-header">
<div className="warning-badge">
<WarningIcon />
<span>Незащищенное соединение</span>
</div>
<button className="back-btn" onClick={() => setCurrentPage('searchResults')}>
<BackIcon />
Назад к результатам
</button>
</div>
<div className="fake-site-page">
<div className="fake-site-content">
<h1 className="fake-title"> ТелеЛитр - НЕОФИЦИАЛЬНЫЙ САЙТ</h1>
<div className="warning-box">
<p> ВНИМАНИЕ! Этот сайт не имеет защищенного SSL-сертификата!</p>
<p>Ваше соединение не зашифровано. Данные могут быть перехвачены злоумышленниками.</p>
<p>Адресная строка: <span className="fake-url">http://tele-litra-free.download</span> (не защищено)</p>
</div>
<div className="download-section">
<p>Для скачивания книг установите наше приложение:</p>
<button className="download-btn" onClick={handleDownloadVirus}>
📥 Скачать TeleLitru_Installer.exe
</button>
</div>
</div>
</div>
{showVirusModal && (
<div className="modal-overlay">
<div className="modal virus-modal">
<div className="virus-icon">🦠</div>
<h3 className="virus-title">О НЕТ! ВЫ СКАЧАЛИ ВИРУС!</h3>
<p>Вы скачали файл с поддельного сайта. Это вредоносное ПО!</p>
<p>Никогда не скачивайте файлы с непроверенных сайтов и не переходите по подозрительным ссылкам!</p>
<div className="modal-data virus-data">
<strong>Что произошло:</strong><br/>
- Ваш компьютер заражен трояном<br/>
- Данные могли быть украдены<br/>
- Рекомендуется немедленно запустить антивирус<br/>
- Не вводите пароли на подозрительных сайтах
</div>
<button onClick={() => { setShowVirusModal(false); setCurrentPage('yandex'); }} className="modal-btn virus-btn">Я понял, больше так не буду</button>
</div>
</div>
)}
</div>
);
}
if (currentPage === 'telelitra') {
return (
<div className="app">
<div className="header-with-back secure-header">
<div className="secure-badge">
<SecureIcon />
<span>Защищенное соединение</span>
</div>
<button className="back-btn" onClick={() => setCurrentPage('searchResults')}>
<BackIcon />
Назад к результатам
</button>
</div>
<div className="telelitra-page">
<div className="telelitra-content">
<h1 className="telelitra-title"> ТелеЛитр - Официальный сайт</h1>
<div className="secure-box">
<p>🔒 SSL Сертификат подтвержден (Let's Encrypt)</p>
<p>Адресная строка: <span className="secure-url">https://tele-litra.gov.ru</span> (защищено)</p>
<p>Ваше соединение зашифровано. Сайт официальный и безопасный.</p>
</div>
<div className="info-section">
<h2>Добро пожаловать в ТелеЛитр!</h2>
<p>Крупнейшая официальная библиотека электронных книг.</p>
<div className="features">
<div className="feature">📚 Более 1 миллиона лицензионных книг</div>
<div className="feature">🎧 Аудиокниги от официальных издательств</div>
<div className="feature">📱 Официальное мобильное приложение</div>
<div className="feature">⭐ Рейтинги и отзывы читателей</div>
<div className="feature">💰 Бесплатные книги по школьной программе</div>
<div className="feature">🎓 Образовательные материалы</div>
</div>
<button className="register-btn" onClick={() => alert('Добро пожаловать на официальный сайт ТелеЛитр! Здесь безопасно.')}>
Зарегистрироваться
</button>
</div>
</div>
</div>
</div>
);
}
// Детали письма
if (selectedEmail) {
const email = emails.find(e => e.id === selectedEmail);
return (
<div className="app">
<div className="header-with-back">
<button className="back-btn" onClick={() => { setSelectedEmail(null); setCurrentPage('email'); }}>
<BackIcon />
Назад к письмам
</button>
<button className="back-btn yandex-back" onClick={() => setCurrentPage('yandex')}>
🏠 На главную
</button>
</div>
<div className="email-detail">
<div className="email-detail-header">
<EmailIcon />
<h3>{email?.subject}</h3>
</div>
<p className="email-from"><strong>От:</strong> {email?.from}</p>
<p className="email-body">{email?.body}</p>
{selectedEmail === 1 && (
<div className="phishing-form">
<h4>⚠️ Внимание! Подтвердите данные</h4>
<input
type="text"
placeholder="Логин"
value={login}
onChange={(e) => setLogin(e.target.value)}
className="input-field"
/>
<input
type="password"
placeholder="Пароль"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="input-field"
/>
<button onClick={handlePhishingSubmit} className="phishing-btn">Подтвердить</button>
</div>
)}
{selectedEmail === 2 && (
<div className="gosuslugi-link">
<button onClick={() => setCurrentPage('gosuslugi')} className="gosuslugi-nav-btn">
<GosuslugiIcon />
Перейти на сайт Госуслуг
</button>
</div>
)}
</div>
{showPhishingModal && (
<div className="modal-overlay">
<div className="modal">
<h3 className="modal-title">😱 О нет! Ваши данные украдены!</h3>
<p>Вы ввели логин и пароль на поддельном сайте.</p>
<p>Никогда не переходите по подозрительным ссылкам из писем!</p>
<div className="modal-data">
<strong>Украденные данные:</strong><br/>
Логин: {login}<br/>
Пароль: {password}
</div>
<button onClick={() => { setShowPhishingModal(false); setCurrentPage('yandex'); }} className="modal-btn">Понятно</button>
</div>
</div>
)}
</div>
);
}
// Список писем
return (
<div className="app">
<div className="header-with-back">
<button className="back-btn" onClick={() => setCurrentPage('yandex')}>
<BackIcon />
Назад к Яндекс
</button>
</div>
<div className="email-list">
<h2>Входящие</h2>
{emails.map(email => (
<div key={email.id} className="email-item" onClick={() => setSelectedEmail(email.id)}>
<div className="email-icon">
<EmailIcon />
</div>
<div className="email-info">
<strong>{email.from}</strong>
<p>{email.subject}</p>
</div>
</div>
))}
</div>
</div>
);
};
export default YandexApp;