Расследование взлома корпоративной почты: как мы нашли атаку

Обращение клиента: юридическая фирма под ударом

Юридическая фирма «Правовой Альянс» обратилась к нам экстренно: за последние два месяца позиции их корпоративного сайта в поисковых системах упали на 60-70%. Сайт — визитка фирмы с блогом юридических статей, основной источник привлечения клиентов. Потеря позиций означала потерю 40% входящих обращений.

Внутренний IT-специалист клиента проверил сайт стандартными средствами: файлы не изменены, вирусов нет, SSL-сертификат валиден, контент на месте. Но при проверке сайта через Google Search Console обнаружились странные предупреждения о «смешанных кодировках» в тексте страниц.

Наша команда ITFresh приняла задачу и начала расследование, которое вскрыло изощрённую атаку, невидимую обычными средствами диагностики.

Первые признаки: невидимая аномалия

Мы начали с базовой проверки — открыли сайт в браузере и визуально всё выглядело корректно. Текст на русском языке читался нормально, верстка не нарушена. Однако когда мы скопировали текст со страницы и вставили в hex-редактор, обнаружилась аномалия:

# Нормальный текст (UTF-8, кириллица)
D0 9F D1 80 D0 B0 D0 B2 D0 BE D0 B2 D0 BE D0 B9
П  р  а  в  о  в  о  й

# Текст со страницы (для поисковых ботов)
D0 9F D1 80 61 D0 B2 6F D0 B2 6F D0 B9
П  р  a  в  o  в  o  й

Буквы «а» и «о» в тексте были подменены на визуально идентичные латинские аналоги — но только для трафика поисковых роботов! Обычные пользователи получали нормальную страницу. Это классическая гомографическая атака, адаптированная для SEO-диверсии.

Форензика: анализ nginx на уровне бинарника

Стандартная проверка конфигурации nginx через nginx -T (дамп всей конфигурации) не показала ничего подозрительного. Все конфигурационные файлы на диске выглядели чисто. Но мы заметили первую зацепку:

# Версия установленного пакета
$ dpkg -l | grep nginx
nginx  1.14.2-1~stretch

# Версия запущенного бинарника
$ nginx -v
nginx version: nginx/1.10.3

# Несовпадение версий — критический индикатор!

Бинарный файл nginx был подменён скомпилированной версией с модифицированным исходным кодом. Злоумышленник изменил обработку флага -T в исходниках (src/core/nginx.c, функция case 'T':), отключив вывод скрытых директив конфигурации.

Извлечение скрытой конфигурации через GDB

Поскольку штатные средства nginx были скомпрометированы, мы использовали отладчик для извлечения реальной конфигурации из памяти процесса:

# Подтверждение: strace показывает отсутствие write() при -T
$ strace -e write nginx -T 2>&1 | grep write
# Пусто — подтверждение модификации бинарника

# Подключаемся к запущенному процессу через GDB
$ gdb -p $(pgrep -f 'nginx: master')
(gdb) break main
(gdb) set ngx_dump_config = 1
(gdb) continue

После принудительной установки переменной ngx_dump_config в 1 через отладчик, nginx выдал полную конфигурацию, включая скрытые директивы, которые были невидимы через nginx -T.

Механизм атаки: условная подмена символов

Извлечённая скрытая конфигурация содержала изощрённый механизм подмены контента с использованием модуля sub_filter и условной логики на основе User-Agent:

# Определение: это поисковый бот?
map $http_user_agent $is_search_bot {
    "~*yandex.com/bots"       1;
    "~*googlebot"             1;
    "~*www.google.com/bot"    1;
    "~*bingbot"               1;
    default                   0;
}

# Исключение: это WordPress-админка?
map $uri $is_wp_admin {
    "~*/wp-admin"  1;
    "~*/wp-login"  1;
    default        0;
}

# Условная подмена кириллической 'о' (U+043E)
map "о:$is_search_bot:$is_wp_admin" $replace_o {
    "о:1:0"  "o";    # Для бота: латинская 'o' (U+006F)
    default  "о";    # Для всех остальных: кириллическая 'о'
}

# Условная подмена кириллической 'а' (U+0430)
map "а:$is_search_bot:$is_wp_admin" $replace_a {
    "а:1:0"  "a";    # Для бота: латинская 'a' (U+0061)
    default  "а";    # Для всех остальных: кириллическая 'а'
}

# Применение подмены
sub_filter_once off;
sub_filter 'о' $replace_o;
sub_filter 'а' $replace_a;

Изящность атаки заключалась в следующем:

  • Обычные пользователи видели нормальный текст — жалоб не поступало
  • Поисковые боты получали текст со смешанными кодировками — алгоритмы ранжирования расценивали это как спам или некачественный контент
  • Подмена затрагивала только буквы «а» и «о» — самые частотные в русском языке
  • WordPress-админка не затрагивалась — администратор не замечал изменений

Определение вектора проникновения

Для компиляции и подмены бинарника nginx злоумышленнику требовался root-доступ к серверу. Мы проанализировали возможные вектора проникновения:

# Проверка SSH-логов
$ grep 'Accepted' /var/log/auth.log | grep -v 'known_ips'
# Обнаружены подключения с IP из Юго-Восточной Азии

# Проверка SSH-ключей
$ find / -name authorized_keys -exec md5sum {} \;
# Неизвестный ключ в /root/.ssh/authorized_keys

# Проверка cron
$ for user in $(cut -f1 -d: /etc/passwd); do crontab -l -u $user 2>/dev/null; done
# Обнаружен cron-задание для обновления бэкдора

# Проверка SUID-файлов
$ find / -perm -4000 -type f 2>/dev/null
# Нетипичные SUID-бинарники в /tmp

