80% SOC-аналитиков пропускают критические следы в логах, потому что смотрят не туда и не тем. Они тонут в гигабайтах данных, пытаясь найти иголку в стоге сена, когда хакер уже давно пьет кофе с их паролями. Эта статья — твой личный гайд по форензике для начинающих, который научит видеть цифровые следы там, где другие видят лишь шум. Пристегнись, мы погружаемся в мир логов, ивентов и реальных расследований.
Ключевые выводы
Если у тебя всего 30 секунд, вот что нужно запомнить:- Базовые навыки: Твой хлеб с маслом — это анализ Windows Event Log (Event ID 4624, 4625), Linux syslog/auth.log через Grep и сетевые логи в Wireshark. Без этого никуда.
- Российские реалии: В наших широтах правят MaxPatrol SIEM, StaffCop и Kaspersky Security Center. Учись работать с ними, это твой пропуск в мир корпоративного SOC.
- Практический подход: Забудь про скучную теорию. 80% времени трать на ковыряние реальных логов, 20% — на чтение мануалов.
- Время на освоение: Будь готов потратить 2-3 месяца, чтобы начать уверенно анализировать инциденты и не краснеть на разборах.
- Бюджет: Готовься к цифрам. Инструменты стоят денег, и в корпоративном сегменте это 150-300 тыс. рублей в год на лицензии.
Содержание
- Что нужно знать
- Архитектура процесса форензики
- Основы анализа Windows Event Log для SOC-аналитика
- Linux системные логи: эффективные Grep-команды для аудита
- Сетевые логи: анализ PCAP-файлов в Wireshark
- Корреляция событий в российских SIEM-системах
- Построение цифрового следа: методология расследования
- Автоматизация форензики: скрипты для SOC
- Инструменты форензики для джуниор SOC-аналитиков 2025
- Монетизация навыков форензики на российском рынке
- Часто задаваемые вопросы
- Решение типовых проблем
- Ресурсы для углубления
Что нужно знать
Проверь себя. Без этого набора навыков дальше будет больно и непонятно.- Windows Event Log: Критически важен для 99% корпоративных сетей в РФ, построенных на доменах Active Directory. Для углубленного изучения рекомендую курс Пентест AD от практикующих специалистов.
- Linux системное администрирование: Ты должен понимать базовые команды и структуру логов в
/var/log
, иначе потеряешься. - Сетевые протоколы: TCP/IP и HTTP/HTTPS — это азбука. Без нее анализ PCAP-файлов превратится в гадание на кофейной гуще.
- Регулярные выражения: Твой лучший друг для эффективного поиска в тоннах текстовых логов через Grep.
- SIEM-системы: Нужен практический опыт работы с MaxPatrol, Splunk или их аналогами.
- Знание 152-ФЗ: При расследовании инцидентов ты будешь иметь дело с персональными данными. Незнание закона не освобождает от ответственности.
Архитектура процесса форензики
Любое расследование, как хороший детектив, идет по четкому сценарию. Вот его скелет.Схема показывает три ключевых этапа форензики: сбор данных из различных источников, корреляция событий для выявления связей и финальное расследование с формированием выводов.
Основы анализа Windows Event Log для SOC-аналитика
Думаешь, Event Viewer — это скучно? А вот и нет. Это золотая жила для SOC-аналитика, особенно в доменных сетях.Критически важные Event ID для расследования инцидентов
Windows Event Log — твой главный источник правды о том, что творится в системе. Для джуниор SOC-аналитиков важно сфокусироваться на главном:Event ID 4624 — успешная аутентификация. Это событие — настоящий клад:
- Тип входа (Logon Type): 2 (интерактивный), 3 (сетевой), 10 (RDP).
- IP-адрес источника (Source Network Address).
- Имя учетной записи и домен.
- Уровень целостности процесса.
- Код ошибки (Failure Reason).
- Количество последовательных неудач.
- Источник атаки.
Event ID 4740 — блокировка учетной записи. Чаще всего это следствие brute-force атаки.
Практический анализ Event ID 4624 с use case
А теперь самое мясо. Разберем реальный кейс подозрительного входа в сеть российской IT-компании.
XML:
<Event>
<EventData>
<Data Name="LogonType">3</Data>
<Data Name="TargetUserName">admin_backup</Data>
<Data Name="TargetDomainName">DOMAIN</Data>
<Data Name="SourceNetworkAddress">192.168.1.100</Data>
<Data Name="LogonProcessName">NtLmSsp</Data>
<Data Name="AuthenticationPackageName">NTLM</Data>
<Data Name="ElevatedToken">%%1842</Data>
<Data Name="WorkstationName">WORKSTATION01</Data>
</EventData>
</Event>
- Сетевой вход (Type 3) глубокой ночью (02:15 MSK). Кто работает в это время?
- Административная учетная запись
admin_backup
используется не для бэкапов. Подозрительно. - NTLM-аутентификация вместо более безопасного Kerberos. Это устаревший протокол.
- Повышенные привилегии (
ElevatedToken=Yes
) сразу после входа.
Linux системные логи: эффективные Grep-команды для аудита
Пересаживаемся на пингвина. Если в твоей сети есть Linux-серверы (а они есть), безgrep
ты как без рук.Структура критически важных логов Linux
Linux хранит свои секреты в каталоге/var/log/
. Для форензики нас интересуют два файла:auth.log — все, что связано с аутентификацией и правами.
Bash:
# Анализ неудачных SSH-подключений
grep "Failed password" /var/log/auth.log | head -20
# Поиск подозрительных sudo-команд
grep -E "sudo.*COMMAND" /var/log/auth.log | grep -v "known_admin"
# Выявление brute-force по SSH
grep "Failed password" /var/log/auth.log | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | sort | uniq -c | sort -nr
# Дополнительные полезные команды для форензики:
# Поиск успешных SSH-входов
grep "Accepted password\|Accepted publickey" /var/log/auth.log
# Анализ su/sudo escalation
grep -E "(su:|sudo:)" /var/log/auth.log | grep -E "(authentication failure|session opened)"
# Проверка изменений в sudoers
grep "sudoers" /var/log/auth.log
# Универсальная команда для RHEL/CentOS систем
grep "Failed password" /var/log/secure 2>/dev/null || grep "Failed password" /var/log/auth.log
[code=bash]
# Поиск критических ошибок системы
grep -i "critical\|emergency\|alert" /var/log/syslog
# Анализ сетевых подключений
grep -E "connection.*established|connection.*closed" /var/log/syslog
Продвинутые Grep-команды для SOC-аналитика
Готов к магии командной строки? Эти команды сэкономят тебе часы работы.Временная корреляция событий:
Bash:
# События за последние 24 часа с временными метками
grep "$(date --date='1 day ago' '+%b %d')" /var/log/auth.log | \
grep -E "authentication failure|Failed password"
Bash:
# События за последние 24 часа
journalctl --since "24 hours ago" | grep -E "authentication failure|Failed password"
# Альтернатива через grep с корректным форматом даты
grep -E "$(date '+%b %e')|$(date --date='1 day ago' '+%b %e')" /var/log/auth.log | \
grep -E "authentication failure|Failed password"
# Универсальная команда с временным диапазоном (последние 24 часа)
awk -v d1="$(date --date='24 hours ago' '+%Y-%m-%d %H:%M')" \
-v d2="$(date '+%Y-%m-%d %H:%M')" \
'$0 ~ /authentication failure|Failed password/ {print}' /var/log/auth.log
# Продвинутый вариант с точной временной корреляцией
for i in {0..23}; do
grep "$(date --date="$i hours ago" '+%b %e %H:')" /var/log/auth.log
done | grep -E "authentication failure|Failed password" | sort -k1,2
# Для систем с syslog-ng или rsyslog (ISO timestamp)
grep -E "$(date -Ihour --date='24 hours ago' | cut -d'T' -f1)" /var/log/auth.log | \
grep -E "authentication failure|Failed password"
# Мощная команда для корреляции с подсчетом по часам
for hour in {00..23}; do
echo "=== $(date '+%b %e') $hour:00-$hour:59 ==="
grep "$(date '+%b %e') $hour:" /var/log/auth.log | \
grep -cE "authentication failure|Failed password"
done
# Бонус: Временная корреляция с IP-адресами атакующих
grep -E "authentication failure|Failed password" /var/log/auth.log | \
sed -n "s/.*$(date '+%b %e').* from \([0-9.]*\).*/\1/p" | \
sort | uniq -c | sort -rn
Bash:
# Подозрительные команды с правами root
grep -E "sudo:.*USER=root.*COMMAND=" /var/log/auth.log | \
grep -vE "(systemctl|service|apt|apt-get|yum|dnf|snap|dpkg|rpm|journalctl|hostnamectl|timedatectl)" | \
tail -50
# Более точный паттерн с расширенным анализом
grep "sudo:" /var/log/auth.log | grep "USER=root" | \
grep -vE "COMMAND=/(usr/bin/)?(systemctl|service|apt|apt-get|yum|dnf|zypper|pacman|emerge|snap|flatpak|dpkg|rpm|update-alternatives|locale-gen|journalctl|hostnamectl|timedatectl|loginctl|networkctl|resolvectl|systemd-resolve)" | \
tail -50
# Продвинутые варианты для глубокого анализа:
# 1. Поиск выполнения скриптов и бинарников из подозрительных локаций
grep "sudo:.*COMMAND=" /var/log/auth.log | \
grep -E "COMMAND=(/tmp/|/dev/shm/|/var/tmp/|/home/.*/\.|wget|curl|nc|netcat|/bin/sh|/bin/bash)"
# 2. Анализ sudo с выводом пользователя и команды
grep "sudo:.*USER=root.*COMMAND=" /var/log/auth.log | \
sed -n 's/.[I]sudo: *\([^ ][/I]\).[I]COMMAND=\(.[/I]\)/User: \1 | Command: \2/p' | \
grep -vE "(systemctl|service|apt)" | tail -50
# 3. Статистика подозрительных sudo-команд по пользователям
grep "sudo:.*USER=root.*COMMAND=" /var/log/auth.log | \
grep -vE "(systemctl|service|apt|yum|dnf)" | \
awk '{for(i=1;i<=NF;i++) if($i ~ /^sudo:/) print $(i+1)}' | \
sort | uniq -c | sort -rn
# 4. Временная корреляция подозрительных sudo
grep "sudo:.*USER=root.*COMMAND=" /var/log/auth.log | \
grep -vE "(systemctl|service|apt|yum)" | \
awk '{print $1, $2, $3}' | uniq -c | sort -rn
# 5. Поиск изменения критических файлов через sudo
grep "sudo:.*COMMAND=" /var/log/auth.log | \
grep -E "(passwd|shadow|sudoers|authorized_keys|crontab|/etc/rc|/etc/init)"
# 6. КРИТИЧНО: Поиск потенциальных reverse shells
grep "sudo:.*COMMAND=" /var/log/auth.log | \
grep -E "(nc |netcat |bash -i|sh -i|/dev/tcp/|mkfifo|telnet |socat |python.*socket|perl.*socket|ruby.*socket|php.*fsockopen)"
Сетевые логи: анализ PCAP-файлов в Wireshark
Сетевой трафик не врет. Он показывает, кто, куда и зачем ходил по сети. Wireshark предоставляет мощные возможности для анализа PCAP-файлов.Базовые фильтры Wireshark для форензики
Вот несколько фильтров, которые должен знать каждый аналитик.Фильтрация подозрительного трафика:
Код:
# HTTP-трафик с подозрительными User-Agent
http.user_agent contains "sqlmap" or http.user_agent contains "Nmap" or
http.user_agent contains "nikto" or http.user_agent contains "masscan" or
http.user_agent contains "metasploit" or http.user_agent contains "ZmEu"
# DNS-запросы к подозрительным доменам
dns.qry.name contains ".tk" or dns.qry.name contains ".ml" or
dns.qry.name contains ".ga" or dns.qry.name contains ".cf" or
dns.qry.name matches ".*\.bit$" or dns.qry.name matches "[0-9]{10,}\."
# Большие объемы исходящих данных (возможная эксфильтрация)
tcp.len > 1460 and ip.src matches "^192\.168\.1\."
# Альтернативный точный вариант для подсети
(tcp.len > 1460) and (ip.src >= 192.168.1.0 and ip.src <= 192.168.1.255)
# Дополнительные критически важные фильтры для SOC:
# 1. Поиск PowerShell Empire C2 трафика
http.request.uri contains "news.php" or http.request.uri contains "login/process.php" or
http.cookie contains "session="
# 2. Обнаружение Cobalt Strike beacons
http.request.method == "POST" and http.request.uri matches "/(submit\.php|updates|visit\.js)"
# 3. Подозрительные HTTPS соединения (возможный C2)
tls.handshake.extensions_server_name contains ".duckdns.org" or
tls.handshake.extensions_server_name matches "[0-9]{1,3}-[0-9]{1,3}-[0-9]{1,3}-[0-9]{1,3}\."
# 4. Data exfiltration через DNS tunneling
dns.qry.name.len > 50 or dns.txt.length > 100
# 5. Обнаружение ARP spoofing
arp.duplicate-address-detected or arp.duplicate-address-frame
# 6. Подозрительные SMB операции (возможный lateral movement)
smb2.cmd == 5 and smb2.filename contains "$" and not smb2.filename contains "IPC$"
# 7. Обнаружение port scanning
tcp.flags.syn == 1 and tcp.flags.ack == 0 and tcp.window_size <= 1024
# 8. IRC трафик (часто используется ботнетами)
tcp.port == 6667 or tcp.port == 6697 or irc
# 9. Base64 encoded payloads в HTTP
http.request matches "^[A-Za-z0-9+/]{100,}={0,2}$" or
http.response matches "^[A-Za-z0-9+/]{100,}={0,2}$"
# 10. Выявление Mimikatz в трафике
frame contains "mimikatz" or frame contains "sekurlsa::" or
kerberos.error_code == 32
Код:
# TLS-соединения с подозрительными сертификатами
# Самоподписанные или с коротким сроком действия
x509ce.SubjectAltName == "" or
x509sat.printableString contains "localhost" or
x509sat.printableString contains "example.com" or
x509ce.BasicConstraints == 1 and tls.handshake.type == 11
# Проверка на подозрительные CN в сертификатах
tls.handshake.certificate and (
x509sat.printableString matches "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" or
x509sat.printableString contains "*.duckdns.org" or
x509sat.printableString contains "Let's Encrypt"
)
# SSH-соединения в нерабочее время
tcp.port == 22 and frame.time >= "Jan 15, 2024 22:00:00" and frame.time <= "Jan 16, 2024 06:00:00"
# Альтернативный формат времени (epoch)
tcp.port == 22 and frame.time_epoch >= 1705353600 and frame.time_epoch <= 1705384800
# Продвинутые фильтры для анализа зашифрованного трафика:
# 1. Обнаружение слабых TLS версий
ssl.record.version == 0x0300 or ssl.record.version == 0x0301 or
tls.record.version == 0x0301 or tls.record.version == 0x0302
# 2. Подозрительные JA3 хеши (известные малварные)
tls.handshake.ja3 == "74927e242d6c3febf8cb9cab10a7f889" or
tls.handshake.ja3 == "72a589da586844d7f0818ce684948eea"
# 3. TLS с необычно
Практический кейс: анализ сетевой атаки
Давай разберем PCAP-файл с активностью в сети российской финансовой организации.Обнаружение сканирования портов: Ищем SYN-пакеты без ACK.
Код:
tcp.flags.syn == 1 and tcp.flags.ack == 0 and ip.src == 203.0.113.100
Код:
http.request.uri contains "/admin" or http.request.uri contains "../../"
Код:
# РАСШИРЕННОЕ обнаружение сканирования портов
# SYN scan от конкретного источника
tcp.flags.syn == 1 and tcp.flags.ack == 0 and ip.src == 203.0.113.100
# Обнаружение различных типов сканирования
# NULL scan
tcp.flags == 0x000
# FIN scan
tcp.flags.fin == 1 and tcp.flags.ack == 0
# XMAS scan
tcp.flags.fin == 1 and tcp.flags.push == 1 and tcp.flags.urg == 1
# ACK scan
tcp.flags.syn == 0 and tcp.flags.ack == 1 and tcp.flags.rst == 0 and tcp.len == 0
# Массовое сканирование (более 100 SYN пакетов)
tcp.flags.syn == 1 and tcp.flags.ack == 0 and tcp.window_size <= 1024
# КОМПЛЕКСНОЕ выявление попыток эксплуатации
http.request.uri contains "/admin" or
http.request.uri contains "../../" or
http.request.uri contains "../.." or
http.request.uri contains "..%2f" or
http.request.uri contains "..%252f" or
http.request.uri contains "%00" or
http.request.uri contains ".git" or
http.request.uri contains ".env" or
http.request.uri contains "web.config" or
http.request.uri matches ".*\\.(bak|backup|old|orig|~)$" or
http.request.uri contains "eval(" or
http.request.uri contains "exec(" or
http.request.uri contains "system(" or
http.request.uri contains "shell_exec" or
http.request.uri contains "phpinfo()" or
http.request.uri contains "<script" or
http.request.uri contains "javascript:" or
http.request.uri contains "onclick=" or
http.request.uri matches ".*union.*select.*" or
http.request.uri matches ".*\\'.*or.*\\'.*=.*\\'"
# ПРОДВИНУТЫЙ анализ C&C серверов
# DNS к подозрительным TLD и DGA доменам
(dns.qry.name matches ".*\\.bit$") or
(dns.qry.name matches ".*\\.onion$") or
(dns.qry.name matches ".*\\.i2p$") or
(dns.qry.name matches "[a-z]{20,}\\.") or
(dns.qry.name matches "[0-9a-f]{32}\\.")
# HTTPS на нестандартных портах (часто C&C)
tls and not (tcp.port == 443 or tcp.port == 8443)
# TCP на 443 без TLS (подозрительно)
(tcp.port == 443 and not tls)
# Специфичные для финансового сектора фильтры:
# 1. Попытки доступа к банковским API
http.request.uri contains "/api/v1/accounts" or
http.request.uri contains "/api/v1/transfers" or
http.request.uri contains "/api/v1/balance" or
http.request.uri contains "SWIFT" or
http.request.uri contains "transaction"
# 2. Обнаружение кражи сессий
http.cookie and (
http.request.uri contains "session=" or
http.request.uri contains "PHPSESSID=" or
http.request.uri contains "JSESSIONID="
)
# 3. Выявление попыток SQL инъекций в финансовых системах
http.request matches ".*(DROP|DELETE|INSERT|UPDATE).*ACCOUNTS.*" or
http.request matches ".*(DROP|DELETE|INSERT|UPDATE).*TRANSACTIONS.*"
# 4. Обнаружение data exfiltration через ICMP
icmp and data.len > 48
# 5. Beacon detection (регулярные интервалы)
tcp and frame.time_delta >= 59 and frame.time_delta <= 61
# 6. Cobalt Strike specific
http.request.uri matches "/(ab2g|ab2h|updates|visit\.js|fwlink)" or
http.user_agent == "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0)"
# 7. PowerShell Empire indicators
http.cookie contains "session=" and http.request.method == "POST"
Корреляция событий в российских SIEM-системах
Сырые логи — это хорошо, но SIEM-система — это мозг твоего SOC. Она связывает события из разных источников в единую картину.MaxPatrol SIEM: практические запросы для джуниоров
MaxPatrol SIEM от Positive Technologies — лидирующее решение на российском рынке информационной безопасности. Для эффективной корреляции событий используются специальные запросы (обзор рынка SIEM):Поиск аномальных входов:
SQL:
Поиск аномальных входов в MaxPatrol SIEM
-- Используем правильный синтаксис EPL
SELECT
time,
src.ip as source_ip,
dst.host as destination_host,
subject.account.name as user_name,
logon_type
FROM normalized
WHERE
msgid = 'WINDOWS-SUCCESSFUL-LOGON'
AND event_src.title = 'Windows'
AND id = '4624'
AND logon_type = 3
AND src.ip NOT IN ('10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16')
AND time >= now() - 24h
ORDER BY time DESC
-- Альтернативный вариант с использованием фильтров
table_list = {'windows_logon'}
| filter msgid = 'WINDOWS-SUCCESSFUL-LOGON'
| filter logon_type = 3
| filter src.ip != subnet('10.0.0.0/8')
| filter time >= now() - 24h
| table time, src.ip, subject.account.name, logon_type
🔓 Эксклюзивный контент для зарегистрированных пользователей.
SQL:
Корреляция Windows и Linux событий
-- Правильное правило корреляции для MaxPatrol SIEM
rule correlation_win_linux: (
sequence within 5m (
e1:msgid = 'WINDOWS-SUCCESSFUL-LOGON'
and id = '4624'
and logon_type = 3
e2:event_src.title = 'Linux'
and severity = 'high'
and e1.src.ip = e2.src.ip
)
)
-- Расширенные запросы для MaxPatrol SIEM:
-- 1. Обнаружение брутфорса
SELECT
src.ip,
dst.host,
subject.account.name,
count(*) as failed_attempts
FROM normalized
WHERE
msgid = 'WINDOWS-FAILED-LOGON'
AND id = '4625'
AND time >= now() - 1h
GROUP BY src.ip, dst.host, subject.account.name
HAVING count(*) > 5
ORDER BY failed_attempts DESC
-- 2. Обнаружение privilege escalation
table_list = {'windows_audit'}
| filter msgid IN ('WINDOWS-PRIVILEGE-USE', 'WINDOWS-SPECIAL-LOGON')
| filter subject.privileges contains 'SeDebugPrivilege'
or subject.privileges contains 'SeImpersonatePrivilege'
| filter time >= now() - 24h
| table time, subject.account.name, subject.privileges, src.host
-- 3. Корреляция PowerShell и сетевой активности
rule powershell_network: (
sequence within 1m (
e1:msgid = 'WINDOWS-POWERSHELL-SCRIPT-BLOCK'
and lower(text) contains 'invoke-webrequest'
or lower(text) contains 'downloadstring'
e2:msgid = 'FIREWALL-PERMIT'
and e1.src.host = e2.src.host
and e2.dst.port IN (80, 443, 8080)
)
)
-- 4. Обнаружение Mimikatz
SELECT
time,
src.host,
subject.account.name,
object.process.name,
text
FROM normalized
WHERE
event_src.title = 'Windows'
AND (
lower(text) contains 'mimikatz'
OR lower(text) contains 'sekurlsa'
OR lower(text) contains 'gentilkiwi'
OR msgid = 'WINDOWS-SYSMON-PROCESS-ACCESS'
AND object.process.name contains 'lsass.exe'
)
AND time >= now() - 7d
-- 5. Lateral Movement через RDP
table_list = {'windows_logon', 'network_traffic'}
| filter msgid = 'WINDOWS-SUCCESSFUL-LOGON'
| filter logon_type = 10 -- RDP
| filter src.ip != '127.0.0.1'
| join src.ip, time [
| filter protocol = 'RDP' or dst.port = 3389
| filter bytes_out > 10485760 -- > 10MB
]
| table time, src.ip, subject.account.name, bytes_out
-- 6. Обнаружение Data Exfiltration
SELECT
src.ip,
dst.ip,
sum(bytes_out) as total_bytes,
count(*) as connection_count
FROM normalized
WHERE
event_src.vendor = 'netflow'
AND dst.port IN (443, 8443, 53)
AND time >= now() - 1h
GROUP BY src.ip, dst.ip
HAVING sum(bytes_out) > 104857600 -- > 100MB
ORDER BY total_bytes DESC
-- 7. Обнаружение аномальных DNS запросов
table_list = {'dns'}
| filter msgid = 'DNS-QUERY'
| filter query_type IN ('TXT', 'NULL', 'PRIVATE')
or length(query) > 50
or regex(query, '[0-9a-f]{32}')
| stats count() by src.ip, query
| filter count > 10
| sort count desc
Splunk-запросы адаптированные для российских реалий
Хотя Splunk ограниченно доступен в РФ, многие организации используют его для анализа логов. Эти запросы помогут тебе быстро найти следы атаки.Базовый поиск инцидентов:
Код:
# ОПТИМИЗИРОВАННЫЙ базовый поиск инцидентов
index=security OR index=windows sourcetype="WinEventLog:Security" OR sourcetype="XmlWinEventLog:Security" EventCode=4625
| bin _time span=1h
| stats count as failed_attempts dc(user) as unique_users by src_ip, _time
| where failed_attempts > 10
| eval risk_score = case(
failed_attempts > 100, "CRITICAL",
failed_attempts > 50, "HIGH",
failed_attempts > 20, "MEDIUM",
1=1, "LOW"
)
| sort -failed_attempts
# Специфичные для российских организаций запросы:
# 1. Обнаружение использования российских VPN/прокси
index=* src_ip=*
| lookup geo_ip_lookup ip as src_ip OUTPUT country, city
| search country="Russia" OR country="Russian Federation"
| regex src_ip="^(185\.220\.|195\.123\.|91\.108\.|149\.154\.)"
| stats count by src_ip, country, city, user
| where count > 5
# 2. Мониторинг доступа к системам ГосСОПКА/НКЦКИ
index=security EventCode=4624 OR EventCode=4688
| search dest="*.gov.ru" OR dest="*.gosuslugi.ru" OR dest="*.cert.ru"
| eval critical_system = case(
match(dest, ".*gosuslugi.*"), "ГосУслуги",
match(dest, ".*cert\.ru"), "НКЦКИ",
match(dest, ".*gov\.ru"), "ГосПортал",
1=1, "Другое"
)
| stats count by user, src_ip, critical_system
| sort -count
# 3. Обнаружение активности российских APT (Cozy Bear, Fancy Bear patterns)
index=* sourcetype=*
| eval suspicious_pattern = case(
match(process_name, ".*servicehost\.exe"), 1,
match(process_name, ".*seethru\.exe"), 1,
match(CommandLine, ".*sekurlsa::.*"), 1,
match(CommandLine, ".*lsadump::.*"), 1,
match(url, ".*\.goodsblock\.ru"), 1,
match(dns_query, ".*\.vectorb\.net"), 1,
1=1, 0
)
| where suspicious_pattern=1
| stats count by host, user, process_name, CommandLine
# 4. Мониторинг обхода DLP-систем (популярных в РФ)
index=* sourcetype=proxy OR sourcetype=firewall
| search (url="*.telegram.org" OR url="*.tor2web.org" OR url="*.onion.*")
OR (dest_port=9050 OR dest_port=9150)
OR (app="Telegram" OR app="Signal" OR app="TOR")
| eval dlp_bypass = case(
match(url, ".*telegram.*"), "Telegram",
match(url, ".*tor.*|.*onion.*"), "TOR",
dest_port IN (9050, 9150), "TOR_Port",
1=1, "Other"
)
| stats count by src_ip, user, dlp_bypass
| where count > 10
# 5. Обнаружение использования КриптоПро/РуТокен
index=windows EventCode=4688
| search (process_name="*cryptcp.exe" OR process_name="*cpverify.exe" OR process_name="*rtDrivers.exe")
| eval crypto_tool = case(
match(process_name, ".*cryptcp.*"), "КриптоПро",
match(process_name, ".*rtDriver.*"), "РуТокен",
match(process_name, ".*cpverify.*"), "КриптоПро Verify",
1=1, "Unknown"
)
| stats count by user, host, crypto_tool, CommandLine
| sort -count
# 6. Мониторинг 1С и других российских ERP
index=* sourcetype=*1c* OR sourcetype=*galaktika*
| search (message="*EXCP*" OR message="*SDBL*" OR message="*deadlock*")
| eval system_type = case(
match(sourcetype, ".*1c.*"), "1C:Enterprise",
match(sourcetype, ".*galaktika.*"), "Галактика ERP",
1=1, "Other"
)
| timechart span=1h count by system_type
# 7. Обнаружение атак на Касперский/DrWeb endpoints
index=endpoint sourcetype="kaspersky:*" OR sourcetype="drweb:*"
| search (threat_name="*" OR action="blocked" OR severity="high")
| eval av_vendor = case(
match(sourcetype, "kaspersky"), "Kaspersky",
match(sourcetype, "drweb"), "Dr.Web",
1=1, "Unknown"
)
| stats count by threat_name, av_vendor, src_ip, dest_ip
| sort -count
# 8. Комплексная корреляция для банковского сектора РФ
index=* (EventCode=4624 OR EventCode=4625 OR sourcetype=cisco:asa OR sourcetype=squid)
| eval event_type = case(
EventCode=4624, "Successful_Logon",
EventCode=4625, "Failed_Logon",
match(sourcetype, "cisco"), "Firewall",
match(sourcetype, "squid"), "Proxy",
1=1, "Other"
)
| transaction src_ip maxspan=5m
| where eventcount > 20
| eval risk_indicators = mvcount(mvfilter(match(event_type, "Failed_Logon")))
| where risk_indicators > 5
| table _time, src_ip, user, risk_indicators, event_type
# 9. SWIFT/СПФ мониторинг (для финансового сектора)
index=* (message="*MT103*" OR message="*MT202*" OR message="*СПФС*" OR message="*СБП*")
| rex field=message "Amount:\s*(?<amount>[\d,\.]+)"
| eval amount_numeric = tonumber(replace(amount, ",", ""))
| where amount_numeric > 10000000
| eval payment_system = case(
match(message, "MT\d{3}"), "SWIFT",
match(message, "СПФС"), "СПФС",
match(message, "СБП"), "СБП",
1=1, "Unknown"
)
| stats sum(amount_numeric) as total_amount count by payment_system, src_ip
| eval total_amount_millions = round(total_amount/1000000, 2)
| sort -total_amount
# 10. Dashboard запрос для SOC (обобщенная статистика)
index=* earliest=-24h
| eval category = case(
EventCode IN (4624, 4625, 4720, 4740), "Authentication",
EventCode IN (4688, 4689), "Process",
EventCode IN (5140, 5145), "FileShare",
match(sourcetype, "firewall"), "Network",
match(sourcetype, "proxy"), "Web",
1=1, "Other"
)
| stats count sparkline(count) as trend by category
| eval severity = case(
category="Authentication" AND count>1000, "HIGH",
category="Process" AND count>5000, "MEDIUM",
1=1, "LOW"
)
| sort -count
🔓 Эксклюзивный контент для зарегистрированных пользователей.
Код:
# Временная корреляция событий
index=security (EventCode=4624 OR EventCode=4625)
| bin _time span=1h
| stats count(eval(EventCode=4624)) as successful,
count(eval(EventCode=4625)) as failed by _time, src_ip
| where failed > successful*3
| sort -failed
# ОПТИМИЗИРОВАННАЯ версия с дополнительными метриками
index=security OR index=windows EventCode IN (4624, 4625)
| bin _time span=1h
| stats count(eval(EventCode=4624)) as successful_logins,
count(eval(EventCode=4625)) as failed_logins,
dc(user) as unique_users,
values(user) as targeted_users by _time, src_ip
| eval failure_ratio = round(failed_logins / (successful_logins + 1), 2)
| eval attack_score = case(
failed_logins > 100 AND successful_logins = 0, "BRUTE_FORCE",
failed_logins > successful_logins*5, "CREDENTIAL_STUFFING",
failed_logins > successful_logins*3, "PASSWORD_SPRAY",
failed_logins > successful_logins, "SUSPICIOUS",
1=1, "NORMAL"
)
| where attack_score != "NORMAL"
| sort -failed_logins
# Продвинутые запросы для временной корреляции:
# 1. Обнаружение Password Spray с временными окнами
index=security EventCode=4625
| bucket _time span=5m
| stats count as attempts,
dc(user) as unique_targets,
dc(src_ip) as unique_sources,
values(user) as users by _time
| where unique_targets > 5 AND unique_sources < 3
| eval attack_pattern = "PASSWORD_SPRAY"
| table _time, attempts, unique_targets, users, attack_pattern
# 2. Корреляция успешного входа после брутфорса
index=security (EventCode=4624 OR EventCode=4625)
| sort 0 _time
| eval event_type=if(EventCode=4625, "failed", "success")
| transaction src_ip user maxspan=10m startswith="event_type=failed" endswith="event_type=success"
| where eventcount > 10
| eval bruteforce_success = "TRUE"
| table _time, src_ip, user, eventcount, duration
# 3. Выявление аномальных временных паттернов входа
index=security EventCode=4624
| eval hour=strftime(_time, "%H")
| eval day_of_week=strftime(_time, "%A")
| eval is_business_hours = if((hour>=9 AND hour<=18) AND NOT match(day_of_week, "Saturday|Sunday"), 1, 0)
| stats count as login_count by user, is_business_hours, src_ip
| eventstats avg(login_count) as avg_logins, stdev(login_count) as stdev_logins by user
| eval zscore = (login_count - avg_logins) / stdev_logins
| where abs(zscore) > 3 AND is_business_hours=0
| eval anomaly_type = "OFF_HOURS_ANOMALY"
# 4. Временная корреляция lateral movement
index=security (EventCode=4624 OR EventCode=4688 OR EventCode=5140)
| bin _time span=1m
| eval action = case(
EventCode=4624 AND Logon_Type=3, "NETWORK_LOGON",
EventCode=4688, "PROCESS_CREATED",
EventCode=5140, "SHARE_ACCESSED",
1=1, "OTHER"
)
| stats values(action) as actions,
dc(dest_host) as hosts_touched,
earliest(_time) as start_time,
latest(_time) as end_time by src_ip, user
| eval duration_minutes = round((end_time - start_time)/60, 2)
| where hosts_touched > 3 AND duration_minutes < 30
| eval risk_score = hosts_touched * 10 / duration_minutes
# 5. Обнаружение Time-based Evasion
index=*
| bin _time span=10s
| stats count by _time, src_ip
| streamstats window=6 avg(count) as avg_count, stdev(count) as stdev_count by src_ip
| eval is_regular = if(stdev_count < 0.1 AND avg_count > 0, 1, 0)
| where is_regular = 1
| eval pattern = "AUTOMATED_BEACON"
# 6. Корреляция DDoS по временным меткам
index=network OR index=firewall
| bin _time span=1s
| stats count as requests_per_second,
dc(src_ip) as unique_sources,
avg(bytes_in) as avg_packet_size by _time, dest_ip, dest_port
| where requests_per_second > 1000
| eval attack_type = case(
avg_packet_size < 100 AND unique_sources > 100, "SYN_FLOOD",
avg_packet_size > 1000 AND unique_sources > 50, "UDP_FLOOD",
requests_per_second > 5000, "HTTP_FLOOD",
1=1, "UNKNOWN_DDOS"
)
# 7. Обнаружение Data Exfiltration по времени
index=proxy OR index=firewall
| bin _time span=10m
| stats sum(bytes_out) as total_bytes,
count as connection_count,
values(dest_ip) as destinations by _time, src_ip
| eventstats avg(total_bytes) as avg_bytes,
stdev(total_bytes) as stdev_bytes by src_ip
| eval zscore = (total_bytes - avg_bytes) / stdev_bytes
| where zscore > 3
| eval exfil_risk = case(
total_bytes > 1073741824, "CRITICAL", # > 1GB
total_bytes > 104857600, "HIGH", # > 100MB
total_bytes > 10485760, "MEDIUM", # > 10MB
1=1, "LOW"
)
# 8. Временной анализ Persistence механизмов
index=windows (EventCode=4698 OR EventCode=4657 OR EventCode=7045 OR EventCode=4688)
| eval persistence_type = case(
EventCode=4698, "SCHEDULED_TASK",
EventCode=7045, "SERVICE_INSTALLED",
EventCode=4657, "REGISTRY_MODIFIED",
EventCode=4688 AND match(CommandLine, "reg add.*Run"), "REGISTRY_RUN_KEY",
1=1, "OTHER"
)
| bin _time span=5m
| stats count by _time, persistence_type, host
| where count > 1
| transaction host maxspan=30m
| where eventcount > 3
| eval risk = "PERSISTENCE_CHAIN_DETECTED"
# 9. Российская специфика: корреляция по московскому времени
index=* earliest=-24h
| eval moscow_time = strftime(_time + 10800, "%Y-%m-%d %H:%M:%S") # UTC+3
| eval moscow_hour = tonumber(strftime(_time + 10800, "%H"))
| eval is_russian_business_hours = if(moscow_hour >= 9 AND moscow_hour <= 18, "YES", "NO")
| stats count by is_russian_business_hours, EventCode
| eval suspicious = if(is_russian_business_hours="NO" AND count > 100, "AFTER_HOURS_ACTIVITY", "NORMAL")
Построение цифрового следа: методология расследования
А теперь собираем пазл. Как из разрозненных логов, IP-адресов и временных меток сложить полную картину атаки?Пошаговый алгоритм анализа инцидента
Этап 1: Первичная оценка (Timeline Analysis)- Определи временные рамки инцидента.
- Собери логи из всех доступных источников за этот период.
- Создай единую временную шкалу событий.
- Сопоставь события по IP-адресам. Один и тот же IP мог светиться в логах файрвола, веб-сервера и на контроллере домена.
- Проанализируй действия скомпрометированных учетных записей.
- Ищи аномальные паттерны поведения.
- Исследуй файловую систему на предмет новых или измененных файлов.
- Проведи глубокий анализ сетевого трафика.
- Изучи запущенные процессы и созданные службы.
Практический кейс взлома: пошаговая реконструкция
Исходные данные: Есть подозрение на компрометацию веб-сервера российского интернет-магазина. Поехали.Шаг 1: Анализ веб-логов Apache
🔓 Эксклюзивный контент для зарегистрированных пользователей.
Bash:
# Поиск SQL-инъекций с контекстом
grep -E "(\%27|\'|\%22|\"|union.*select|select.*from|insert.*into|drop.*table|exec\(|execute|xp_cmdshell|sp_executesql|<script|javascript:|onerror=|onclick=)" /var/log/apache2/access.log | \
grep -v "Googlebot\|bingbot" | head -50
# Правильное извлечение User-Agent
# Для combined log format Apache
awk -F'"' '{print $6}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head -10
# Альтернативный точный способ
grep -o '"[^"]*" "[^"]*"$' /var/log/apache2/access.log | cut -d'"' -f4 | sort | uniq -c | sort -nr | head -10
# Полный пошаговый анализ взлома интернет-магазина:
# ШАГ 1: RECONNAISSANCE - Обнаружение сканирования
echo "=== ПОИСК СЛЕДОВ СКАНИРОВАНИЯ ==="
# Поиск сканеров уязвимостей
grep -E "(nikto|sqlmap|nmap|masscan|burp|zap|acunetix|nessus|metasploit|w3af)" /var/log/apache2/access.log -i | \
awk '{print $1, $4, $7}' | head -20
# Поиск подозрительных роботов
grep -E "User-Agent.*(\(\)|bot|spider|crawler|scraper|harvest|extract|grab|mirror)" /var/log/apache2/access.log -i | \
grep -v "Googlebot\|bingbot\|Yandex" | head -20
# ШАГ 2: EXPLOITATION - Поиск эксплуатации
echo "=== АНАЛИЗ ПОПЫТОК ЭКСПЛУАТАЦИИ ==="
# SQL инъекции (расширенный поиск)
grep -E "(union.*select|select.*from|insert.*into|update.*set|delete.*from|drop.*table|\%27|\%22|0x[0-9a-f]+|concat\(|substring\(|ascii\(|sleep\(|benchmark\()" \
/var/log/apache2/access.log -i | head -30
# XSS атаки
grep -E "(<script|javascript:|onerror=|onload=|onclick=|<iframe|<embed|<object|alert\(|prompt\(|confirm\()" \
/var/log/apache2/access.log -i | head -20
# LFI/RFI атаки
grep -E "(\.\.\/|\.\.\\\\|\%2e\%2e|\%252e|\.\./\.\./|etc\/passwd|windows\/system32|boot\.ini|win\.ini|php:\/\/|data:\/\/|expect:\/\/|input:\/\/)" \
/var/log/apache2/access.log -i | head -20
# Command injection
grep -E "(\||;|&|\$\(|\`|%0a|%0d|system\(|exec\(|shell_exec|passthru\(|eval\()" \
/var/log/apache2/access.log | head -20
# ШАГ 3: PERSISTENCE - Поиск установки бэкдоров
echo "=== ПОИСК ВЕББЭКДОРОВ ==="
# Подозрительные PHP файлы
grep -E "(c99|r57|wso|b374k|webshell|shell\.php|cmd\.php|upload\.php|uploader\.php|system\.php|config\.php\.bak|\.php\.suspected)" \
/var/log/apache2/access.log -i | head -20
# Поиск загрузки файлов
grep -E "POST.*(upload|fileupload|attachment|file=|upfile=)" /var/log/apache2/access.log | \
awk '{print $1, $4, $7}' | head -20
# ШАГ 4: DATA EXFILTRATION - Анализ утечки данных
echo "=== АНАЛИЗ ВОЗМОЖНОЙ УТЕЧКИ ДАННЫХ ==="
# Массовые запросы к БД
awk '$10 > 100000 {print $1, $4, $7, $10}' /var/log/apache2/access.log | head -20
# Подозрительные запросы к admin панели
grep -E "(\/admin|\/manager|\/panel|\/cpanel|\/wp-admin|\/administrator|\/phpmyadmin)" \
/var/log/apache2/access.log | \
awk '{count[$1]++} END {for(ip in count) if(count[ip] > 50) print ip, count[ip]}' | sort -k2 -nr
# ШАГ 5: COVER TRACKS - Попытки скрыть следы
echo "=== ПОПЫТКИ СКРЫТЬ СЛЕДЫ ==="
# Поиск доступа к логам
grep -E "(access\.log|error\.log|\/var\/log|\/logs\/|log\.txt)" /var/log/apache2/access.log | head -10
# Запросы с подменой Referer/User-Agent
awk -F'"' '$4 ~ /Googlebot/ && $2 !~ /google\.com/ {print $1}' /var/log/apache2/access.log | \
cut -d' ' -f1 | sort -u
# КОМПЛЕКСНЫЙ АНАЛИЗ для российских интернет-магазинов:
# 1. Поиск атак на платежные системы
grep -E "(payment|oplata|checkout|kassa|acquiring|merchant|yandex\.checkout|tinkoff|sberbank|qiwi|webmoney)" \
/var/log/apache2/access.log | \
grep -E "(union|select|<script|\.\.\/|\%27)" | head -20
# 2. Анализ атак на 1С-Битрикс (популярная CMS в РФ)
grep -E "(\/bitrix\/admin|\/bitrix\/modules|\/bitrix\/tools|\/bitrix\/components|bitrix_sessid|bitrix_sm)" \
/var/log/apache2/access.log | \
awk '{print $1, $7}' | sort | uniq -c | sort -nr | head -20
# 3. Временной анализ (по МСК)
echo "=== ВРЕМЕННОЙ АНАЛИЗ АТАКИ ==="
awk '{print $4}' /var/log/apache2/access.log | \
sed 's/\[//; s/\/.*//' | \
uniq -c | \
awk '$1 > 1000 {print "Всплеск активности:", $2, "запросов:", $1}'
# 4. IP геолокация атакующих
echo "=== ГЕОЛОКАЦИЯ АТАКУЮЩИХ ==="
grep -E "(union.*select|\.\.\/|shell\.php)" /var/log/apache2/access.log | \
awk '{print $1}' | sort -u | \
while read ip; do
echo -n "$ip: "
whois $ip 2>/dev/null | grep -i country | head -1
done
# 5. Создание отчета для СБ
echo "=== ГЕНЕРАЦИЯ ОТЧЕТА ==="
{
echo "ОТЧЕТ О КОМПРОМЕТАЦИИ СЕРВЕРА"
echo "Дата: $(date)"
echo "Сервер: $(hostname)"
echo ""
echo "1. Уникальные IP атакующих:"
grep -E "(union|select|script|shell)" /var/log/apache2/access.log | \
awk '{print $1}' | sort -u | wc -l
echo ""
echo "2. Временной диапазон атаки:"
grep -E "(union|select|script|shell)" /var/log/apache2/access.log | \
head -1 | awk '{print "Начало:", $4}'
grep -E "(union|select|script|shell)" /var/log/apache2/access.log | \
tail -1 | awk '{print "Конец:", $4}'
echo ""
echo "3. Наиболее атакуемые URL:"
grep -E "(union|select|script|shell)" /var/log/apache2/access.log | \
awk '{print $7}' | sort | uniq -c | sort -nr | head -5
} > /tmp/security_report_$(date +%Y%m%d).txt
# 6. Проверка модифицированных файлов
find /var/www -type f -name "*.php" -mtime -7 -exec ls -la {} \; | \
grep -v "cache\|temp\|log"
# 7. Поиск подозрительных процессов от www-data
ps aux | grep www-data | grep -E "(sh|bash|nc|netcat|perl|python)"
Bash:
# Поиск событий в временном диапазоне
# Корректный поиск в 5-минутном окне вокруг времени атаки
for i in {-5..5}; do
grep "$(date -d "2024-01-15 14:30 $i minutes" '+%b %d %H:%M')" /var/log/syslog
done | grep -E "started|executed|spawned|created|launched"
# ОПТИМАЛЬНЫЙ вариант с использованием journalctl
journalctl --since "2024-01-15 14:25" --until "2024-01-15 14:35" | \
grep -E "(started|executed|spawned|fork|exec|systemd\[1\]:|kernel:.*process)"
# Полная корреляция с системными логами:
# ШАГ 2.1: АНАЛИЗ ПРОЦЕССОВ
echo "=== АНАЛИЗ ПОДОЗРИТЕЛЬНЫХ ПРОЦЕССОВ ==="
# Поиск новых процессов от www-data
journalctl --since "2024-01-15 14:25" --until "2024-01-15 14:35" | \
grep -E "(www-data|apache2|httpd)" | \
grep -E "(execve|fork|clone|started|sh|bash|python|perl|php|nc|netcat)"
# Анализ через auditd (если включен)
ausearch -ts 01/15/2024 14:25:00 -te 01/15/2024 14:35:00 -m execve | \
grep -E "(www-data|apache)" | aureport -x --summary
# Традиционный grep по всем логам
for log in syslog auth.log kern.log; do
echo "=== Анализ /var/log/$log ==="
grep "Jan 15 14:3[0-5]" /var/log/$log | \
grep -E "(COMMAND|executed|started|process|fork|exec|sudo|su:|ssh|login)"
done
# ШАГ 2.2: АНАЛИЗ СЕТЕВОЙ АКТИВНОСТИ
echo "=== СЕТЕВАЯ АКТИВНОСТЬ В МОМЕНТ АТАКИ ==="
# Новые сетевые соединения
journalctl --since "2024-01-15 14:25" --until "2024-01-15 14:35" | \
grep -E "(ACCEPT|ESTABLISHED|listening|connection from|Connected)"
# Анализ UFW/iptables логов
grep "Jan 15 14:3" /var/log/ufw.log 2>/dev/null | \
grep -E "(BLOCK|ALLOW|DPT=80|DPT=443|DPT=22)"
# ШАГ 2.3: АНАЛИЗ АУТЕНТИФИКАЦИИ
echo "=== СОБЫТИЯ АУТЕНТИФИКАЦИИ ==="
# Подозрительные sudo команды
grep "Jan 15 14:3" /var/log/auth.log | \
grep -E "(sudo:.*COMMAND|su\[|authentication failure|Failed password)"
# Новые SSH сессии
grep "Jan 15 14:3" /var/log/auth.log | \
grep -E "(sshd.*Accepted|session opened|publickey|password)"
# ШАГ 2.4: ФАЙЛОВАЯ АКТИВНОСТЬ
echo "=== ИЗМЕНЕНИЯ ФАЙЛОВОЙ СИСТЕМЫ ==="
# Поиск создания новых файлов (если есть auditd)
ausearch -ts 01/15/2024 14:25:00 -te 01/15/2024 14:35:00 -m create | \
grep -E "(\.php|\.sh|\.pl|\.py|\.jsp|\.asp)"
# Анализ изменений в критических директориях
find /var/www -type f -newermt "2024-01-15 14:25" ! -newermt "2024-01-15 14:35" -ls
# ШАГ 2.5: КОРРЕЛЯЦИЯ С DOCKER/CONTAINERS
echo "=== АНАЛИЗ КОНТЕЙНЕРОВ ==="
# Docker события
docker events --since "2024-01-15T14:25:00" --until "2024-01-15T14:35:00" 2>/dev/null
# Или через journalctl
journalctl -u docker --since "2024-01-15 14:25" --until "2024-01-15 14:35"
# ШАГ 2.6: АНАЛИЗ CRON И SCHEDULED TASKS
echo "=== ПРОВЕРКА ЗАПЛАНИРОВАННЫХ ЗАДАЧ ==="
# Cron выполнения
grep "Jan 15 14:3" /var/log/cron.log 2>/dev/null || \
grep "CRON" /var/log/syslog | grep "Jan 15 14:3"
# Проверка модификации crontab
grep "crontab" /var/log/auth.log | grep "Jan 15"
# ШАГ 2.7: КОМПЛЕКСНАЯ ВРЕМЕННАЯ КОРРЕЛЯЦИЯ
echo "=== ПОСТРОЕНИЕ TIMELINE АТАКИ ==="
# Создание единого timeline
{
echo "ВРЕМЯ | ТИП | СОБЫТИЕ"
echo "------|-----|--------"
# Apache события
grep -E "(union|select|shell)" /var/log/apache2/access.log | \
grep "15/Jan/2024:14:3" | \
awk '{print $4 " | WEB | " $7}' | sed 's/\[//'
# Системные события
journalctl --since "2024-01-15 14:25" --until "2024-01-15 14:35" | \
grep -E "(started|executed|sudo)" | \
awk '{print $1 " " $2 " " $3 " | SYS | " $0}' | cut -c1-100
# Auth события
grep "Jan 15 14:3" /var/log/auth.log | \
awk '{print $1 " " $2 " " $3 " | AUTH | " $0}' | cut -c1-100
} | sort | tee /tmp/attack_timeline.txt
# ШАГ 2.8: РАСШИРЕННЫЙ ПОИСК IOC
echo "=== ПОИСК ИНДИКАТОРОВ КОМПРОМЕТАЦИИ ==="
# Подозрительные строки в логах
for pattern in "wget" "curl" "nc -e" "bash -i" "/dev/tcp/" "python -c" "perl -e" "ruby -e" "powershell" "cmd.exe"; do
echo "Поиск: $pattern"
grep -r "$pattern" /var/log/ 2>/dev/null | grep "Jan 15 14:3" | head -3
done
# Reverse shells индикаторы
journalctl --since "2024-01-15 14:25" --until "2024-01-15 14:35" | \
grep -E "(4444|5555|6666|7777|8888|9999|31337|mkfifo|/dev/tcp/|socket|SOCK_STREAM)"
# ШАГ 2.9: ПРОВЕРКА PERSISTENCE
echo "=== МЕХАНИЗМЫ ЗАКРЕПЛЕНИЯ ==="
# Новые systemd сервисы
systemctl list-units --all --type=service | \
xargs -I {} sh -c 'systemctl show {} -p ActiveEnterTimestamp | grep "2024-01-15 14:3" && echo "Подозрительный сервис: {}"'
# Изменения в автозагрузке
ls -la /etc/init.d/ /etc/rc*.d/ /etc/systemd/system/ | \
grep "Jan 15 14:"
# ШАГ 2.10: MEMORY FORENSICS (если доступен дамп)
echo "=== АНАЛИЗ ПАМЯТИ ==="
# Проверка подозрительных процессов в памяти
ps aux | awk '$9 ~ /14:3[0-5]/ {print}'
# Netstat в момент атаки (если есть сохраненные данные)
ss -tunap | grep -E "(ESTAB|LISTEN)" | \
awk '{print $1, $5, $6}' | sort -u
# ИТОГОВЫЙ ОТЧЕТ
echo "=== ГЕНЕРАЦИЯ ОТЧЕТА О КОРРЕЛЯЦИИ ==="
{
echo "КОРРЕЛЯЦИОННЫЙ АНАЛИЗ ИНЦИДЕНТА"
echo "Время атаки: 2024-01-15 14:30"
echo ""
echo "Обнаруженные индикаторы:"
echo "- Web-атаки: $(grep "15/Jan/2024:14:3" /var/log/apache2/access.log | wc -l)"
echo "- Системные события: $(journalctl --since '2024-01-15 14:25' --until '2024-01-15 14:35' | wc -l)"
echo "- Auth события: $(grep 'Jan 15 14:3' /var/log/auth.log | wc -l)"
echo ""
echo "Подозрительные процессы:"
ps aux | awk '$9 ~ /14:3[0-5]/ {print $11}' | sort -u
} > /tmp/correlation_report_$(date +%Y%m%d).txt
В Wireshark применяем фильтр для исследования HTTP POST-запросов в момент атаки:
Код:
# Правильный формат времени для Wireshark
http.request.method == "POST" and frame.time >= "Jan 15, 2024 14:25:00"
# Альтернативный вариант с epoch time (более надежный)
http.request.method == "POST" and frame.time_epoch >= 1705324500
# Полный анализ сетевого трафика для расследования:
# ШАГ 3.1: АНАЛИЗ POST ЗАПРОСОВ
# Все POST запросы с подозрительным контентом
http.request.method == "POST" and frame.time >= "Jan 15, 2024 14:25:00" and
(http.request.uri contains "upload" or
http.request.uri contains "shell" or
http.request.uri contains "cmd" or
http.request.uri contains "admin")
# POST с большим payload (возможная загрузка вебшелла)
http.request.method == "POST" and http.content_length > 10000 and
frame.time >= "Jan 15, 2024 14:25:00"
# ШАГ 3.2: ОБНАРУЖЕНИЕ SQL ИНЪЕКЦИЙ
# SQL инъекции в HTTP трафике
http and frame.time >= "Jan 15, 2024 14:25:00" and
(http.request.uri matches ".*(\%27|\'|\%22|\"|union.*select|select.*from).*" or
urlencoded-form.value matches ".*(union.*select|exec|execute|drop|insert).*")
# ШАГ 3.3: АНАЛИЗ WEBSHELL КОММУНИКАЦИИ
# Поиск характерных вебшелл паттернов
http and frame.time >= "Jan 15, 2024 14:25:00" and
(http.request.uri contains "c99" or
http.request.uri contains "r57" or
http.request.uri contains "wso" or
http.request.uri contains ".php.suspected" or
http.cookie contains "b374k")
# Base64 encoded команды (типично для вебшеллов)
http.request.method == "POST" and
frame.time >= "Jan 15, 2024 14:25:00" and
http matches "[A-Za-z0-9+/]{50,}={0,2}"
# ШАГ 3.4: COMMAND & CONTROL АНАЛИЗ
# Поиск регулярных beacon соединений
http and frame.time >= "Jan 15, 2024 14:25:00" and
tcp.stream eq 0 and
(http.request.uri contains "news.php" or
http.request.uri contains "update.php" or
http.request.uri contains "check.php")
# Подозрительные User-Agent от C2
http and frame.time >= "Jan 15, 2024 14:25:00" and
(http.user_agent contains "Mozilla/4.0 (compatible; MSIE 6.0;" or
http.user_agent contains "Mozilla/5.0 (compatible; MSIE 9.0;" or
http.user_agent == "Mozilla/5.0")
# ШАГ 3.5: DATA EXFILTRATION
# Большие POST запросы (утечка данных)
http.request.method == "POST" and
frame.time >= "Jan 15, 2024 14:25:00" and
http.content_length > 1048576 and
not (ip.dst == 10.0.0.0/8 or ip.dst == 172.16.0.0/12 or ip.dst == 192.168.0.0/16)
# Подозрительные файлы в multipart
http.request.method == "POST" and
frame.time >= "Jan 15, 2024 14:25:00" and
(http.file_data contains "<?php" or
http.file_data contains "eval(" or
http.file_data contains "base64_decode")
# ШАГ 3.6: РОССИЙСКАЯ СПЕЦИФИКА
# Атаки на российские платежные системы
http and frame.time >= "Jan 15, 2024 14:25:00" and
(http.request.uri contains "yandex" or
http.request.uri contains "sberbank" or
http.request.uri contains "tinkoff" or
http.request.uri contains "qiwi" or
http.request.uri contains "webmoney")
# Атаки на 1С-Битрикс
http and frame.time >= "Jan 15, 2024 14:25:00" and
(http.request.uri contains "/bitrix/admin" or
http.request.uri contains "/bitrix/modules" or
http.cookie contains "BITRIX_SM")
# ШАГ 3.7: СЛОЖНЫЕ КОРРЕЛЯЦИИ
# Корреляция успешных эксплойтов (200 OK после подозрительного POST)
http.request.method == "POST" and
frame.time >= "Jan 15, 2024 14:25:00" and
http.response.code == 200 and
(http.request.uri contains "../" or
http.request.uri contains "system(" or
http.request.uri contains "exec(")
# ШАГ 3.8: СЕТЕВЫЕ АНОМАЛИИ
# TCP на нестандартных портах
tcp.port > 10000 and tcp.port != 65535 and
frame.time >= "Jan 15, 2024 14:25:00" and
tcp.flags.syn == 1 and tcp.flags.ack == 0
# DNS туннелинг
dns and frame.time >= "Jan 15, 2024 14:25:00" and
(dns.qry.name.len > 50 or
dns.txt.length > 100 or
dns.qry.type == 16)
# ШАГ 3.9: ИЗВЛЕЧЕНИЕ IOC
# Экспорт подозрительных IP для блокировки
http and frame.time >= "Jan 15, 2024 14:25:00" and
(http.request.uri contains "shell" or
http.request.uri contains "union select")
# После применения: File -> Export -> Resolved Addresses
# ШАГ 3.10: СТАТИСТИЧЕСКИЙ АНАЛИЗ
# Топ атакующих IP за период
ip.src and frame.time >= "Jan 15, 2024 14:25:00" and
frame.time <= "Jan 15, 2024 14:35:00"
# Statistics -> IPv4 Statistics -> Source and Destination Addresses
# Анализ HTTP объектов
http and frame.time >= "Jan 15, 2024 14:25:00"
# File -> Export Objects -> HTTP
# ДОПОЛНИТЕЛЬНЫЕ ПРОВЕРКИ ДЛЯ ФОРЕНЗИКИ:
# 1. Следы Metasploit
http and frame.time >= "Jan 15, 2024 14:25:00" and
(http.request.uri matches "^/[a-zA-Z0-9]{4,10}$" and
http.user_agent contains "Mozilla/4.0")
# 2. Следы SQLMap
http and frame.time >= "Jan 15, 2024 14:25:00" and
(http.user_agent contains "sqlmap" or
http.request.uri matches ".*id=.*(\%27|\').*")
# 3. Mimikatz over HTTP
http and frame.time >= "Jan 15, 2024 14:25:00" and
(frame contains "mimikatz" or
frame contains "sekurlsa" or
frame contains "gentilkiwi")
# 4. PowerShell Empire
http and frame.time >= "Jan 15, 2024 14:25:00" and
(http.cookie contains "session=" and
http.request.uri matches "/(news|admin/get)\.php")
# 5. Cobalt Strike
http and frame.time >= "Jan 15, 2024 14:25:00" and
(http.request.uri matches "/(ab2g|ab2h|updates|visit\.js|fwlink)" or
http.request.uri matches "^/[a-z]{3,10}$" and http.request.method == "POST")
# ЭКСПОРТ РЕЗУЛЬТАТОВ:
# После применения любого фильтра:
# 1. File -> Export Specified Packets -> CSV для анализа в Excel
# 2. File -> Export Objects -> HTTP для извлечения файлов
# 3. Statistics -> Conversations для анализа связей
# 4. Statistics -> Protocol Hierarchy для общей картины
- Обнаружена SQL-инъекция в параметре поиска товаров. Классика.
- Злоумышленник получил доступ к базе данных клиентов.
- Установлен веб-шелл для удаленного управления сервером.
Автоматизация форензики: скрипты для SOC
Хватит работать руками. Давай научим машину делать грязную работу за тебя.PowerShell-скрипты для анализа Windows Event Log
Анализ подозрительных входов в систему
Код:
# Анализ подозрительных входов с надежным парсингом
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4624; StartTime=(Get-Date).AddDays(-1)} |
ForEach-Object {
$xml = [xml]$_.ToXml()
$eventData = @{}
$xml.Event.EventData.Data | ForEach-Object {
$eventData[$_.Name] = $_.'#text'
}
# Фильтруем сетевые логины (тип 3) с внешних IP
if ($eventData.LogonType -eq 3 -and
$eventData.IpAddress -notmatch '^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\.|::1|fe80:)') {
[PSCustomObject]@{
TimeCreated = $_.TimeCreated
User = "$($eventData.TargetDomainName)\$($eventData.TargetUserName)"
SourceIP = $eventData.IpAddress
LogonType = $eventData.LogonType
WorkstationName = $eventData.WorkstationName
ProcessName = $eventData.ProcessName
}
}
} | Sort-Object TimeCreated -Descending
# КОМПЛЕКСНЫЙ НАБОР СКРИПТОВ ДЛЯ SOC:
# 1. ОБНАРУЖЕНИЕ БРУТФОРСА
function Find-BruteForceAttempts {
param(
[int]$Hours = 24,
[int]$Threshold = 10
)
$failedLogins = Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=4625
StartTime=(Get-Date).AddHours(-$Hours)
} -ErrorAction SilentlyContinue |
ForEach-Object {
$xml = [xml]$_.ToXml()
$data = @{}
$xml.Event.EventData.Data | ForEach-Object {
$data[$_.Name] = $_.'#text'
}
[PSCustomObject]@{
Time = $_.TimeCreated
User = $data.TargetUserName
Domain = $data.TargetDomainName
SourceIP = $data.IpAddress
FailureReason = $data.FailureReason
SubStatus = $data.SubStatus
}
}
# Группировка и анализ
$failedLogins | Group-Object SourceIP | Where-Object {
$_.Count -gt $Threshold
} | ForEach-Object {
[PSCustomObject]@{
SourceIP = $_.Name
AttemptsCount = $_.Count
TargetUsers = ($_.Group | Select-Object -ExpandProperty User -Unique) -join ', '
FirstAttempt = ($_.Group | Sort-Object Time | Select-Object -First 1).Time
LastAttempt = ($_.Group | Sort-Object Time -Descending | Select-Object -First 1).Time
AttackType = if(($_.Group | Select-Object -ExpandProperty User -Unique).Count -gt 5) {
"Password Spray"
} else {
"Targeted Brute Force"
}
}
} | Sort-Object AttemptsCount -Descending
}
# 2. ОБНАРУЖЕНИЕ PRIVILEGE ESCALATION
function Find-PrivilegeEscalation {
param(
[int]$Hours = 24
)
# Поиск изменений привилегий
$events = @(4672, 4673, 4674) # Special privileges, Sensitive privilege use
Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=$events
StartTime=(Get-Date).AddHours(-$Hours)
} -ErrorAction SilentlyContinue |
ForEach-Object {
$xml = [xml]$_.ToXml()
$data = @{}
$xml.Event.EventData.Data | ForEach-Object {
$data[$_.Name] = $_.'#text'
}
# Проверяем на подозрительные привилегии
if ($data.PrivilegeList -match 'SeDebugPrivilege|SeLoadDriverPrivilege|SeRestorePrivilege|SeTakeOwnershipPrivilege') {
[PSCustomObject]@{
Time = $_.TimeCreated
EventID = $_.Id
User = "$($data.SubjectDomainName)\$($data.SubjectUserName)"
Privileges = $data.PrivilegeList
ProcessName = $data.ProcessName
Risk = "HIGH"
}
}
} | Sort-Object Time -Descending
}
# 3. ОБНАРУЖЕНИЕ LATERAL MOVEMENT
function Find-LateralMovement {
param(
[int]$Hours = 24
)
# События RDP, SMB, WMI, PSRemoting
$events = @(4624, 4648, 5140, 5145)
Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=$events
StartTime=(Get-Date).AddHours(-$Hours)
} -ErrorAction SilentlyContinue |
ForEach-Object {
$xml = [xml]$_.ToXml()
$data = @{}
$xml.Event.EventData.Data | ForEach-Object {
$data[$_.Name] = $_.'#text'
}
$suspicious = $false
$movementType = ""
switch ($_.Id) {
4624 {
if ($data.LogonType -eq 10) {
$suspicious = $true
$movementType = "RDP"
} elseif ($data.LogonType -eq 3 -and $data.ProcessName -match 'powershell|cmd|wmic') {
$suspicious = $true
$movementType = "Network Logon"
}
}
4648 {
$suspicious = $true
$movementType = "Explicit Credentials"
}
5140 {
if ($data.ShareName -match '\$|ADMIN|IPC') {
$suspicious = $true
$movementType = "Admin Share Access"
}
}
}
if ($suspicious) {
[PSCustomObject]@{
Time = $_.TimeCreated
Type = $movementType
SourceIP = $data.IpAddress
TargetHost = $env:COMPUTERNAME
User = "$($data.TargetDomainName)\$($data.TargetUserName)"
Process = $data.ProcessName
ShareName = $data.ShareName
}
}
} | Where-Object {$_} | Sort-Object Time -Descending
}
# 4. ОБНАРУЖЕНИЕ PERSISTENCE
function Find-PersistenceMechanisms {
param(
[int]$Hours = 24
)
$results = @()
# Проверка новых служб (Event ID 7045)
$results += Get-WinEvent -FilterHashtable @{
LogName='System'
ID=7045
StartTime=(Get-Date).AddHours(-$Hours)
} -ErrorAction SilentlyContinue |
ForEach-Object {
[PSCustomObject]@{
Time = $_.TimeCreated
Type = "New Service"
Name = $_.Message -replace '.*service name: ([^\s]+).*', '$1'
Details = $_.Message
Risk = if($_.Message -match 'powershell|cmd|wscript|cscript|rundll32') {"HIGH"} else {"MEDIUM"}
}
}
# Проверка запланированных задач (Event ID 4698)
$results += Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=4698
StartTime=(Get-Date).AddHours(-$Hours)
} -ErrorAction SilentlyContinue |
ForEach-Object {
$xml = [xml]$_.ToXml()
[PSCustomObject]@{
Time = $_.TimeCreated
Type = "Scheduled Task"
Name = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'TaskName'}).'#text'
Details = $_.Message
Risk = "MEDIUM"
}
}
return $results | Sort-Object Time -Descending
}
# 5. ОБНАРУЖЕНИЕ POWERSHELL АТАК
function Find-PowerShellAttacks {
param(
[int]$Hours = 24
)
# PowerShell operational log
Get-WinEvent -FilterHashtable @{
LogName='Microsoft-Windows-PowerShell/Operational'
ID=@(4103, 4104)
StartTime=(Get-Date).AddHours(-$Hours)
} -ErrorAction SilentlyContinue |
Where-Object {
$_.Message -match 'IEX|Invoke-Expression|Invoke-Command|DownloadString|DownloadFile|EncodedCommand|Base64|hidden|bypass|unrestricted|Invoke-Mimikatz|Invoke-ReflectivePEInjection|Invoke-Shellcode|Invoke-WmiMethod|Get-GPPPassword|Get-Keystrokes|Get-TimedScreenshot|Get-VaultCredential|Invoke-CredentialInjection|Invoke-TokenManipulation|Invoke-Empire|Invoke-PowerDump|Invoke-Kerberoast'
} |
ForEach-Object {
[PSCustomObject]@{
Time = $_.TimeCreated
User = $_.UserId
ScriptBlock = ($_.Message -split "`n")[0..5] -join "`n"
Risk = if($_.Message -match 'Mimikatz|Empire|Kerberoast') {"CRITICAL"} else {"HIGH"}
}
} | Sort-Object Time -Descending
}
# 6. MASTER ФУНКЦИЯ ДЛЯ КОМПЛЕКСНОГО АНАЛИЗА
function Invoke-SecurityAudit {
param(
[int]$Hours = 24,
[string]$OutputPath = "$env:TEMP\SecurityAudit_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
)
Write-Host "[*] Starting Security Audit for last $Hours hours..." -ForegroundColor Cyan
$report = @"
<!DOCTYPE html>
<html>
<head>
<title>Security Audit Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
h1 { color: #d32f2f; }
h2 { color: #1976d2; margin-top: 30px; }
table { border-collapse: collapse; width: 100%; margin: 15px 0; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.critical { background-color: #ff5252; color: white; }
.high { background-color: #ff9800; }
.medium { background-color: #ffeb3b; }
.low { background-color: #4caf50; color: white; }
</style>
</head>
<body>
<h1>Security Audit Report - $(Get-Date)</h1>
"@
# Брутфорс
Write-Host "[*] Checking for brute force attacks..." -ForegroundColor Yellow
$bruteForce = Find-BruteForceAttempts -Hours $Hours
if ($bruteForce) {
$report += "<h2>🔨 Brute Force Attempts Detected</h2>"
$report += $bruteForce | ConvertTo-Html -Fragment
}
# Privilege Escalation
Write-Host "[*] Checking for privilege escalation..." -ForegroundColor Yellow
$privEsc = Find-PrivilegeEscalation -Hours $Hours
if ($privEsc) {
$report += "<h2>⚡ Privilege Escalation Detected</h2>"
$report += $privEsc | ConvertTo-Html -Fragment
}
# Lateral Movement
Write-Host "[*] Checking for lateral movement..." -ForegroundColor Yellow
$lateral = Find-LateralMovement -Hours $Hours
if ($lateral) {
$report += "<h2>➡️ Lateral Movement Detected</h2>"
$report += $lateral | ConvertTo-Html -Fragment
}
# Persistence
Write-Host "[*] Checking for persistence mechanisms..." -ForegroundColor Yellow
$persistence = Find-PersistenceMechanisms -Hours $Hours
if ($persistence) {
$report += "<h2>🔒 Persistence Mechanisms Detected</h2>"
$report += $persistence | ConvertTo-Html -Fragment
}
# PowerShell Attacks
Write-Host "[*] Checking for PowerShell attacks..." -ForegroundColor Yellow
$psAttacks = Find-PowerShellAttacks -Hours $Hours
if ($psAttacks) {
$report += "<h2>💻 PowerShell Attacks Detected</h2>"
$report += $psAttacks | ConvertTo-Html -Fragment
}
$report += "</body></html>"
# Сохранение отчета
$report | Out-File -FilePath $OutputPath -Encoding UTF8
Write-Host "[+] Report saved to: $OutputPath" -ForegroundColor Green
# Открытие отчета
Start-Process $OutputPath
}
# ИСПОЛЬЗОВАНИЕ:
# Find-BruteForceAttempts -Hours 48 -Threshold 5
# Find-PrivilegeEscalation -Hours 24
# Find-LateralMovement -Hours 12
# Find-PersistenceMechanisms -Hours 24
# Find-PowerShellAttacks -Hours 24
# Invoke-SecurityAudit -Hours 24 # Полный аудит
Мониторинг создания новых учетных записей
Код:
# Мониторинг создания учетных записей
$Events = Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4720; StartTime=(Get-Date).AddHours(-8)}
foreach ($Event in $Events) {
$User = $Event.Properties[0].Value
$Creator = $Event.Properties[4].Value
Write-Host "Создана учетная запись: $User пользователем: $Creator в $($Event.TimeCreated)"
}
# ВЕРСИЯ с XML парсингом и полной информацией
function Monitor-AccountCreation {
param(
[int]$Hours = 8,
[switch]$ShowDetails,
[switch]$ExportCSV
)
$Events = Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=4720
StartTime=(Get-Date).AddHours(-$Hours)
} -ErrorAction SilentlyContinue
if (-not $Events) {
Write-Host "Новые учетные записи не создавались за последние $Hours часов" -ForegroundColor Green
return
}
$Results = foreach ($Event in $Events) {
$xml = [xml]$Event.ToXml()
$EventData = @{}
$xml.Event.EventData.Data | ForEach-Object {
$EventData[$_.Name] = $_.'#text'
}
# Определяем риск
$RiskLevel = "Low"
$RiskReasons = @()
# Проверка подозрительных признаков
if ($EventData.TargetUserName -match 'admin|root|sa|sys|temp|test|guest') {
$RiskLevel = "High"
$RiskReasons += "Suspicious username pattern"
}
if ($Event.TimeCreated.Hour -lt 6 -or $Event.TimeCreated.Hour -gt 22) {
$RiskLevel = "Medium"
$RiskReasons += "Created outside business hours"
}
if ($EventData.SubjectUserName -notmatch 'admin|administrator') {
$RiskLevel = "High"
$RiskReasons += "Created by non-admin user"
}
[PSCustomObject]@{
TimeCreated = $Event.TimeCreated
NewUser = $EventData.TargetUserName
Domain = $EventData.TargetDomainName
CreatedBy = "$($EventData.SubjectDomainName)\$($EventData.SubjectUserName)"
CreatorSID = $EventData.SubjectUserSid
NewUserSID = $EventData.TargetUserSid
PrivilegeList = $EventData.PrivilegeList
ComputerName = $Event.MachineName
RiskLevel = $RiskLevel
RiskReasons = $RiskReasons -join '; '
}
}
# Вывод результатов
if ($ShowDetails) {
$Results | Format-List
} else {
$Results | Format-Table TimeCreated, NewUser, CreatedBy, RiskLevel -AutoSize
}
# Экспорт в CSV если требуется
if ($ExportCSV) {
$CSVPath = "$env:TEMP\AccountCreation_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$Results | Export-Csv -Path $CSVPath -NoTypeInformation
Write-Host "Экспортировано в: $CSVPath" -ForegroundColor Green
}
# Статистика
Write-Host "`n=== СТАТИСТИКА ===" -ForegroundColor Cyan
Write-Host "Всего создано учетных записей: $($Results.Count)" -ForegroundColor Yellow
$Results | Group-Object CreatedBy | ForEach-Object {
Write-Host " $($_.Name): $($_.Count) учетных записей"
}
# Предупреждения о рисках
$HighRisk = $Results | Where-Object {$_.RiskLevel -eq 'High'}
if ($HighRisk) {
Write-Host "`n⚠️ ВНИМАНИЕ: Обнаружены подозрительные учетные записи!" -ForegroundColor Red
$HighRisk | ForEach-Object {
Write-Host " - $($_.NewUser): $($_.RiskReasons)" -ForegroundColor Red
}
}
return $Results
}
# РАСШИРЕННЫЙ МОНИТОРИНГ ИЗМЕНЕНИЙ УЧЕТНЫХ ЗАПИСЕЙ
# 1. Мониторинг всех операций с учетными записями
function Monitor-AccountOperations {
param(
[int]$Hours = 24
)
$AccountEvents = @{
4720 = "Account Created"
4722 = "Account Enabled"
4723 = "Password Change Attempted"
4724 = "Password Reset Attempted"
4725 = "Account Disabled"
4726 = "Account Deleted"
4738 = "Account Modified"
4740 = "Account Locked Out"
4767 = "Account Unlocked"
4781 = "Account Name Changed"
}
$AllEvents = @()
foreach ($EventID in $AccountEvents.Keys) {
$Events = Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=$EventID
StartTime=(Get-Date).AddHours(-$Hours)
} -ErrorAction SilentlyContinue
foreach ($Event in $Events) {
$xml = [xml]$Event.ToXml()
$EventData = @{}
$xml.Event.EventData.Data | ForEach-Object {
$EventData[$_.Name] = $_.'#text'
}
$AllEvents += [PSCustomObject]@{
Time = $Event.TimeCreated
EventType = $AccountEvents[$EventID]
TargetUser = $EventData.TargetUserName
TargetDomain = $EventData.TargetDomainName
ExecutedBy = "$($EventData.SubjectDomainName)\$($EventData.SubjectUserName)"
Computer = $Event.MachineName
EventID = $EventID
}
}
}
return $AllEvents | Sort-Object Time -Descending
}
# 2. Мониторинг добавления в привилегированные группы
function Monitor-GroupMembership {
param(
[int]$Hours = 24,
[string[]]$CriticalGroups = @(
'Domain Admins',
'Enterprise Admins',
'Schema Admins',
'Administrators',
'Backup Operators',
'Account Operators',
'Server Operators',
'Print Operators'
)
)
# Event ID 4728, 4732, 4756 - добавление в группы
$Events = Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=@(4728, 4732, 4756)
StartTime=(Get-Date).AddHours(-$Hours)
} -ErrorAction SilentlyContinue
$Results = foreach ($Event in $Events) {
$xml = [xml]$Event.ToXml()
$EventData = @{}
$xml.Event.EventData.Data | ForEach-Object {
$EventData[$_.Name] = $_.'#text'
}
$GroupName = $EventData.TargetUserName
$IsCritical = $CriticalGroups -contains $GroupName
if ($IsCritical) {
[PSCustomObject]@{
Time = $Event.TimeCreated
Action = "Member Added"
Group = $GroupName
Member = $EventData.MemberSid
AddedBy = "$($EventData.SubjectDomainName)\$($EventData.SubjectUserName)"
Critical = $true
Alert = "⚠️ CRITICAL GROUP MODIFICATION"
}
}
}
if ($Results) {
Write-Host "`n🚨 КРИТИЧЕСКИЕ ИЗМЕНЕНИЯ В ГРУППАХ ОБНАРУЖЕНЫ!" -ForegroundColor Red
$Results | Format-Table -AutoSize
}
return $Results
}
# 3. Детектирование подозрительных паттернов создания учетных записей
function Detect-SuspiciousAccountPatterns {
param(
[int]$Days = 7
)
$Events = Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=4720
StartTime=(Get-Date).AddDays(-$Days)
} -ErrorAction SilentlyContinue
$Accounts = foreach ($Event in $Events) {
$xml = [xml]$Event.ToXml()
$EventData = @{}
$xml.Event.EventData.Data | ForEach-Object {
$EventData[$_.Name] = $_.'#text'
}
[PSCustomObject]@{
Time = $Event.TimeCreated
User = $EventData.TargetUserName
Creator = $EventData.SubjectUserName
}
}
# Анализ паттернов
Write-Host "`n=== АНАЛИЗ ПАТТЕРНОВ ===" -ForegroundColor Cyan
# Массовое создание
$GroupedByTime = $Accounts | Group-Object {$_.Time.ToString("yyyy-MM-dd HH")}
$MassCreation = $GroupedByTime | Where-Object {$_.Count -gt 5}
if ($MassCreation) {
Write-Host "⚠️ Массовое создание учетных записей:" -ForegroundColor Red
$MassCreation | ForEach-Object {
Write-Host " $($_.Name): $($_.Count) учетных записей"
}
}
# Подозрительные имена
$SuspiciousNames = $Accounts | Where-Object {
$_.User -match '^(user|test|temp|admin)\d+$|^[a-z]{1}[0-9]{4,}$'
}
if ($SuspiciousNames) {
Write-Host "⚠️ Подозрительные имена учетных записей:" -ForegroundColor Red
$SuspiciousNames | ForEach-Object {
Write-Host " $($_.User) - создан $($_.Time)"
}
}
# Создание в нерабочее время
$AfterHours = $Accounts | Where-Object {
$_.Time.Hour -lt 7 -or $_.Time.Hour -gt 20 -or
$_.Time.DayOfWeek -in @('Saturday', 'Sunday')
}
if ($AfterHours) {
Write-Host "⚠️ Учетные записи созданы в нерабочее время:" -ForegroundColor Yellow
$AfterHours | ForEach-Object {
Write-Host " $($_.User) - $($_.Time)"
}
}
}
# 4. REAL-TIME МОНИТОРИНГ
function Start-AccountMonitoring {
param(
[int]$CheckIntervalMinutes = 5
)
Write-Host "Запуск мониторинга учетных записей..." -ForegroundColor Green
Write-Host "Проверка каждые $CheckIntervalMinutes минут. Нажмите Ctrl+C для остановки." -ForegroundColor Cyan
$LastCheck = Get-Date
while ($true) {
Start-Sleep -Seconds ($CheckIntervalMinutes * 60)
$NewAccounts = Monitor-AccountCreation -Hours ([Math]::Ceiling($CheckIntervalMinutes / 60))
if ($NewAccounts) {
# Отправка алерта (можно интегрировать с email/Teams/Slack)
Write-Host "`n🔔 ALERT: Обнаружены новые учетные записи!" -ForegroundColor Red
# Логирование
$LogPath = "$env:TEMP\AccountMonitoring.log"
$NewAccounts | ConvertTo-Json | Add-Content -Path $LogPath
}
$LastCheck = Get-Date
Write-Host "Последняя проверка: $LastCheck" -ForegroundColor Gray
}
}
# ИСПОЛЬЗОВАНИЕ:
# Monitor-AccountCreation -Hours 24 -ShowDetails
# Monitor-AccountOperations -Hours 48
# Monitor-GroupMembership -Hours 24
# Detect-SuspiciousAccountPatterns -Days 7
# Start-AccountMonitoring -CheckIntervalMinutes 10
Bash-скрипты для Linux форензики
Автоматический анализ auth.log
Bash:
#!/bin/bash
# Комплексный скрипт анализа Linux Security
# Цветной вывод
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Конфигурация
REPORT_DIR="/tmp/security_reports"
REPORT_FILE="$REPORT_DIR/security_report_$(date +%Y%m%d_%H%M%S).txt"
HTML_REPORT="$REPORT_DIR/security_report_$(date +%Y%m%d_%H%M%S).html"
# Создание директории для отчетов
mkdir -p "$REPORT_DIR"
# Функция проверки прав
check_permissions() {
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}[!] Скрипт требует root привилегий${NC}"
exit 1
fi
}
# Определение системы логирования
detect_log_system() {
if command -v journalctl &> /dev/null && systemctl is-active systemd-journald &> /dev/null; then
echo "systemd"
elif [ -f "/var/log/auth.log" ]; then
echo "syslog"
elif [ -f "/var/log/secure" ]; then
echo "rhel"
else
echo "unknown"
fi
}
# Функция получения логов
get_auth_logs() {
local log_system=$(detect_log_system)
case $log_system in
"systemd")
journalctl -u ssh -u sshd --since "24 hours ago" --no-pager
;;
"syslog")
zcat -f /var/log/auth.log* 2>/dev/null | grep -E "$(date +%b\ %e)|$(date -d yesterday +%b\ %e)"
;;
"rhel")
zcat -f /var/log/secure* 2>/dev/null | grep -E "$(date +%b\ %e)|$(date -d yesterday +%b\ %e)"
;;
*)
echo -e "${RED}[!] Не удалось определить систему логирования${NC}"
exit 1
;;
esac
}
# ГЛАВНАЯ ФУНКЦИЯ АНАЛИЗА
analyze_security() {
echo -e "${BLUE}[*] Запуск комплексного анализа безопасности...${NC}"
# Начало HTML отчета
cat > "$HTML_REPORT" << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Linux Security Analysis Report</title>
<style>
body { font-family: 'Courier New', monospace; margin: 20px; background: #1e1e1e; color: #d4d4d4; }
h1 { color: #ff6b6b; border-bottom: 2px solid #ff6b6b; }
h2 { color: #4ecdc4; margin-top: 30px; }
.critical { background: #ff6b6b; color: white; padding: 10px; border-radius: 5px; }
.warning { background: #ffd93d; color: black; padding: 10px; border-radius: 5px; }
.info { background: #6bcf7f; color: black; padding: 10px; border-radius: 5px; }
pre { background: #2d2d2d; padding: 10px; border-radius: 5px; overflow-x: auto; }
table { width: 100%; border-collapse: collapse; margin: 20px 0; }
th { background: #4ecdc4; color: black; padding: 10px; }
td { border: 1px solid #555; padding: 8px; }
tr:nth-child(even) { background: #2d2d2d; }
</style>
</head>
<body>
<h1>🔒 Linux Security Analysis Report</h1>
<p>Generated: $(date)</p>
<p>Hostname: $(hostname)</p>
EOF
# 1. АНАЛИЗ БРУТФОРСА
echo -e "${YELLOW}[1/10] Анализ попыток брутфорса...${NC}"
{
echo "=== АНАЛИЗ БРУТФОРСА ==="
echo "<h2>1. Brute Force Analysis</h2><pre>" >> "$HTML_REPORT"
local auth_logs=$(get_auth_logs)
# Top атакующие IP
echo "Top 10 атакующих IP-адресов:"
echo "$auth_logs" | grep -E "Failed password|authentication failure" | \
grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" | \
sort | uniq -c | sort -rn | head -10 | \
while read count ip; do
# Геолокация IP
country=$(whois "$ip" 2>/dev/null | grep -i country | head -1 | cut -d: -f2 | xargs)
printf " %-20s %6d попыток [%s]\n" "$ip" "$count" "${country:-Unknown}"
done
# Временной анализ атак
echo -e "\nВременное распределение атак (по часам):"
echo "$auth_logs" | grep "Failed password" | \
awk '{print $3}' | cut -d: -f1 | sort | uniq -c | sort -k2
echo "</pre>" >> "$HTML_REPORT"
} | tee -a "$REPORT_FILE"
# 2. АНАЛИЗ УСПЕШНЫХ ВХОДОВ
echo -e "${YELLOW}[2/10] Анализ успешных аутентификаций...${NC}"
{
echo -e "\n=== УСПЕШНЫЕ ВХОДЫ ==="
echo "<h2>2. Successful Logins</h2><pre>" >> "$HTML_REPORT"
# Успешные входы с внешних IP
echo "Успешные входы с внешних IP:"
get_auth_logs | grep "Accepted" | \
grep -vE "192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.|127\." | \
tail -20
# Входы с использованием ключей
echo -e "\nВходы по SSH ключам:"
get_auth_logs | grep "Accepted publickey" | tail -10
echo "</pre>" >> "$HTML_REPORT"
} | tee -a "$REPORT_FILE"
# 3. АНАЛИЗ SUDO КОМАНД
echo -e "${YELLOW}[3/10] Анализ sudo активности...${NC}"
{
echo -e "\n=== SUDO АКТИВНОСТЬ ==="
echo "<h2>3. Sudo Activity</h2><pre>" >> "$HTML_REPORT"
# Подозрительные sudo команды
echo "Подозрительные sudo команды:"
get_auth_logs | grep "sudo.*COMMAND" | \
grep -E "(chmod.*777|rm.*-rf|passwd|shadow|sudoers|nc |netcat |/bin/sh|/bin/bash)" | \
tail -20
# Неудачные sudo попытки
echo -e "\nНеудачные sudo попытки:"
get_auth_logs | grep "sudo.*authentication failure" | tail -10
echo "</pre>" >> "$HTML_REPORT"
} | tee -a "$REPORT_FILE"
# 4. АНАЛИЗ СОЗДАНИЯ ПОЛЬЗОВАТЕЛЕЙ
echo -e "${YELLOW}[4/10] Проверка новых пользователей...${NC}"
{
echo -e "\n=== НОВЫЕ ПОЛЬЗОВАТЕЛИ ==="
echo "<h2>4. User Account Changes</h2><pre>" >> "$HTML_REPORT"
# Недавно созданные пользователи
echo "Пользователи созданные за последние 7 дней:"
find /home -maxdepth 1 -type d -mtime -7 2>/dev/null | \
while read dir; do
user=$(basename "$dir")
[ "$user" != "home" ] && echo " - $user ($(stat -c %y "$dir" | cut -d' ' -f1))"
done
# Пользователи с UID 0
echo -e "\nПользователи с UID=0 (root привилегии):"
awk -F: '$3==0 {print " ВНИМАНИЕ: " $1}' /etc/passwd
# Пользователи без паролей
echo -e "\nПользователи без паролей:"
awk -F: '($2=="!" || $2=="*" || $2=="") {print " - " $1}' /etc/shadow 2>/dev/null
echo "</pre>" >> "$HTML_REPORT"
} | tee -a "$REPORT_FILE"
# 5. АНАЛИЗ SSH КОНФИГУРАЦИИ
echo -e "${YELLOW}[5/10] Проверка SSH конфигурации...${NC}"
{
echo -e "\n=== SSH КОНФИГУРАЦИЯ ==="
echo "<h2>5. SSH Configuration Security</h2><pre>" >> "$HTML_REPORT"
# Проверка небезопасных настроек
echo "Проверка безопасности SSH:"
# Root login
root_login=$(grep "^PermitRootLogin" /etc/ssh/sshd_config 2>/dev/null | awk '{print $2}')
if [[ "$root_login" == "yes" ]]; then
echo -e " ${RED}[КРИТИЧНО]${NC} Root login разрешен!"
else
echo -e " ${GREEN}[OK]${NC} Root login запрещен"
fi
# Password authentication
pass_auth=$(grep "^PasswordAuthentication" /etc/ssh/sshd_config 2>/dev/null | awk '{print $2}')
if [[ "$pass_auth" == "yes" ]]; then
echo -e " ${YELLOW}[ВНИМАНИЕ]${NC} Парольная аутентификация включена"
fi
# Authorized keys проверка
echo -e "\nПодозрительные SSH ключи:"
find /home -name "authorized_keys" -type f 2>/dev/null | \
while read keyfile; do
suspicious=$(grep -E "command=|nc |netcat |bash|sh " "$keyfile" 2>/dev/null)
if [ ! -z "$suspicious" ]; then
echo " ВНИМАНИЕ: $keyfile содержит подозрительные команды"
fi
done
echo "</pre>" >> "$HTML_REPORT"
} | tee -a "$REPORT_FILE"
# 6. АНАЛИЗ CRON ЗАДАЧ
echo -e "${YELLOW}[6/10] Проверка cron задач...${NC}"
{
echo -e "\n=== CRON ЗАДАЧИ ==="
echo "<h2>6. Cron Jobs Analysis</h2><pre>" >> "$HTML_REPORT"
# Системные cron
echo "Подозрительные системные cron задачи:"
for crondir in /etc/cron.* /var/spool/cron; do
[ -d "$crondir" ] && find "$crondir" -type f 2>/dev/null | \
while read cronfile; do
suspicious=$(grep -E "wget|curl|nc |netcat |bash.*-c|sh.*-c|/dev/tcp" "$cronfile" 2>/dev/null)
if [ ! -z "$suspicious" ]; then
echo " ФАЙЛ: $cronfile"
echo " СОДЕРЖИМОЕ: $suspicious"
fi
done
done
# Пользовательские cron
echo -e "\nПользовательские crontab:"
for user in $(cut -f1 -d: /etc/passwd); do
usercron=$(crontab -l -u "$user" 2>/dev/null)
if [ ! -z "$usercron" ]; then
echo " Пользователь: $user"
echo "$usercron" | head -5
fi
done
echo "</pre>" >> "$HTML_REPORT"
} | tee -a "$REPORT_FILE"
# 7. АНАЛИЗ СЕТЕВЫХ СОЕДИНЕНИЙ
echo -e "${YELLOW}[7/10] Анализ сетевых соединений...${NC}"
{
echo -e "\n=== СЕТЕВЫЕ СОЕДИНЕНИЯ ==="
echo "<h2>7. Network Connections</h2><pre>" >> "$HTML_REPORT"
# Подозрительные порты
echo "Прослушиваемые порты:"
ss -tuln | grep LISTEN | \
while read line; do
port=$(echo "$line" | grep -oE ":[0-9]+" | tail -1 | cut -d: -f2)
# Проверка на известные backdoor порты
case $port in
4444|5555|6666|7777|8888|9999|31337)
echo -e " ${RED}[BACKDOOR?]${NC} $line"
;;
*)
echo " $line"
;;
esac
done
# Активные соединения
echo -e "\nАктивные внешние соединения:"
ss -tun | grep ESTAB | grep -vE "127\.0\.0\.1|::1" | head -20
echo "</pre>" >> "$HTML_REPORT"
} | tee -a "$REPORT_FILE"
# 8. ПРОВЕРКА ПРОЦЕССОВ
echo -e "${YELLOW}[8/10] Анализ подозрительных процессов...${NC}"
{
echo -e "\n=== ПОДОЗРИТЕЛЬНЫЕ ПРОЦЕССЫ ==="
echo "<h2>8. Process Analysis</h2><pre>" >> "$HTML_REPORT"
# Процессы с сетевой активностью
echo "Процессы с сетевыми соединениями:"
lsof -i -P | grep -E "ESTABLISHED|LISTEN" | \
grep -vE "127\.0\.0\.1|::1" | head -20
# Скрытые процессы
echo -e "\nПроверка скрытых процессов:"
ps aux | awk '$11 ~ /^\[/ && $11 !~ /^\[(kernel|systemd|kworker|migration|ksoftirqd|rcu_)/ {print}'
# CPU/Memory интенсивные процессы
echo -e "\nTop CPU потребители:"
ps aux --sort=-%cpu | head -5
echo "</pre>" >> "$HTML_REPORT"
} | tee -a "$REPORT_FILE"
# 9. ПРОВЕРКА ФАЙЛОВОЙ СИСТЕМЫ
echo -e "${YELLOW}[9/10] Проверка изменений в файловой системе...${NC}"
{
echo -e "\n=== ИЗМЕНЕНИЯ ФАЙЛОВОЙ СИСТЕМЫ ==="
echo "<h2>9. File System Changes</h2><pre>" >> "$HTML_REPORT"
# Недавно измененные системные файлы
echo "Системные файлы измененные за последние 24 часа:"
find /etc /usr/bin /usr/sbin /bin /sbin -type f -mtime -1 2>/dev/null | head -20
# SUID/SGID файлы
echo -e "\nНовые SUID/SGID файлы:"
find / -type f \( -perm -4000 -o -perm -2000 \) -mtime -7 2>/dev/null
# Подозрительные файлы в /tmp и /dev/shm
echo -e "\nПодозрительные файлы в временных директориях:"
find /tmp /dev/shm -type f \( -name "*.sh" -o -name "*.pl" -o -name "*.py" \) -mtime -1 2>/dev/null
echo "</pre>" >> "$HTML_REPORT"
} | tee -a "$REPORT_FILE"
# 10. ПРОВЕРКА ЛОГОВ НА ОЧИСТКУ
echo -e "${YELLOW}[10/10] Проверка попыток очистки логов...${NC}"
{
echo -e "\n=== ПОПЫТКИ ОЧИСТКИ СЛЕДОВ ==="
echo "<h2>10. Log Tampering Detection</h2><pre>" >> "$HTML_REPORT"
# Проверка размера логов
echo "Подозрительно маленькие лог-файлы:"
find /var/log -type f -name "*.log" -size -1k 2>/dev/null
# Проверка timestamp логов
echo -e "\nЛоги не обновлявшиеся более 24 часов:"
find /var/log -type f -name "*.log" -mtime +1 2>/dev/null | head -10
# История команд
echo -e "\nПопытки очистки истории команд:"
get_auth_logs | grep -E "history -c|rm.*history|> .*history" | tail -10
echo "</pre>" >> "$HTML_REPORT"
} | tee -a "$REPORT_FILE"
# Завершение HTML отчета
cat >> "$HTML_REPORT" << 'EOF'
<h2>Summary</h2>
<div class="info">
<p>Analysis completed. Review all findings above and take appropriate action.</p>
<p>For critical findings, immediate investigation is recommended.</p>
</div>
</body>
</html>
EOF
echo -e "\n${GREEN}[+] Анализ завершен!${NC}"
echo -e "${GREEN}[+] Текстовый отчет: $REPORT_FILE${NC}"
echo -e "${GREEN}[+] HTML отчет: $HTML_REPORT${NC}"
}
# ДОПОЛНИТЕЛЬНЫЕ УТИЛИТЫ
# Мониторинг в реальном времени
monitor_realtime() {
echo -e "${BLUE}[*] Запуск мониторинга в реальном времени...${NC}"
echo -e "${YELLOW}Нажмите Ctrl+C для остановки${NC}\n"
tail -f /var/log/auth.log | \
while read line; do
# Подсветка критичных событий
if echo "$line" | grep -qE "Failed password|authentication failure"; then
echo -e "${RED}[FAIL]${NC} $line"
elif echo "$line" | grep -q "Accepted"; then
echo -e "${GREEN}[OK]${NC} $line"
elif echo "$line" | grep -qE "sudo.*COMMAND"; then
echo -e "${YELLOW}[SUDO]${NC} $line"
else
echo "$line"
fi
done
}
# Быстрая проверка IOC
check_ioc() {
local ioc_file="${1:-/tmp/ioc_list.txt}"
if [ ! -f "$ioc_file" ]; then
echo -e "${RED}[!] IOC файл не найден: $ioc_file${NC}"
return 1
fi
echo -e "${BLUE}[*] Проверка IOC из $ioc_file...${NC}"
while IFS= read -r ioc; do
echo -e "\nПоиск: $ioc"
# Поиск в логах
grep -r "$ioc" /var/log/ 2>/dev/null | head -5
# Поиск в процессах
ps aux | grep -v grep | grep "$ioc"
# Поиск в сети
ss -tun | grep "$ioc"
done < "$ioc_file"
}
# Главное меню
main() {
check_permissions
case "${1:-analyze}" in
analyze)
analyze_security
;;
monitor)
monitor_realtime
;;
ioc)
check_ioc "$2"
;;
*)
echo "Использование: $0 {analyze|monitor|ioc [file]}"
exit 1
;;
esac
}
# Запуск
main "$@"
Инструменты форензики для джуниор SOC-аналитиков 2025
Твой арсенал — это то, что отличает профессионала от любителя. Давай посмотрим, чем воевать.Российские решения и их возможности
Бесплатные инструменты доступные в РФ
Не все измеряется деньгами. Мощный арсенал можно собрать и бесплатно.Анализ логов:
- ELK Stack (Elasticsearch, Logstash, Kibana) — мощная и гибкая платформа для сбора и анализа логов.
- Graylog — отличная альтернатива ELK с удобным веб-интерфейсом.
- OSSEC — система обнаружения вторжений, которая умеет анализировать логи в реальном времени.
- Wireshark — абсолютный стандарт для анализа сетевого трафика.
- NetworkMiner — мастер по извлечению артефактов (файлов, учетных данных) из PCAP-файлов.
- Suricata — мощная IDS/IPS с возможностями форензики.
- Sysinternals Suite — набор утилит от Microsoft, который должен быть у каждого.
- YARA — поиск и классификация вредоносного ПО (
Ссылка скрыта от гостей).
- Volatility — король анализа дампов оперативной памяти.
GUI-интерфейсы для визуального анализа
Консоль — это круто, но иногда хочется простоты и наглядности.MaxPatrol SIEM Dashboard:
- Интерактивные дашборды, которые показывают картину целиком.
- Drag-and-drop конструктор отчетов для начальства.
- Интеграция с российскими источниками Threat Intelligence.
- Красивые графики для визуализации временных рядов событий.
- Возможность создавать алерты на основе аномалий.
- Полная поддержка русского языка в интерфейсе.
Монетизация навыков форензики на российском рынке
Знания — это хорошо, а знания, которые приносят деньги — еще лучше. Давай посмотрим, как превратить навыки в карьеру и доход.Построение портфолио SOC-аналитика
Структура портфолио для джуниора:- Кейсы расследований: 3-5 детальных разборов инцидентов (можно с платформ вроде Hack The Box).
- Скрипты автоматизации: Твои готовые решения для анализа логов на PowerShell или Bash.
- Сертификаты: GCIH, GCFA или российские аналоги от Positive Technologies покажут твою серьезность.
- Публикации: Статьи на Habr или Codeby, выступления на конференциях — это жирный плюс.
- Экспресс-анализ инцидента: 150-300 тыс. рублей.
- Полное расследование: 500 тыс. - 2 млн рублей.
- Консультации по час: 8-15 тыс. рублей.
- Аудит системы логирования: 200-500 тыс. рублей.
Карьерные траектории в форензике
Junior SOC Analyst (80-150 тыс. руб/мес):- Смотрит на дашборды SIEM.
- Разбирает первичные алерты.
- Выполняет базовый анализ логов по готовым инструкциям.
- Проводит глубокие расследования инцидентов.
- Пишет правила корреляции для SIEM.
- Общается с внешними экспертами и вендорами.
- Проектирует архитектуру систем безопасности.
- Выступает экспертом в суде.
- Руководит командой аналитиков (путь в кибербез).
Часто задаваемые вопросы
Q: Как анализировать Windows Event Log для SOC-аналитика?A: Сконцентрируйся на Event ID 4624 (успешный вход), 4625 (неудачный вход), 4720 (создание юзера), 4740 (блок учетки). Используй PowerShell для автоматизации и ищи аномалии по времени и IP-адресам.
Код:
# КРИТИЧЕСКИ ВАЖНЫЕ Event ID для SOC (не только базовые 4):
# === АУТЕНТИФИКАЦИЯ И ДОСТУП ===
4624 # Успешный вход (ВАЖНО: проверять Logon Type!)
# Type 2 = Interactive (физический вход)
# Type 3 = Network (сетевой доступ)
# Type 10 = RemoteInteractive (RDP)
# Type 11 = CachedInteractive (offline вход)
4625 # Неудачный вход (смотреть Failure Reason и SubStatus!)
4634 # Выход из системы
4648 # Вход с явными учетными данными (lateral movement!)
4672 # Специальные привилегии назначены при входе
# === УПРАВЛЕНИЕ УЧЕТНЫМИ ЗАПИСЯМИ ===
4720 # Создание учетной записи
4722 # Учетная запись включена
4723 # Попытка смены пароля
4724 # Попытка сброса пароля
4725 # Учетная запись отключена
4726 # Учетная запись удалена
4738 # Учетная запись изменена
4740 # Блокировка учетной записи
4767 # Разблокировка учетной записи
# === УПРАВЛЕНИЕ ГРУППАМИ (КРИТИЧНО!) ===
4728 # Добавление в глобальную группу безопасности
4732 # Добавление в локальную группу безопасности
4756 # Добавление в универсальную группу безопасности
4733 # Удаление из группы безопасности
# === ИЗМЕНЕНИЯ ПОЛИТИК ===
4719 # Изменение политики аудита
4739 # Изменение политики домена
# === ПРИВИЛЕГИИ И ПРАВА ===
4673 # Использование привилегированной службы
4674 # Операция с привилегированным объектом
4688 # Создание нового процесса (с командной строкой!)
4689 # Завершение процесса
# === ДОСТУП К ОБЪЕКТАМ ===
4656 # Запрос доступа к объекту
4663 # Попытка доступа к объекту
4660 # Объект удален
4670 # Изменены разрешения объекта
# === СЕТЕВАЯ АКТИВНОСТЬ ===
5140 # Доступ к сетевой папке
5145 # Проверка доступа к сетевому объекту
5156 # Windows Firewall разрешил подключение
5157 # Windows Firewall заблокировал подключение
# === КРИТИЧЕСКИЕ СИСТЕМНЫЕ СОБЫТИЯ ===
1102 # Журнал аудита очищен (УДАЛЕНИЕ СЛЕДОВ!)
4616 # Системное время изменено
4657 # Изменение значения реестра
4697 # Установка службы в системе
4698 # Создание запланированной задачи
4702 # Обновление запланированной задачи
7045 # Установка новой службы (System log)
PowerShell команды для эффективного анализа:
Код:
# 1. КОМПЛЕКСНЫЙ АНАЛИЗ БРУТФОРСА
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4625} -MaxEvents 1000 |
Group-Object {$_.Properties[19].Value} | # Группировка по IP
Where-Object {$_.Count -gt 10} |
ForEach-Object {
$ip = $_.Name
$events = $_.Group
$users = $events | ForEach-Object {$_.Properties[5].Value} | Select-Object -Unique
[PSCustomObject]@{
SourceIP = $ip
AttemptsCount = $_.Count
TargetUsers = $users -join ', '
FirstAttempt = $events[0].TimeCreated
LastAttempt = $events[-1].TimeCreated
AttackPattern = if($users.Count -gt 5) {"Password Spray"} else {"Targeted"}
}
} | Sort-Object AttemptsCount -Descending
# 2. ОБНАРУЖЕНИЕ LATERAL MOVEMENT
# Корреляция 4624 (Type 3) + 4672 (admin privs) + 4688 (process)
$timeWindow = (Get-Date).AddHours(-24)
$suspiciousLogins = Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=@(4624,4672,4688)
StartTime=$timeWindow
} | Group-Object {$_.RecordId} |
Where-Object {
$events = $_.Group
($events | Where-Object {$_.Id -eq 4624 -and $_.Properties[8].Value -eq 3}) -and
($events | Where-Object {$_.Id -eq 4672}) -and
($events | Where-Object {$_.Id -eq 4688 -and $_.Properties[5].Value -match 'powershell|cmd|wmic'})
}
# 3. ОБНАРУЖЕНИЕ KERBEROASTING
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4769} |
Where-Object {
$_.Properties[8].Value -eq '0x17' -and # RC4 encryption
$_.Properties[6].Value -ne 'krbtgt' -and
$_.Properties[6].Value -ne '$'
} | Select-Object TimeCreated,
@{N='ServiceName';E={$_.Properties[6].Value}},
@{N='ClientName';E={$_.Properties[3].Value}}
# 4. ОБНАРУЖЕНИЕ GOLDEN TICKET
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4624} |
Where-Object {
$_.Properties[8].Value -eq 3 -and # Network logon
$_.Properties[11].Value -eq 'Kerberos' -and
[DateTime]::Parse($_.Properties[12].Value) -gt (Get-Date).AddDays(10) # Ticket > 10 days
}
# 5. МОНИТОРИНГ ИЗМЕНЕНИЙ В ADMIN ГРУППАХ
Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=@(4728,4732,4756)
StartTime=(Get-Date).AddDays(-1)
} | Where-Object {
$_.Message -match 'Domain Admins|Enterprise Admins|Schema Admins|Administrators'
} | ForEach-Object {
[PSCustomObject]@{
Time = $_.TimeCreated
Action = "User added to privileged group"
Group = ($_.Message | Select-String -Pattern 'Group Name:\s+(.+)' -AllMatches).Matches[0].Groups[1].Value
Member = ($_.Message | Select-String -Pattern 'Member:\s+(.+)' -AllMatches).Matches[0].Groups[1].Value
AddedBy = ($_.Message | Select-String -Pattern 'Subject:[\s\S]+Account Name:\s+(.+)' -AllMatches).Matches[0].Groups[1].Value
}
}
# 6. TIMELINE РЕКОНСТРУКЦИЯ АТАКИ
function Build-AttackTimeline {
param([string]$TargetUser, [int]$Hours = 24)
$criticalEvents = @(4624,4625,4672,4688,4698,4720,4732)
Get-WinEvent -FilterHashtable @{
LogName='Security'
ID=$criticalEvents
StartTime=(Get-Date).AddHours(-$Hours)
} | Where-Object {$_.Message -match $TargetUser} |
Select-Object TimeCreated, Id,
@{N='EventType';E={
switch($_.Id) {
4624 {'Successful Login'}
4625 {'Failed Login'}
4672 {'Admin Rights'}
4688 {'Process Created'}
4698 {'Scheduled Task'}
4720 {'Account Created'}
4732 {'Added to Group'}
}
}},
@{N='Details';E={$_.Message.Substring(0, [Math]::Min(200, $_.Message.Length))}}
| Sort-Object TimeCreated
}
Дополнительные критические проверки:
Код:
# ПРОВЕРКА НА MIMIKATZ
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=@(4656,4663,4703)} |
Where-Object {$_.Message -match 'lsass\.exe'}
# ОБНАРУЖЕНИЕ PASS-THE-HASH
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4624} |
Where-Object {
$_.Properties[8].Value -eq 3 -and # Network logon
$_.Properties[10].Value -eq 'NTLM' -and
$_.Properties[11].Value -eq '0x0' # No elevated token
}
# ПРОВЕРКА УДАЛЕНИЯ ЛОГОВ
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=1102} -ErrorAction SilentlyContinue
Get-WinEvent -FilterHashtable @{LogName='System'; ID=104} -ErrorAction SilentlyContinue
A: Для базового анализа используйте:
- Брутфорс:
grep "Failed password" /var/log/auth.log (Debian/Ubuntu) или /var/log/secure
(RHEL/CentOS) - Sudo активность:
grep -E "sudo:.*COMMAND=" /var/log/auth.log
- Извлечение IP атакующих:
grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"
- Для systemd систем: используйте
journalctl
вместо grep - Для сжатых логов: используйте
zgrep
вместо grep - Временная фильтрация:
grep "$(date '+%b %e')" /var/log/auth.log
Bash:
# УНИВЕРСАЛЬНЫЕ команды для разных дистрибутивов:
# 1. Поиск брутфорса (работает везде)
grep -E "Failed password|authentication failure" /var/log/auth.log 2>/dev/null || \
grep -E "Failed password|authentication failure" /var/log/secure 2>/dev/null
# 2. Более эффективный анализ брутфорса с подсчетом
grep "Failed password" /var/log/auth.log | \
grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | \
sort | uniq -c | sort -nr | head -10
# 3. Sudo команды с полным контекстом
grep -E "sudo:.*COMMAND=" /var/log/auth.log | \
sed -n 's/.*sudo: *\([^ ]*\).*COMMAND=\(.*\)/User: \1 | Command: \2/p'
# 4. ВАЖНЫЕ дополнительные команды:
# Успешные входы после неудач (признак взлома)
grep -A5 -B5 "Accepted password" /var/log/auth.log | \
grep -E "Failed password.*Accepted password"
# SSH ключи и подозрительная активность
grep -E "Accepted publickey|Invalid user|Connection closed by authenticating user" /var/log/auth.log
# Изменения привилегий
grep -E "user NOT in sudoers|opened a session|session closed" /var/log/auth.log
# Временная корреляция (события за последний час)
grep "$(date -d '1 hour ago' '+%b %e %H')" /var/log/auth.log
# 5. Продвинутые паттерны с регулярками:
# Обнаружение password spray
awk '/Failed password/ {print $11}' /var/log/auth.log | \
sort | uniq -c | awk '$1 > 10 {print}'
# Поиск подозрительных команд
grep -E "sudo.*COMMAND" /var/log/auth.log | \
grep -E "(wget|curl|nc |netcat |bash.*-c|chmod.*777|/etc/passwd|/etc/shadow)"
# Анализ источников атак по странам
grep "Failed password" /var/log/auth.log | \
grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" | \
sort -u | while read ip; do
echo -n "$ip: "
geoiplookup $ip 2>/dev/null || echo "Unknown"
done
Критически важные дополнения:
1. Учет разных систем:
Bash:
# Автоопределение системы логов
LOG_FILE=$([ -f /var/log/auth.log ] && echo "/var/log/auth.log" || echo "/var/log/secure")
grep "Failed password" "$LOG_FILE"
Bash:
zgrep "Failed password" /var/log/auth.log* | head -50
Bash:
journalctl -u sshd --since "1 hour ago" | grep "Failed password"
Q: Как проводить корреляцию сетевых событий в форензике?
A: Связывай данные из SIEM по времени и IP. В MaxPatrol SIEM используй JOIN-запросы, чтобы соединить события Windows, Linux и сетевых устройств. Всегда смотри на временное окно ±5 минут от ключевого события.
Q: Какие инструменты необходимы джуниор SOC-аналитику для форензики?
A: Твой стартовый набор: Wireshark, PowerShell/Bash, MaxPatrol SIEM или ELK Stack, и Sysinternals. Готовь бюджет в 150-300 тыс. рублей в год на корпоративные лицензии.
Q: Что такое критически важные логи при расследовании инцидентов?
A: Это Windows Security Log (особенно 4624/4625), Linux auth.log/syslog, логи веб-сервера (access.log), DNS-логи, логи файрвола и антивируса. Они покрывают 90% векторов атак.
Q: Как читать цифровые следы после взлома?
A: Иди по цепочке:
1) Точка входа (веб-уязвимость, RDP).
2) Продвижение по сети (SMB, WMI).
3) Повышение привилегий (эксплойт, дампинг кредов).
4) Закрепление (новые юзеры, задачи в планировщике).
5) Кража данных (аномальный исходящий трафик).
Решение типовых проблем
Проблема | Симптомы | Решение | Профилактика |
---|---|---|---|
Переполнение логов | Диск забит, система тормозит | Настрой ротацию логов, архивируй старые | Мониторь размер логов, настрой автоочистку |
Ложные срабатывания SIEM | Тысячи алертов на обычные действия | Добавь в whitelist доверенные IP и пользователей | Регулярно тюнингуй правила корреляции |
Потеря временной синхронизации | События в логах живут в разном времени | Настрой NTP на всех системах | Используй централизованный NTP-сервер |
Недоступность логов | Критичная система молчит | Проверь агентов сбора логов и сеть | Настрой мониторинг состояния log collectors |
Медленный поиск в логах | Запрос выполняется вечность | Индексируй ключевые поля, оптимизируй запросы | Регулярно обслуживай индексы в SIEM |
Неполная корреляция | SIEM пропускает связанные события | Расширь временное окно для корреляции | Синхронизируй часы, настрой буферы агентов |
Нехватка контекста | В логе есть событие, но нет деталей | Включи расширенное логирование | Настрой verbose logging для критичных систем |
Ресурсы для углубления
Русскоязычные:
- Positive Technologies Blog — свежие исследования и кейсы от ведущих российских экспертов.
- Anti-Malware.ru — живой форум, где можно задать вопрос и получить ответ от практиков.
- Habr Security — статьи от SOC-аналитиков и исследователей с реальным опытом.
Практическое обучение и лабораторные:
- Практикум по расследованию инцидентов incident.codeby.school — hands-on разбор реальных кейсов компрометации с анализом Windows Event Log, память и сетевого трафика.
- DFIR для Linux систем dfir-linux.codeby.school — углубленная форензика Linux: от анализа логов до восстановления timeline атак.
- SANS Cyber Aces — бесплатные туториалы по основам (на английском).
- Лаборатории на GitHub — поищите "DFIR labs" для практики на реальных образах.
Инструменты доступные в РФ:
- MaxPatrol SIEM — флагманское российское решение для корреляции событий.
- ELK Stack — открытая и мощная платформа для анализа больших объемов логов.
- Wireshark — стандарт индустрии для анализа сетевого трафика.
- YARA — язык для описания и поиска вредоносного ПО.
- Volatility Framework — анализ дампов оперативной памяти.