Есть ли способ узнать, кто менял пароль для входа?

11

Я пытаюсь выяснить, кто изменил пароль для входа в SQL Server 2008 R2.

Я уже проверил трассировку по умолчанию - и она не регистрирует это событие. Трассировка по умолчанию будет включать эти связанные с безопасностью события:

/*
    Audit Add DB user event
    Audit Add login to server role event
    Audit Add Member to DB role event
    Audit Add Role event
    Audit Add login event
    Audit Backup/Restore event
    Audit Change Database owner
    Audit DBCC event
    Audit Database Scope GDR event (Grant, Deny, Revoke)
    Audit Login Change Property event
    Audit Login Failed
    Audit Login GDR event
    Audit Schema Object GDR event
    Audit Schema Object Take Ownership
    Audit Server Starts and Stops 
*/

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

Есть ли другой способ узнать это?

Кроме того, я знаю, что трассировка на стороне сервера поможет, но, к сожалению, в нашу трассировку на стороне сервера мы не включили Audit Login Change Password Event.

Лучшая статья, которую я нашел, от Аарона Бертрана: отслеживание изменений пароля входа в SQL Server

Кин Шах
источник
2
Я бы настроил одно из предложений Аарона, затем где-нибудь сделал бы резервную копию текущего хэша пароля и затем изменил пароль обратно. Посмотрите, кто кричит ... или, если он просто случайно изменен, у вас есть след, чтобы поймать их.
Кеннет Фишер
Не совсем ясно, был ли пароль изменен для получения доступа или для предотвращения доступа кого-либо другого. Просто констатирую это, потому что кто-то может не кричать. Кин также может не знать, какой был первоначальный пароль.
Аарон Бертран
Исходный пароль может быть сброшен с помощью хэша (спросите меня, откуда я знаю, ха-ха), который должен быть где-то в журнале транзакций.
Джон Зигель

Ответы:

11

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

Однако надежда все еще есть. Допустим, я сделал это:

CREATE LOGIN flooberella WITH PASSWORD = N'x', CHECK_POLICY = OFF;

Эта информация содержится в трассировке по умолчанию в EventClass 104 (Audit Addlogin Event). Однако, если я изменю пароль одним из следующих способов:

ALTER LOGIN flooberella WITH PASSWORD = N'y';

EXEC sp_password N'y', N'z', N'flooberella';

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

Так что еще можно сделать? Хотя это зависит от информации, которая все еще находится в журнале, а также от использования недокументированной команды DBCC для системной базы данных (вы можете создать резервную копию master и восстановить ее в другом месте), вы можете получить некоторую информацию из журнала транзакций, например:

DBCC LOG(master, 1);

Это даст для двух вышеупомянутых команд строки со следующей (частичной) информацией:

Current LSN             Description
======================  ======================================================================
000000f2:000001b8:0002  ALTER LOGIN;0x01050000000000051500000093a3bcd7a9f8fb1417ab13bce8030000
000000f2:000001b8:0004  Alter login change password;0x01050000000000 ... same sid as above ...

Не похоже много, но теперь возьмите ту часть описания 0x, а затем сделайте:

SELECT name FROM sys.server_principals
  WHERE sid = 0x01050000000000051500000093a3bcd7a9f8fb1417ab13bce8030000;

Дымящийся пистолет! Это человек, ответственный за это событие.

Конечно, если они используют ALTER LOGINсинтаксис для всех операций (которые они должны использовать вместо sp_password), вы не сможете различить того, кто меняет базу данных по умолчанию, и того, кто меняет пароль. Вы же не можете сказать (по крайней мере , что я могу видеть) , что войти в этот пострадавших, только что этот человек изменил на вход в систему . Джон, кажется, думает, что эта информация также есть в журнале, но мне не удалось ее найти (в отличие от информации о времени, которую я как-то прокручивал в прошлом).


В SQL Server 2012 могут быть разные ответы для отдельных пользователей - хотя я подозреваю, что смена пароля все еще запутывается подобными способами. Оставим это для отдельного вопроса.