Расследование показало: злоумышленник получил доступ через скомпрометированный SSH-ключ одного из подрядчиков, который имел root-доступ для обслуживания сервера. Ключ не был отозван после завершения контракта 8 месяцев назад.

Восстановление и защита

Скомпрометированный сервер был полностью перестроен с нуля. Восстановление из бэкапов не рассматривалось, так как невозможно было определить точную дату компрометации.

План восстановления

Наша команда выполнила следующие шаги:

  1. Развёртывание нового сервера на чистой Ubuntu 22.04 с hardening по CIS Benchmark
  2. Установка nginx из официального репозитория с верификацией подписи пакета
  3. Перенос сайта из Git-репозитория (не с компрометированного сервера)
  4. Настройка верификации бинарников через AIDE (Advanced Intrusion Detection Environment)
# Установка и настройка AIDE
apt install aide

# Конфигурация мониторинга критичных файлов
cat >> /etc/aide/aide.conf << 'EOF'
/usr/sbin/nginx p+i+n+u+g+s+b+m+c+sha256
/etc/nginx p+i+n+u+g+d+s+b+m+c+sha256
EOF

# Инициализация базы
aideinit

# Ежедневная проверка через cron
0 6 * * * /usr/bin/aide --check | mail -s "AIDE Report" admin@pravovoy-alians.ru

Превентивные меры безопасности

Мы внедрили комплекс мер для предотвращения повторных инцидентов:

# 1. SSH hardening — /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
MaxAuthTries 3
AllowUsers deploy_user
ClientAliveInterval 300
ClientAliveCountMax 2

# 2. Автоматическая проверка целостности nginx
#!/bin/bash
# /usr/local/bin/verify_nginx.sh — запуск каждый час
EXPECTED_HASH="$(apt-cache show nginx | grep SHA256)"
ACTUAL_HASH="$(sha256sum /usr/sbin/nginx | cut -d' ' -f1)"

if [ "$EXPECTED_HASH" != "$ACTUAL_HASH" ]; then
    echo "ALERT: nginx binary modified!" | \
        telegram-send --config /etc/telegram-send.conf
    systemctl stop nginx
fi

# 3. Fail2ban для SSH
[sshd]
enabled = true
maxretry = 3
bantime = 86400
findtime = 600

Дополнительно мы настроили мониторинг позиций сайта через Google Search Console API с алертами при падении более чем на 10% за неделю.

Техническая суть: почему 'а' не равно 'a'

Для полного понимания атаки необходимо разобраться в Unicode. Кириллическая буква «а» (U+0430) и латинская «a» (U+0061) — это разные символы с разными кодами, хотя визуально идентичны в большинстве шрифтов.

# Демонстрация различий в Python
>>> cyrillic_a = 'а'  # U+0430
>>> latin_a = 'a'      # U+0061
>>> cyrillic_a == latin_a
False
>>> cyrillic_a.encode('utf-8')
b'\xd0\xb0'  # два байта
>>> latin_a.encode('utf-8')
b'a'          # один байт
>>> ord(cyrillic_a)
1072
>>> ord(latin_a)
97

Таблица визуально идентичных символов кириллицы и латиницы, используемых в гомографических атаках:

КириллицаUnicodeЛатиницаUnicode
аU+0430aU+0061
оU+043EoU+006F
еU+0435eU+0065
рU+0440pU+0070
сU+0441cU+0063
уU+0443yU+0079
хU+0445xU+0078

Поисковые алгоритмы обнаруживают смешение скриптов в тексте и интерпретируют это как признак автогенерированного или спамного контента, что приводит к понижению ранжирования.

Результаты расследования и восстановления

Полный цикл работ — от первого обращения до восстановления позиций — занял 6 недель:

ЭтапСрокРезультат
Расследование и форензика3 дняМеханизм атаки полностью раскрыт
Восстановление сервера2 дняЧистый сервер с hardening
Переиндексация поисковиками4-5 недельПозиции восстановлены на 90%
Полное восстановление SEO6 недельВозврат к показателям до атаки

Клиент «Правовой Альянс» заключил с нами договор на постоянное сопровождение инфраструктуры, включающий еженедельные проверки целостности, мониторинг позиций и оперативное реагирование на инциденты. Подробнее о наших услугах по кибербезопасности — на itfresh.ru.

Часто задаваемые вопросы

Визуально это практически невозможно. Используйте hex-редактор или скрипт, который проверяет, что все символы в тексте принадлежат одному Unicode-диапазону. Кириллические символы занимают 2 байта в UTF-8 (D0-D1 xx), а латинские — 1 байт (41-7A).
Сравните хэш-сумму файла /usr/sbin/nginx с эталоном из пакетного менеджера: dpkg --verify nginx или rpm -V nginx. Также проверьте совпадение версий между nginx -v и dpkg -l nginx. Расхождение — критический индикатор компрометации.
При root-компрометации невозможно определить точную дату проникновения. Любой бэкап может содержать бэкдор. Единственный надёжный путь — полная пересборка сервера с нуля и перенос данных только из проверенных источников (Git-репозиторий, верифицированные дампы БД).
AIDE или Tripwire для контроля целостности файлов, Fail2ban для защиты SSH, регулярная ротация SSH-ключей, принцип минимальных привилегий, запрет root-логина по SSH. Для веб-серверов — автоматическая верификация бинарников по расписанию.
Обычно от 4 до 8 недель. После устранения проблемы необходимо запросить переиндексацию в Google Search Console и Яндекс.Вебмастер, убедиться в чистоте контента и подождать, пока поисковые алгоритмы пересчитают ранжирование.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#расследование взлома#корпоративная безопасность#unicode атака#гомографическая атака#nginx безопасность#форензика linux#SEO атака#информационная безопасность
Комментарии 0

Оставить комментарий

загрузка...