Light mode

Когда надежды уже не осталось, или Что делать, если хакер обошел классические средства защиты

  • #Метапродукты

Чтобы понять, что такое метапродукты, нужно погрузиться в проблематику современного SOC. С разным приоритетом и степенью боли аналитики выделяют следующие сложности:

  • Комплексная защита требует множества консолей для разных классов продуктов. 
  • Для каждого класса средств защиты есть известные техники обхода. 
  • Большое количество срабатываний, в том числе false-positive, приводят к ошибкам в принятии решений (увы, человеческий фактор никто не отменял). 
  • Рутина не позволяет концентрироваться на важных задачах.  
  • И главное: современный SOC — это прежде всего люди и их компетенции, поэтому эффективность работы Центра напрямую зависит от конкретной команды.  

Также отметим, что этап обнаружения угроз — только вершина айсберга SOC. Каждый алерт требует валидации, следом за которой идут сбор контекста, сдерживание атаки и реагирование. Эффективность реагирования — вообще отдельная тема, ведь ошибки на данном этапе приводят к тому, что злоумышленники не просто остаются в инфраструктуре, но и начинают действовать более скрытно... 

В результате компаниям приходится набирать дефицитных и дорогих специалистов, которые значительную часть своего времени тонут в рутине. Они вынуждены смотреть в два миллиона консолей, разбираться с тысячами false-positive, рисовать в голове сложные связи и строить неочевидные таймлайны. И все это приходится проделывать много раз в день... 

Ответом на эти вызовы стали метапродукты. Они максимально автоматизируют рабочие процессы SOC: агрегируют в единой консоли срабатывания со всей инфраструктуры, помогают выстраивать недостающий контекст и предлагают эффективные сценарии реагирования.

Победить 7 злых бывших консолей

Начнем с техник обхода классических СЗИ. «Каждый класс продуктов можно обойти, способы давно известны», — что-то подобное обычно говорят про обход отдельного ИБ-решения в вакууме. А что если мы объединим несколько средств защиты и заставим их действовать сообща? 

Sandbox Bypass VS SIEM/EDR. Один из классических способов обхода песочниц — так называемые бесфайловые атаки (нет файла — нечего отправлять на анализ). Вариантов много: прописать полезную нагрузку в значение ключа реестра, создать запланированную задачу и т. д. Однако эти действия можно отследить в журналах ОС, то есть с помощью SIEM/EDR. Кроме того, вредонос может обнаружить, что находится в виртуальной среде, и отказаться выполняться. Тем не менее при попадании на пользовательскую машину он точно запустится, и мы сможем выявить это с помощью EDR и в логах.

Одно время были популярны вредоносы, написанные на Powershell. Но когда Microsoft научились логировать Powershell-скрипты (как весь текст, так и отдельно вызываемые командлеты), избежать обнаружения стало практически невозможно даже с обфускацией. Powershell уступил место малвари на .Net. Ждем логирования…

EDR Bypass VS SIEM. Для обхода EDR-решений часто применяется выгрузка драйвера самой EDR, драйвера Sysmon, либо злоупотребление его конфигурацией (например, когда атакующие используют ключи реестра, исключенные из логирования Sysmon). В этих случаях помогает стандартное логирование Windows, которое позволит человеку зафиксировать вредоносную активность и среагировать. 

И наоборот: при отключении любого системного логирования EDR-решение, которое может регистрировать собственные события безопасности, поможет аналитику SOC не остаться слепым. 

SIEM/EDR Bypass VS NTA. Если атакующим все же удалось отключить любую регистрацию событий на конечном узле, либо они вовсе заблокировали порт отправки событий в систему централизованного сбора журналов, то они смогут безнаказанно и незаметно делать что угодно в рамках захваченного узла. Но с точки зрения атакующего долго сидеть на одной машине бесполезно — нужно развивать атаку и искать полезные данные. При этом перемещение между узлами предполагает сетевое взаимодействие по известным протоколам, которые прекрасно разбирают NTA-системы. 

NTA Bypass VS SIEM/EDR. Избежать обнаружения в трафике можно с помощью собственных проприетарных протоколов. Этот способ не подходит для горизонтального перемещения внутри сети, но может сработать для маскировки С2-соединений, где атакующий сам настраивает принимающий сервер и учит его понимать проприетарщину. При этом появление нового сомнительного протокола в сети — уже хороший индикатор для аналитика. 

