¿Hay alguna manera de averiguar quién cambió la contraseña para iniciar sesión?

11

Estoy tratando de averiguar quién cambió la contraseña para iniciar sesión en SQL Server 2008 R2.

Ya he verificado el seguimiento predeterminado, y no registra ese evento. La traza predeterminada incluirá estos eventos relacionados con la seguridad:

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

Además, busqué en la copia de seguridad del registro de transacciones para descubrirlo, pero no tuve suerte.

¿Hay alguna otra forma de averiguarlo?

Además, soy consciente de que un rastreo del lado del servidor ayudará, pero desafortunadamente en nuestro rastreo del lado del servidor, no incluimos el Audit Login Change Password Event.

El mejor artículo que encontré es de Aaron Bertrand: Seguimiento de cambios de contraseña de inicio de sesión en SQL Server

Kin Shah
fuente
2
Configuraría una de las sugerencias de Aaron, luego haría una copia de seguridad del hash de contraseña actual en algún lugar y luego volvería a cambiar la contraseña. Vea quién grita ... o si solo se cambia aleatoriamente, entonces tiene el rastro en su lugar para atraparlos.
Kenneth Fisher
No está del todo claro si la contraseña se cambió para obtener acceso o para evitar el acceso de otra persona. Solo digo eso porque alguien podría no gritar. Kin también podría no saber cuál era la contraseña original.
Aaron Bertrand
La contraseña original podría restablecerse usando el hash (pregúnteme cómo sé jaja), que debería estar en algún lugar del registro de transacciones.
Jon Seigel

Respuestas:

11

Mi artículo ayudará si lo configura con anticipación, pero no cuando el evento ocurrió en el pasado y no tenía ningún tipo de mecanismo de auditoría configurado.

Sin embargo, todavía hay esperanza. Digamos que hice esto:

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

Esta información se encuentra en el rastreo predeterminado en EventClass 104 (Audit Addlogin Event). Sin embargo, si cambio la contraseña usando cualquiera de estos métodos:

ALTER LOGIN flooberella WITH PASSWORD = N'y';

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

Estos eventos no son capturados por la traza predeterminada, por razones obvias de seguridad: no debería ser posible para cualquier persona con acceso a la traza predeterminada averiguar cuál es la contraseña de otra persona, ni quieren que sea fácil incluso descubrir que se ha cambiado una contraseña (al sondear la frecuencia de estos eventos, por ejemplo, puede revelar ciertas propiedades de su estrategia de seguridad).

Entonces, ¿qué más puedes hacer? Si bien esto se basa en la información que todavía está en el registro, y también se basa en el uso de un comando DBCC no documentado contra una base de datos del sistema (es posible que desee hacer una copia de seguridad del maestro y restaurarlo en otro lugar), puede obtener alguna información del registro de transacciones, p.ej:

DBCC LOG(master, 1);

Esto generará, para los dos comandos anteriores, filas con la siguiente información (parcial):

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

No parece mucho, pero ahora toma esa porción 0x de la descripción, y luego haz:

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

¡Pistola humeante! Esta es la persona responsable de ese evento.

Por supuesto, si usan la ALTER LOGINsintaxis para todas las operaciones (que deberían usar en lugar de sp_password), no puede distinguir entre alguien que cambia la base de datos predeterminada y alguien que cambia la contraseña. Tampoco puede decir (al menos eso puedo ver) qué inicio de sesión afectó, solo que esta persona cambió un inicio de sesión. Jon parece pensar que esta información también está en el registro, pero no pude encontrarla (a diferencia de la información de tiempo, que de alguna manera me desplacé más allá).


Puede haber diferentes respuestas para los usuarios contenidos en SQL Server 2012, aunque sospecho que los cambios de contraseña todavía se ofuscan de manera similar. Dejaré eso para una pregunta separada.

Aaron Bertrand
fuente
Creo que podría usar fn_dblog/ fn_dump_dblogcontra master(o una copia de él) para averiguar qué director se cambió, incluso si tiene que usarlo DBCC PAGE.
Jon Seigel
Busca LOP_XACT_BEGINel Transaction IDque encontraste. Contendrá la hora exacta y el SID del inicio de sesión que lo inició.
Remus Rusanu
@ Jon lo pensarías, pero la ID de página y la ID de ranura son NULAS.
Aaron Bertrand
Tiene que haber una manera para que SQL sepa cómo revertir la transacción ... tal vez simplemente no exponga esos valores en el TVF aunque estén realmente allí.
Jon Seigel
@Jon adelante, eche un vistazo DBCC LOG(master,3);(o el fn_dblog()equivalente) y vea si puede detectar algo que ayude a identificar el objetivo. Cuando lo hago BEGIN TRANSACTION; ALTER LOGIN..., obtengo información aún menos útil, que desaparece si retrocedo, y se convierte en lo anterior si me comprometo.
Aaron Bertrand
4

esto es más largo que un comentario, publicado como respuesta

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
fuente
1
@RemusRusanu Esto solo será útil si está preguntando directamente qué hay en el registro T, pero si intenta leer desde una copia de seguridad del registro T, los SID se cortarían. Además, cada vez que se llama a fn_dump_dblog, crea un nuevo planificador SQLOS oculto y hasta tres subprocesos, que nunca desaparecerán y nunca se reutilizarán.
Kin Shah
1

Puede utilizar el desencadenador DDL a nivel de servidor (tenga en cuenta que para este ejemplo debe tener habilitada y configurada la función de Correo electrónico de base de datos de 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 = '[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
fuente