Привет! Меня зовут Дмитрий Каплунов. Я работаю младшим аналитиком SOC в команде Анастасии Федоровой в К2 Кибербезопасность и более года занимаюсь анализом и расследованием инцидентов ИБ. Один из самых частых видов атак, с которым встречается команда SOC, — это брутфорс. Злоумышленники используют его для взлома систем, учетных записей, зашифрованных данных и т.д. Под катом я собрал всю полезную информацию про расследование брутфорса в SOC, в т.ч. про то, как отличить реальные атаки от сработок, которые вызваны проблемами в инфраструктуре.
«Брутфорс» (от англ. brute force, дословно «грубая сила») обычно обозначает метод атаки, при котором злоумышленник пытается подобрать пароль, логин или ключ шифрования, перебирая все возможные комбинации символов, пока не найдет нужный.
Сложно представить, как человек вручную пытается подобрать пароль или угадать имя учетной записи, поэтому злоумышленник использует специальное ПО, которое отправляет нужные запросы с разными паролями или именами пользователей по словарю или даже генерирует их. При достаточном техническом оснащении у злоумышленника появляется возможность подбирать огромное количество комбинаций за короткий промежуток времени. Неспроста в большинстве инфраструктур существуют достаточно высокие стандарты парольной политики — все, чтобы у паролей типа «Qwerty12345» не осталось шансов на существование.
В контексте SOC необходимо однозначно понимать, появление каких событий может указывать на брутфорс-атаку. В архитектуре Active Directory (AD) сигнализировать об этом могут события:
4625 An account failed to log on
4768 A Kerberos authentication ticket (TGT) was requested (С полем события Result Code неравным 0х0*)
4771 Kerberos pre-authentication failed
4776 The computer attempted to validate the credentials for an account (С полем события Result Code неравным 0х0)
*Поле события Result Code служит для обозначения удачи или причины неудачи запроса, код 0х0 обозначает успешный запрос
Все события выше можно ассоциировать с неудачным входом, но только при наличии определенных логических связей и содержащейся в них информации можно сделать вывод о возможной атаке и ее конкретной форме. На практике чаще всего встречаются две формы атаки — перечисление пользователей и попытка подбора пароля.
Перечисление пользователей — это когда злоумышленник буквально перебирает наиболее распространенные имена пользователей, чтобы угадать или подтвердить наличие определенных учетных записей в системе.
В самом классическом варианте злоумышленник поочередно использует для входа возможные имена пользователей и смотрит на ответное сообщение системы. Если в ответе сообщается, что «Пользователя не существует», то злоумышленник может сделать вывод о том, что для подбора следует пробовать следующее имя пользователя. И так до тех пор, пока система не сообщит, что «Пароль неверный» — это будет означать, что злоумышленник все-таки смог подобрать существующее имя пользователя и при желании останется лишь подобрать пароль к конкретной учетной записи. Подбор пароля к существующей учетной записи будет уже более возможным, нежели попытка подобрать комбинацию имени пользователи и пароля.
Но иногда бывает и так, что у злоумышленника уже есть пароль — он пытается подобрать к нему соответствующее имя учетной записи или готовая связка — имя пользователя + пароль, тогда злоумышленник пытается перебирать системы, к которым эта связка сможет подойти.
На возможную атаку перечислением пользователей будут указывать только несколько событий с одинаковыми Event ID, в которых:
Различные значения полей TargetUserName (имя пользователя, которое пытались угадать).
Одинаковые значения полей Workstation (имя хоста, откуда пришли запросы на вход), IpAddress (IP-адрес хоста, откуда пришли запросы на вход), Computer (имя хоста, на который был запрос входа).
Подразумевается, что потенциальный злоумышленник во время атаки отправляет с одного и того же хоста — поля Workstation и IpAddress, запросы на вход в различные учетные записи — поле TargetUserName, на один и тот же хост – поле Computer.
Также важно количественно понимать, что значит «несколько событий». Неопределенное слово «несколько» означает некое количество событий, после которого предположение, что вновь появившиеся события уже не просто результат простой ошибки пользователя при вводе учетных данных, имеет смысл. В каждой инфраструктуре есть свои особенности и количество событий выбирается обычно не менее 10.
Для атаки с помощью перечисления пользователей может использоваться так называемое перечисление пользователей по словарю — в этот словарь входят самые часто встречающиеся имена учетных записей. Такую атаку сложно перепутать с чем-либо другим, если обратить внимание на имена пользователя в событиях.
Для примера возьмем скриншот из SIEM-системы Kaspersky Unified Monitoring and Analysis Platform (KUMA), хотя в продуктах других вендоров события, конечно, отличаться не будут.
На скриншоте — события, как раз вызванные попыткой атаки перечислением пользователей по словарю. Столбец DestinationUserName — имена пользователей, которых «угадывали» на наличие их в системе.
Попытка подбора пароля — это как правило случай, когда злоумышленник обладает информацией о существующих учетных записях в системе и его действия направлены на подбор пароля к ним. В аналитике SOC принято разделять эту форму брутфорс-атаки на отдельно неудачные и удачные попытки.
На неудачную попытку подбора пароля могут указывать все те же события 4625, 4768, 4771 и 4776. При этом, для нас представляют интерес только логически связанные между собой события с одинаковыми EventID, в которых:
Одинаковые значения полей Workstation (имя хоста отправителя запросов), IpAddress (IP-адрес хоста отправителя запросов), Computer (имя хоста-получателя запроса), TargetUserName (имя пользователя, к которому пытаются подобрать пароль).
То есть возможную атаку можно подозревать, если мы видим, например, 25 событий 4771 — Kerberos pre-authentication failed, в которых указан одинаковый хост/адрес, откуда приходят запросы — поля WorkstationName/IpAddress, имя хоста-получателя запросов — поле Computer, имя пользователя — поле TargetUserName.
На успешную попытку атаки подбором пароля может указывать последовательность из событий неудачной попытки подбора пароля — тех, о которых шла речь выше, и последующее появление после них хотя бы одного события, ассоциируемого с успешным входом:
4624 An account was successfully logged on;
4768 A Kerberos authentication ticket (TGT) was requested. (С полем события Result Code = 0х0);
4776 The computer attempted to validate the credentials for an account. (С полем события Result Code = 0х0).
Здесь также важно не забывать, что не всегда события успешного входа действительно сопоставимы с неуспешными предшествующими попытками и прежде всего необходимо проверить именно это.
При анализе таких событий в первую очередь необходимо обратить внимание на поля событий ClientAddress, WorkstationName, IpAddress — важно, чтобы все события указывали на один и тот же хост или IP-адрес источника. Иногда в окружении может появиться событие успешного входа, но с другим значением IP-адреса или именем хоста источника. Здесь нельзя сделать вывод об успешной атаке, но можно сделать о том, что куда-то пользователь смог войти, а куда-то не смог. Наиболее частой причиной является то, что пароль после его обновления на новый где-то не обновился и, например, почтовый агент пытается авторизоваться по старому паролю.
При анализе событий 4625 An account failed to log on и 4624 An account was successfully logged on помимо одинакового IP-адреса и/или хоста, откуда производился вход, важно обратить внимание на значения полей событий AuthenticationPackageName (Имя пакета аутентификации, который использовался для процесса аутентификации при входе в систему) и LogonId (Идентификатор входа — значение, которое может помочь вам сопоставить это событие с недавними событиями, которые могут содержать тот же идентификатор входа в систему).Если значения полей события 4624 соответствуют значениям события 4625, то можно действительно сопоставлять эти события.
При анализе 4768 A Kerberos authentication ticket (TGT) was requested И 4776 The computer attempted to validate the credentials for an account важно обратить внимание на значения полей событий TicketOptions (Набор различных флагов билета в шестнадцатеричном формате) и TicketEncryptionType (Набор шифрования, который использовался для выдачи TGT). В случае если они одинаковы — можно действительно сопоставить однозначно сказать, что эти события сопоставимы.
Рассмотренные базовые принципы выявления брутфорс-атак обеспечивают общее понимание процесса. Однако для более глубокого понимания происходящего в вашей инфраструктуре и исключения False-Positive, необходимо учитывать ряд дополнительных особенностей, о которых будет рассказано далее.
Поля события FailureCode или ResultCode
Вне зависимости от формы атаки, если в «подозреваемых» событиях указано поле FailureCode или ResultCode, важно уделить им отдельное внимание. «Кодов ошибки» существует немало — они служат для обозначения удачи или причины неудачи запроса. Некоторые из кодов ошибок могут указывать как на возможную атаку, так и на иные проблемы в инфраструктуре. Чаще всего на практике мы столкнемся с такими кодами:
0x0 KDC_ERR_NONE — код успешной предварительной аутентификации;
0x6 KDC_ERR_C_PRINCIPAL_UNKNOWN — пользователь не найден в базе данных Kerberos;
0x17 KDC_ERR_KEY_EXPIRED — пароль пользователя истёк;
0x18 KDC_ERR_PREAUTH_FAILED — неправильный логин или/и пароль;
0x25 KRB_AP_ERR_SKEW — слишком большая разница во времени.
Разберем чуть подробнее.
Код 0х0 указывает на успешную предварительную аутентификацию и может свидетельствовать об успешной попытке подбора пароля — в таком случае важно проанализировать коды, указанные в предшествующих событиях.
Код 0x6 может указывать на то, что в результате неправильного ввода имени пользователя в скрипте, скрипт пытается войти под несуществующим пользователем. Особенно если количество таких событий чрезмерно велико. На практике встречалось, что вместо верного имени пользователя example@domain.com было введено заведомо неверное example@domain\com. Кроме того, такой код ошибки можно часто увидеть в событиях с именами типа example$ — это учетные записи хостов или сервисов и о них чуть позже.
События с кодом 0x17 обычно не указывают на, как таковую, брутфорс-атаку и с большой долей вероятности могут предшествовать событию 4723 An attempt was made to change an account's password — пользователь с истекшим паролем наверняка предпримет попытку его сменить.
Появление событий с кодом 0x18 возможно и довольно часто происходит после события о смене пароля, о котором говорили в предыдущем коде. Несмотря на смену истекшего пароля, некоторые сервисы могут продолжать использовать старый пароль с этой учетной записью и вызывать событие с кодом, уже означающим, что использованный пароль не просто истек, а неправильный. Кроме того, часто имеет место проблема «зависших» в кэше учетных данных — о ней также чуть позже. Важно не забывать, что, если в окружении нет события о смене пароля, стоит обратить более пристальное внимание на этот кейс и, возможно, подсветить проблему ответственным за инфраструктуру.
События с кодом 0x25 говорят о проблемах со временем на хосте, откуда происходит предварительная аутентификации и обычно связаны с тем, что время на хосте настроено неправильно, хост обращается к неверному NTP-серверу или, банально, что на рабочей станции разрядилась батарейка BIOS. Например, пользователь мог самостоятельно изменить время на своей рабочей станции так, что оно теперь сильно опережает или отстает от времени на Domain Controller (DC), и теперь испытывает трудности со входом именно по этой причине.
«Зависшие» кэшированные учетные данные
Кэшированные учетные данные позволяют компьютеру хранить хешированные значения паролей в локальном кэше, что обеспечивает возможность локальной аутентификации и входа в систему даже при отсутствии доступа к контроллеру домена. Однако поскольку кэшированные данные хранятся локально, они могут не всегда отражать текущее состояние учетной записи пользователя в Active Directory. Например, если пользователь изменил пароль, а кэшированные данные все еще содержат старый пароль, компьютер продолжит пытаться использовать устаревшие учетные данные для доступа к различным ресурсам. В таких случаях контроллер домена будет рассматривать эти попытки аутентификации как неудачные — это неизбежно приведет к появлению событий о неудачных попытках входа по причине «неверный пароль». Часто такие события могут приходить поочередно с сообщениями об успешном входе с других хостов.
Проблема с зависшими учетными данными достаточна распространена, так что на эту тему легко найти руководства по устранению таких неполадок.
Сервисные учетные записи
Отдельно стоит упомянуть учетные записи типа example$. Это учетные записи хостов или сервисов в домене AD. Они предназначаются не для прямого управления, а для запуска служб или приложений и часто могут иметь привилегированные права для доступа к системам, приложениям и данным. Часть имени УЗ до $ — обычно имя сервиса или хоста.
Появление событий, которые говорят о неуспешном входе в сервисные учетные записи как правило обуславливается такими проблемами:
«Выпадение» хоста из домена: хост испытывает проблемы, с тем чтобы снова войти в домен;
Неверная конфигурация и проблемы с настройками сервисов, например, некорректная привязка учетных записей;
Истекший или заблокированный аккаунт: сервисная учетная запись может быть устаревшей или заблокированной.
Важно отметить, что у таких учетных записей слишком сложный пароль — обычно они не будут подвержены «классическим» вариантам атаки подбором пароля.
Атаки на публичные сервисы
Часто в событиях входа можно увидеть, что источником запроса является не обычный пользовательский хост, а какой-либо сервис. Почему так может произойти?
В большинстве современных инфраструктур используется аутентификация Kerberos. Пользователь вводит данные для авторизации на сервисе, однако такой запрос выходит за пределы возможностей самого сервиса — он перенаправляет запрос на сервер DC, передавая учетные данные от своего имени, чтобы проверить их подлинность и получить необходимые билеты для данного пользователя. В результате DC сначала выдает TGT (Ticket Granting Ticket), а затем TGS (Ticket Granting Service) билеты. А пользователь получает доступ к сервису, например, почте.
Если в событиях указан IP-адрес или имя почтового сервера (или другого сервиса), это значит, что авторизация прошла через этот сервис, а не напрямую через контроллер домена.
В подавляющем большинстве случаев такие сервисы, как сервер Exchange, Jira и другие, доступны «извне» — это означает, что каждый, кто знает публичный адрес сервиса, может попытаться осуществить на них различные виды брутфорс-атаки. Важно понимать, что в таких условиях регулярные попытки брутфорс-атак неизбежны. Однако еще важнее осознавать, что эти попытки не должны вызывать чрезмерных опасений. Как показывает практика, такие ситуации обычно связаны с сравнительно небольшим количеством событий и чаще всего включают перебор по стандартному словарю. В стандартный словарь входят имена учетных записей типа root, admin, manager и подобные, которые практически невозможно встретить в современных корпоративных инфраструктурах. Если количество таких попыток чрезмерно велико, уже будет иметь смысл выявить IP-адрес источника запросов и заблокировать его на уровне Межсетевого Экрана (МЭ).
Однако такой подход абсолютно неприменим, если мы встретим, к примеру, тот же перебор по словарю, но от пользовательского хоста — это серьезный повод как можно скорее начать мероприятия по локализации и предотвращению.
Заключение
Несмотря на изначально кажущуюся простоту как исполнения, так и выявления брутфорс-атаки, важно не забывать, насколько серьезными могут быть последствия ее успешного проведения. Выявление всех ее форм требует комплексного подхода и внимания к множеству деталей, чтобы исключить ложные срабатывания и своевременно реагировать на реальные угрозы. А понимание базовых принципов вместе с учетом специфических особенностей вашей инфраструктуры позволит выстроить процесс защиты максимально эффективно.