Остается шифровать трафик. Однако факт обращения к RPC, даже при использовании шифрованного SMBv3, регистрируется в событии 5145 на конечном узле и в журнале RPC, а запросы по LDAPS все еще логируются на контроллере домена в открытом виде. Также при горизонтальном перемещении на источник трафика могут срабатывать Endpoint-правила. 

SIEM Bypass VS AV/Sandbox: Мой любимый способ оставить аналитиков SIEM слепыми — маскировка под системные процессы. Например, под фоновую активность ОС или установку нового софта. Если повезет, можно по умолчанию попасть в списки исключений из правил обнаружения. Попробуйте переименовать mimikatz в vmtools.exe и посчитайте, в скольких SOC вы автоматически окажетесь в исключениях ;) 

По этому же принципу работает маскировка С2-фреймворков под браузеры, для которых генерация TLS-трафика — нормальная активность. Здесь на помощь приходит EDR/AV, который смотрит на содержимое файла и может идентифицировать CobaltStrike, даже если хакер назовет его googlechromeupdate.exe.

Один из классических способов обхода SIEM — разрыв цепочек процессов. Фишинг можно обнаружить, если дочерний процесс порожден от офисной программы: outlook.exe → winword.exe → powershell.exe → tmp_dhsfsfc.exe → … Но если макрос злоумышленника будет вызывать команды через WMI, произойдет разрыв цепочки, и все действия будут выполняться от процесса wmiprvse.exe, который никак не связан с winword.exe (wmiprvse.exe → powershell.exe → tmp_dhsfsfc.exe → …). В этом случае только EDR-решение поможет определить, что именно Winword обращался к WMI.

Игру в прятки можно продолжать долго, но приведенные примеры показывают, что попытку обхода одного ИБ-продукта легко задетектить с помощью другого. Если заставить разные классы решений работать вместе, не обнаружить атаку будет сложнее, чем обнаружить ее ;)

Именно поэтому специалисты SOC обрастают средствами для интеграции разных СЗИ. Одни пишут собственные скрипты, другие используют официальные инструменты (если речь о экосистеме продуктов одного вендора), третьи все-таки пытаются уследить за всеми консолями сразу. Метапродукты заметно упрощают решение этой задачи — они автоматически агрегируют информацию из разных ИБ-решений и выдают аналитику в удобном виде.

Если заставить разные классы продуктов работать вместе, не обнаружить атаку будет сложнее, чем обнаружить ее ;)

Место встречи изменить… можно? 

Все ИБ-продукты идут по пути «принимать решение по одному событию — неэффективно». Наиболее точные детекты достигаются за счет связывания нескольких действий в логическую последовательность. На это нацелены и корреляционные движки SIEM, и flowbits/xbits в трафике, связывающие активности из разных сессий. И даже сценарии в EDR: в определенной директории появляется файл — отправь его на сканирование, Yara-сканер дал вердикт о нелегитимности — удали файл. 

Беда в том, что собрать события в цепочку не всегда легко. К примеру, когда злоумышленник разносит атаку по времени (APT-like) или делает ее распределенной.

Не прокрастинатор, а APT

Рассмотрим вариант, когда хакер разносит атаку по времени (APT-like). Если он будет выполнять действия с интервалом больше, чем таймер у коррелятора, то останется вне радаров. Однако хакер не сможет разнести по времени выполнение одной команды (например, перечисление локальных пользователей) — мы сразу получим алерт.

В чем же тогда проблема? В том, что стандартный плейбук SOC при алерте — посмотреть все, что происходило вокруг. Аналитик увидит, что локальных пользователей перечислили, но не обнаружит подозрительных файлов и процессов ни до, ни после этого. Уже завтра об алерте забудут, как о закрытом False Positive, и вряд ли свяжут его с тем, что произойдет на узле через пару дней…

Чтобы эффективно обнаруживать подобные атаки, стоит опираться не на отдельные действия, а на сущности — процессы, файлы, ключи реестра и т. д. Пока жив процесс, который обеспечивает бек-коннект атакующим, не имеет значения, как часто он порождает дочерние процессы: раз в минуту или в неделю. Объединив их в единую сущность, мы увидим, что это связанные активности, сможем отследить четкую последовательность действий, вовремя принять решение об их нелегитимности и отреагировать. Аналогично с закреплением: пока в реестре жив ключ, в котором прописан вредоносный процесс, стартующий при запуске системы, мы можем объединять активности в одну цепочку, независимо от временных пауз и выдержки атакующих.