Аарон Бертран
источник
Я думаю, что вы могли бы использовать fn_dblog/ fn_dump_dblogпротив master(или его копию), чтобы выяснить, какой принципал был изменен, даже если вы должны использовать spelunk DBCC PAGE.
Джон Зигель
Ищите LOP_XACT_BEGINдля Transaction IDвы нашли. Он будет содержать точное время и SID логина, который его запустил.
Ремус Русану
@ Может, ты так и думаешь, но идентификатор страницы и идентификатор слота равны NULL.
Аарон Бертран
У SQL должен быть способ узнать, как откатить транзакцию ... возможно, он просто не отображает эти значения в TVF, даже если они на самом деле есть.
Джон Зигель
@ Джон, продолжайте, посмотрите на DBCC LOG(master,3);(или fn_dblog()эквивалент) и посмотрите, сможете ли вы найти что-нибудь, что поможет идентифицировать цель. Когда я это делаю, BEGIN TRANSACTION; ALTER LOGIN...я получаю еще менее полезную информацию, которая исчезает при откате и становится выше при фиксации.
Аарон Бертран
4

это длиннее, чем комментарий, размещение как ответ

select top(10) 
    [Transaction ID], 
    [Begin Time], 
    [Transaction Name], 
    [Transaction SID],
    SUSER_SNAME([Transaction SID])
from fn_dblog(null, null)
where Operation = 'LOP_BEGIN_XACT';

Transaction ID Begin Time               Transaction Name                  Transaction SID
-------------- ------------------------ --------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0000:00002b12  2014/01/08 20:10:14:890  Event_Session_Startup             NULL
0000:00002b13  2014/01/08 20:10:15:027  DBMgr::StartupDB                  NULL
0000:00002b14  2014/01/08 20:10:15:513  AddGuestUserToTempdb              NULL
0000:00002b15  2014/01/08 20:10:15:537  DBMgr::StartupDB                  NULL
0000:00002b16  2014/01/08 20:10:15:537  DBMgr::StartupDB                  NULL
0000:00002b17  2014/01/08 20:10:15:537  DBMgr::StartupDB                  NULL
0000:00002b18  2014/01/08 20:10:15:540  DBMgr::StartupDB                  NULL
0000:00002b19  2014/01/08 20:10:15:550  DBMgr::StartupDB                  NULL
0000:00002b1a  2014/01/11 11:49:42:760  AutoCreateQPStats                 0x010500000000000515000000A065CF7E784B9B5FE77C877084B65600
0000:00002b1b  2014/01/11 11:53:26:620  test_ack                          0x010500000000000515000000A065CF7E784B9B5FE77C877084B65600

(10 row(s) affected)
Ремус Русану
источник
1
@RemusRusanu Это будет полезно только в том случае, если вы непосредственно запрашиваете что-либо в T-журнале, но если вы пытаетесь читать из резервной копии T-журнала, SID будет отключен. Также каждый раз, когда вызывается fn_dump_dblog, он создает новый скрытый планировщик SQLOS и до трех потоков, которые никогда не исчезнут и никогда не будут использоваться повторно.
Кин Шах
1

Вы можете использовать триггер DDL на уровне сервера (обратите внимание, что для этого примера у вас должна быть включена и настроена функция Почта базы данных SQL Server):

CREATE Trigger [Trg_TrackLoginManagement]
on ALL Server
for DDL_LOGIN_EVENTS
as
set nocount on
declare @data xml,
          @EventType varchar(100),
          @EventTime datetime,
          @ServerName varchar(100),
          @AffectedLoginName varchar(100),
          @WhoDidIt varchar(100),
          @EmailSubject varchar(500),
          @EmailBody varchar(800),
          @EmailRecipients varchar(300)
set @EmailRecipients = 'name@domain.com'
set @data = eventdata()
set @EventType = @data.value('(/EVENT_INSTANCE/EventType)[1]', 'varchar(100)')
set @EventTime = @data.value('(/EVENT_INSTANCE/PostTime)[1]','datetime')
set @ServerName = @data.value('(/EVENT_INSTANCE/ServerName)[1]','varchar(100)')
set @AffectedLoginName = @data.value('(/EVENT_INSTANCE/ObjectName)[1]','varchar(100)')
set @WhoDidIt = @data.value('(/EVENT_INSTANCE/LoginName)[1]','varchar(100)')

set @EmailSubject = 'ALERT: DDL_LOGIN_Event: ' + @EventType + ' occured by ' + @WhoDidIt + ' on ' + @ServerName

set @EmailBody =  'DDL_Login_Event: ' + @EventType + char(10) + 
                 'Event Occured at: ' + convert(Varchar, @EventTime) + char(10) + 
                 'ServerName: ' + @ServerName + char(10) +
                 'Affected Login Name:      ' + @AffectedLoginName + char(10) + 
                 'Event Done by: ' + @WhoDidIt
EXEC msdb.dbo.sp_send_dbmail
    @recipients = @EmailRecipients,
    @body = @EmailBody,
    @subject = @EmailSubject ;
GO
Иван Станкович
источник