Czy istnieje sposób, aby dowiedzieć się, kto zmienił hasło do logowania?

11

Próbuję dowiedzieć się, kto zmienił hasło do logowania w SQL Server 2008 R2.

Sprawdziłem już domyślny ślad - i nie rejestruje tego zdarzenia. Domyślny zapis obejmuje następujące zdarzenia związane z bezpieczeństwem:

/*
    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 
*/

Sprawdziłem również kopię zapasową dziennika transakcji, aby się tego dowiedzieć, ale bez powodzenia.

Czy jest jakiś inny sposób, aby się tego dowiedzieć?

Wiem również, że śledzenie po stronie serwera pomoże, ale niestety w naszym śledzeniu po stronie serwera nie uwzględniliśmy Audit Login Change Password Event.

Najlepszy artykuł, który znalazłem, pochodzi od Aarona Bertranda: Śledzenie zmian hasła logowania w SQL Server

Kin Shah
źródło
2
Skonfigurowałbym jedną z sugestii Aarona, a następnie utworzyłbym gdzieś kopię zapasową bieżącego hasła, a następnie zmieniłem hasło z powrotem. Zobacz, kto krzyczy .. lub jeśli jest on losowo zmieniany, masz ślad, aby go złapać.
Kenneth Fisher
Nie jest do końca jasne, czy hasło zostało zmienione, aby uzyskać dostęp lub uniemożliwić komuś dostęp. Po prostu stwierdzając to, ponieważ ktoś może nie krzyczeć. Kin może również nie wiedzieć, jakie było oryginalne hasło.
Aaron Bertrand
Oryginalne hasło można zresetować za pomocą skrótu (zapytaj, skąd wiem, haha), który powinien znajdować się gdzieś w dzienniku transakcji.
Jon Seigel

Odpowiedzi:

11

Mój artykuł pomoże, jeśli skonfigurujesz go z wyprzedzeniem, ale nie wtedy, gdy wydarzenie miało miejsce w przeszłości i nie miałeś skonfigurowanego żadnego mechanizmu kontroli.

Jednak wciąż jest nadzieja. Powiedzmy, że to zrobiłem:

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

Informacje te znajdują się w domyślnym zapisie w EventClass 104 (Audit Addlogin Event). Jeśli jednak zmienię hasło przy użyciu jednej z następujących metod:

ALTER LOGIN flooberella WITH PASSWORD = N'y';

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

Zdarzenia te nie są przechwytywane przez domyślny ślad, z oczywistych względów bezpieczeństwa - nikt nie powinien mieć dostępu do domyślnego śledzenia, aby dowiedzieć się, jakie jest hasło innej osoby, ani nie chce ułatwić, aby dowiedzieć się, że hasło zostało zmienione (na przykład sondowanie częstotliwości tych zdarzeń może ujawnić pewne właściwości strategii bezpieczeństwa).

Co jeszcze możesz zrobić? Chociaż polega to na tym, że informacje nadal znajdują się w dzienniku, a także na użyciu nieudokumentowanej komendy DBCC względem systemowej bazy danych (możesz wykonać kopię zapasową wzorca i przywrócić ją w innym miejscu), możesz uzyskać pewne informacje z dziennika transakcji, na przykład:

DBCC LOG(master, 1);

Spowoduje to, dla powyższych dwóch poleceń, wiersze z następującymi (częściowymi) informacjami:

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

Nie wydaje się to dużo, ale teraz weź tę część 0x opisu, a następnie wykonaj:

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

Palenie pistoletu! To osoba odpowiedzialna za to wydarzenie.

Oczywiście, jeśli używają ALTER LOGINskładni do wszystkich operacji (których powinni używać zamiast sp_password), nie można odróżnić osoby zmieniającej domyślną bazę danych od osoby zmieniającej hasło. Nie można też powiedzieć (przynajmniej to widzę), które zalogować to wpływ, tylko że ta osoba zmieniła się zalogować. Jon wydaje się myśleć, że ta informacja również znajduje się w dzienniku, ale nie udało mi się jej znaleźć (w przeciwieństwie do informacji o czasie, które jakoś przewinęłam w przeszłość).


W SQL Server 2012 mogą być różne odpowiedzi dla zamkniętych użytkowników - choć podejrzewam, że zmiany haseł są nadal zaciemniane w podobny sposób. Pozostawię to na osobne pytanie.

Aaron Bertrand
źródło
Myślę, że możesz użyć fn_dblog/ fn_dump_dblogprzeciwko master(lub jego kopii), aby dowiedzieć się, która zasada została zmieniona, nawet jeśli musisz użyć spelunk DBCC PAGE.
Jon Seigel
Poszukaj LOP_XACT_BEGINdla Transaction IDznalazłeś. Będzie zawierać dokładny czas i identyfikator SID loginu, który go uruchomił.
Remus Rusanu
@Jeżeli tak uważasz, ale identyfikator strony i identyfikator boksu mają wartość NULL.
Aaron Bertrand
Musi istnieć sposób, aby SQL wiedział, jak wycofać transakcję ... może po prostu nie ujawnia tych wartości w TVF, nawet jeśli faktycznie tam są.
Jon Seigel
@Jon śmiało, spójrz DBCC LOG(master,3);(lub fn_dblog()odpowiednik) i sprawdź, czy możesz dostrzec coś, co pomogłoby zidentyfikować cel. Kiedy to robię BEGIN TRANSACTION; ALTER LOGIN..., otrzymuję jeszcze mniej użyteczne informacje, które znikają, jeśli wycofam, i stają się powyższe, jeśli popełnię.
Aaron Bertrand
4

to jest dłuższe niż komentarz, publikowanie jako odpowiedź

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)
Remus Rusanu
źródło
1
@RemusRusanu Przyda się to tylko wtedy, gdy bezpośrednio pytasz, co jest w dzienniku T, ale jeśli spróbujesz odczytać z kopii zapasowej dziennika T, identyfikatory SID zostaną odcięte. Również przy każdym wywołaniu fn_dump_dblog tworzy nowy ukryty harmonogram SQLOS i maksymalnie trzy wątki, które nigdy nie znikną i nigdy nie zostaną ponownie użyte.
Kin Shah
1

Możesz użyć wyzwalacza DDL na poziomie serwera (zwróć uwagę, że w tym przykładzie musisz mieć włączoną i ustawioną funkcję SQL Server Database Mail):

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 = '[email protected]'
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
Ivan Stankovic
źródło