Рисунок 1. Разнесенные во времени действия связываются в цепочку.svg
Рисунок 1. Разнесенные во времени действия связываются в цепочку

В качестве примера приведу кейс из наших киберучений. Команда атакующих нашла на внешнем периметре инфраструктуры форму авторизации и решила перебрать пароли. Это был далеко не банальный Brute Force: не больше трех попыток для одного пользователя плюс смена IP-адреса через каждые семь попыток. Так или иначе, всегда найдется хотя бы одно «но». Парни забыли, что помимо IP нужно менять еще и User-Agent! Именно он стал сущностью, которая помогла нам связать воедино действия хакеров и вовремя заблокировать атаку. Что самое приятное, на это не нужно тратить тонну времени и сил — метапродукты автоматически решают подобные задачи в реальном времени ;)

Метапродукты позволяют составлять алгоритмы действий, которые помогают эффективно связывать отдельные события в логические цепочки. Например: 

отправляем подозрительный файл на сканирование в песочницу —> если файл вредоносный, передаем информацию в TI-решение —> SIEM получает данные о вредоносном хеше или C2-сервере —> автоматически выявляем IoC в инфраструктуре (в том числе ретроспективно).

Распределенные атаки 

Если длинные временные интервалы больше не являются проблемой для защитников, хакерам остается попробовать сделать атаку распределенной (нет, сейчас будет не про DDoS, хотя идея похожа). То есть построить ее так, что у разных действий не будет общих точек пересечения. 

Зачастую хакеры развивают атаку сразу из нескольких мест — присутствуют на двух-трех, а то и пяти машинах в разных сегментах инфраструктуры. В такой ситуации провести ниточки между их активностями будет непросто. Особенно если злоумышленники не используют общие С2-адреса, популярные инструменты и файлы с известной хеш-суммой — все то, что аналитик сразу побежит проверять как IoC. 

К счастью, детекты некоторых действий практически невозможно обойти, поэтому рано или поздно атакующим приходится жертвовать точками присутствия, чтобы раздобыть данные для продвижения к главной цели. При обнаружении подобной активности нужно искать и другие точки присутствия злоумышленников, а для этого особенно важно комбинировать возможности разных классов ИБ-продуктов. Для наглядности решим задачку: 

Дано: 

  • Хакер, который соорудил самописный туннель, назвал файл на каждом узле случайным образом и положил по случайному пути. Плюс арендовал в облаке 5 разных адресов. Нет, лучше даже в двух облаках! 
  • SIEM, который оперирует путями и названиями файлов, но не видит, что у них внутри, и не может сопоставить файлы с разных узлов. 
  • EDR, который может заглянуть внутрь файла, но не знает, что точно такой же файл есть на соседнем узле. 

Решение: 

Очевидно, по отдельности наши ИБ-продукты не справляются, значит нужно их подружить! Заставить говорить на одном языке, делиться информацией, делать выводы и отправлять их оператору SOC (желательно в рамках единого окна). Тогда вместо разрозненных сообщений из серии «В твоей инфраструктуре происходит что-то подозрительное, но это не точно…» специалист получит простой и понятный месседж «Из всего шума мы выбрали 50 алертов, они связаны, и это выглядит опасно!». 

Самый простой способ решить задачу интеграции СЗИ — передать ее метапродуктам ;)

Склейка, валидация, вердикт

В любом SOC есть правила обнаружения: 

  • Точные, которые со 100% вероятностью сообщают, что в инфраструктуре работает хакер. Обычно их легко обойти — это как служба BTOBTO в impacket smbexec. 
  • Общие, которые срабатывают на множество действий, в том числе легитимных. Их называют по-разному: контекстные, вспомогательные, дженерики и др. Обойти их практически невозможно, и иногда это единственный способ обнаружить продвинутую атаку. 

Почему же тогда хакеры остаются незамеченными? Потому что дженерики — это шумные и низкоприоритетные правила: чтобы аналитик обратил на них внимание, рядом должно произойти что-то более подозрительное. В качестве примера рассмотрим технику закрепления Default File Association Modify. Злоумышленник прописывает в реестре: если пользователь открывает .png-файл, вместо Paint нужно запустить полезную нагрузку. Оператор/EDR увидел корреляцию — при открытии файла .png запустится программа X, исполняемый файл которой был создан с помощью некого setup.exe. Пока X не запустится, мы не узнаем, хороший он или плохой. А запуститься программа может и через месяц, причем просто открыть сетевое соединение: само по себе это событие не сигнализирует об опасности. 

Кроме того, изменение ассоциации файловых расширений — распространенное действие при установке любого ПО. За сутки SOC фиксирует тысячи подобных срабатываний, и аналитик просто не может ждать запуска каждого файла, чтобы убедиться в его (не)легитимности. А если полезную нагрузку замаскировать под Adobe Acrobat, велика вероятность и вовсе попасть в исключения.

Мне очень откликается идея метапродуктов, потому что я, как аналитик, хорошо понимаю, что значит выполнять однотипные действия по плейбуку (делать это качественно больше 3-4 раз подряд просто невозможно). Особенно если алерты однотипные и похожи на системную активность... А программе не станет скучно, и она точно не забьет, а будет обрабатывать каждый алерт с должной тщательностью.

1 suspicious + 1 suspicious = 1 malicious

Представим, что аналитику поручили забирать и отрабатывать все низкоприоритетные срабатывания по плейбуку. Он должен понять, какой процесс изменил ключ реестра, откуда появился исполняемый файл, кем он был запущен и т. д. Дальше придется ждать и смотреть, будет ли происходить что-то плохое — неважно сколько, хоть целый месяц.

Рисунок 2. Сбор контекста для алерта_ запрос связанных событий до и после срабатывания.svg
Рисунок 2. Сбор контекста для алерта: запрос связанных событий до и после срабатывания

У большинства срабатываний не будет связи с другими низкоприоритетными алертами. Но на 1000 кейсов найдется один, где цепочка все-таки построится. Этого будет достаточно, чтобы поднять связанные алерты в статус «Требует внимания».

Рисунок 3. Сбор контекста позволяет связать алерты в один таймлайн, даже если между ними было несколько других действий.svg
Рисунок 3. Сбор контекста позволяет связать алерты в один таймлайн, даже если между ними было несколько других действий

Решать подобные задачи силами человека — жестоко и неэффективно, а вот использовать для репитативных действий алгоритмы — вполне естественно. В этом и заключается суть автоматизации, которую несут в SOC метапродукты. Машине все равно, собирать контекст один раз или тысячу раз в день, у нее не замыливается взгляд, нет лени и перерыва на обед. А еще предрассудков, что файл kb174346745.exe — это «по-любому что-то легитимное от Microsoft». 

Иногда аналитики говорят, что хакеру достаточно спалиться всего один раз, чтобы его обнаружили и выбили из инфраструктуры. На самом деле, нужно ЗАМЕТНО спалиться один раз, потому что попадание под общие правила редко приводит к немедленному обнаружению. Ситуация изменится, если любое срабатывание будет расследоваться с одинаковой тщательностью и скоростью. Для этого и нужны метапродукты: если хотя бы один сенсор заметит подозрительную активность, контекст будет автоматически собран, а алерт отработан на все 100%, независимо от приоритета. И не забывайте, что когда сенсоры внедрены правильно, обойти сразу все попросту не получится ;)

Ошибки склейки

При сборе активностей в цепочку важно не тащить туда все подряд. Слепленные без разбора действия принесут больше вреда, чем пользы, потому что аналитику все равно придется потратить кучу времени на их валидацию. Тем не менее большинство современных решений для автоматизации расследования и реагирования несут аналитику всю возможную информацию и оставляют решение за ним: что относится к атаке, а что нет. 

Берем классический пример с фишинговым письмом — сотрудник открыл файл и впустил злоумышленника в инфраструктуру. Параллельно с действиями хакера наш пользователь продолжает работать и генерировать события, на которые могут срабатывать правила корреляции или сигнатуры. При этом нельзя говорить о том, что после компрометации учетной записи вся ее активность — это активность хакера. И уже тем более не стоит собирать все действия этой учетной записи в цепочку, иначе после компрометации еще нескольких сотрудников вам придется привязать к атаке добрую половину инфраструктуры. 

Это справедливо и для других кейсов: инъекция в легитимный процесс или вход в существующую сессию тоже требуют отделения легитимной активности от хакерской. Чтобы не тратить на это время и силы специалистов SOC, метапродукты могут использовать продвинутые алгоритмы валидации и склейки. Например, связывание по нескольким неточным признакам: проверяется совпадение не только по учетной записи, но и по общим С2-серверам. Также можно использовать алгоритмы профилирования активности или поведенческий анализ. К примеру, если несколько независимых процессов в инфраструктуре начинают генерировать трафик во внешнюю сеть по протоколу, который ранее не встречался в инфраструктуре. 

Плюс метапродуктов в том, что сенсоры под ними превращаются в инструмент обнаружения. При этом можно использовать для принятия решений любую доступную информацию и технологии, к примеру, связку ML с классическими методами обнаружения атак. Что позволяет делать более интеллектуальную работу на уровне продукта, а не человека.

False-positive

Ни одному ИБ-решению пока не удалось свести количество false-positive к нулю, а значит, они могут ошибочно собирать легитимные действия пользователей в цепочки. Этот вопрос актуален для всех классических СЗИ, но что насчет метапродуктов? Пройдемся по основным проблемам, связанным с false-positive, и посмотрим на их решение. 

1. False-positive отнимают время аналитика на валидацию и внесение исключений в правила. 

Метапродукты автоматически обрабатывают алерты и могут оперативно переварить намного больше данных, чем человек. Следите за красотой мысли: получив информацию о срабатывании, система сама запрашивает окружающий контекст, который позволяет ей самостоятельно принять решение о TP/FP — вот и автовалидация, о которой все давно мечтали! Как результат, можно смело отказываться от классических механизмов вайтлистинга и избежать связанных с ними проблем. 

2. Валидация требует дополнительных компетенций и плейбуков.

Реализованные в метапродуктах механизмы сбора контекста позволяют перенести экспертизу по расследованию и валидации инцидентов на уровень СЗИ — по аналогии с правилами обнаружения атак. 

Это важно еще и в контексте реагирования. У каждой учетной записи в домене есть LDAP-атрибут Script-Path. Куда бы пользователь ни залогинился, на узле будет исполняться то, что прописано в этом атрибуте. Например, это может быть открытие обратного шелла, который даст хакеру доступ к узлу с возможностью исполнения кода от имени пользователя. Это малоизвестный, но довольно красивый способ закрепления и горизонтального перемещения. 

Аналитик SOC будет видеть подозрительные процессы и действия от имени пользователя в разных частях инфраструктуры. Корневым процессом будет userinit.exe, но если не знать, что закрепление можно искать и в атрибутах LDAP, можно сколько угодно убивать процессы и менять пароль пользователю — хакер будет снова и снова возвращаться в инфраструктуру. 

3. Частые false-positive не позволяют автоматически реагировать на действия атакующих. 

Это правда: нельзя удалять все запланированные задачи (или же атрибуты LDAP), основываясь только на самом факте их появления — возможно, это просто обновление браузера. Метапродукты принимают решение о важности алерта не на основании одного события, а учитывают совокупность действий (эффективный скоринг — наше все). Цепочка — это про развитие атаки, поэтому в ней всегда есть логическая последовательность: создание файла, запуск, закрепление, разведка, горизонтальное перемещение и т. д. У тех же административных скриптов, которые по кругу собирают данные доменных пользователей, такой последовательности не будет. Хотя они тоже генерируют много шума и собираются в цепочки, просто короткие и с низким скором. Чтобы разобраться в этом, человеку потребуется драгоценное время, а метапродукты решают подобные задачи автоматически.

Ложные шумы для привлечения внимания

Я была на множестве киберучений и могу с уверенностью сказать: не так страшны алерты, как их отсутствие. Смотришь в консоли, а там пусто — ни одной атаки. Подозрительно… Другое дело, когда на периметре мелькают невнятные попытки сканирования и подбора паролей: значит, периметр не прошли! Сидишь, радуешься, блокируешь облачные IP, а хакеры в этот момент незаметно уносят NTDS.dit. :)

Когда обойти сенсоры не получается, хакер может попробовать сместить ваше внимание на менее важные, но более шумные действия. Представим, что у него есть аналог ботнета: в какой-то момент в нескольких точках вашей инфраструктуры начинают шуметь правила. Что тогда? 

  • Человек может начать тонуть в алертах и просто не успеет их разобрать. Метапродукты же соберут весь шум в цепочки и быстро их обработают. 
  • Атакующему придется постараться, чтобы сгенерировать сложный и разнообразный шум, который продвинутые алгоритмы склейки не смогут собрать в единую цепочку (то есть задача сводится к разбору всего одного кейса). 
  • А если и удастся, сложные алгоритмы скоринга определят ту цепочку, в которой действительно есть продвижение хакера. 
  • Метапродукты предложат сценарий реагирования, который позволит одним кликом убить «ботнет» (а ведь на его на построение, вероятно, ушел не один месяц).
Рисунок 4. Как атакуемую инфраструктуру видят человек и ИБ-продукт.svg
Рисунок 4. Как атакуемую инфраструктуру видит человек и ИБ-продукт

Реагирование 

Наконец, поговорим о реагировании. В первую очередь нужно помнить о том, что сценарий реагирования действительно должен помочь остановить хакера (существует миллион примеров с невычищенным закреплением — неотозванные авторизационные сертификаты, SSH-ключи, токены и т. д.). Но при этом выстроенный сценарий не должен быть деструктивным. Этот вопрос особенно актуален для реагирования в автоматическом или полуавтоматическом режиме.

Когда мы только начинали работать со сценариями, у нас была теория: если учетная запись используется в атаке, на нее нужно реагировать, даже если мы не знаем, как и когда она была захвачена. Однажды атакующие повысили права на узле, мы это обнаружили и довольные собой предложили заблокировать NT AUTHORITY\SYSTEM. Начальник SOC сказал: «Я не уверен, что так вообще можно. А если и можно, то как-то страшно» :)

Изоляция зараженного пользовательского узла — стандарт плейбуков большинства SOC, но для важных инфраструктурных серверов нужно искать менее инвазивные способы. Их нельзя просто изолировать, поэтому мы вынуждены реагировать на конкретные файлы и процессы, но и здесь есть свои сложности. К примеру, хакер может заставить СЗИ думать, что системный процесс — это вредонос. Если мы его остановим, это приведет к BSOD. 

В дереве процессов обычно есть только их имена. Если не обращаться к EDR за дополнительными данными (как запущен процесс, от какой УЗ, какие у него метаданные и хеш-сумма), хакер сможет избежать обнаружения и реагирования, просто назвавшись svchost.exe. Также нужно учитывать инъекции в легитимные системные процессы — это поможет понять, удалять или не удалять исполняемые файлы «вредоносных» процессов. 

На удалении сущностей остановимся отдельно, ведь после любого реагирования наступает этап восстановления. Согласитесь, отвязать вредоносную групповую политику от всех OU куда приятнее, чем восстанавливать безвозвратно утраченные данные. Если у вас есть возможность изолировать/заблокировать/остановить, используйте ее — это всегда лучше удаления. Кроме того, в SOC часто встречаются исключения из реагирования: например, сервисные УЗ, из-под которых запущены важные для бизнес-процессов системы. Метапродукты должны учитывать подобные сценарии, чтобы не допустить остановки критичных сервисов и самоуничтожения средств защиты. 

Если с сущностями ОС все в целом понятно (для них есть известные сценарии подтверждения вредоносности), то со специфичным ПО, особенно самописным, все куда сложнее. Для таких кейсов пока невозможно построить эффективные и при этом не деструктивные сценарии. Здесь реагирование можно проводить только в полуавтоматическом режиме — валидация и финальное решение остаются за оператором SOC. 

Но даже в таких случаях метапродукты помогут остановить хакера еще на подступе к критичной системе — за счет автоматизированного сбора контекста, связывания срабатываний и построения сценария сдерживания атаки. При этом затраты на расследование будут незначительными по сравнению с ресурсами (временными и техническими), которые потребуются атакующим, чтобы незаметно продвигаться по инфраструктуре.

Метапродукты 

  • Заставляют разные классы ИБ-решений говорить на одном языке 
  • Превращают экспертизу по расследованию и реагированию в часть СЗИ 
  • Минимизируют ошибки, связанные с человеческим фактором 
  • Высвобождают ресурсы специалистов для решения сложных и творческих задач

Мы дěлаем Positive Research → для ИБ-экспертов, бизнеса и всех, кто интересуется ✽ {кибербезопасностью}