[SQL][問題處理]是誰偷改登入帳號的密碼 ?

[SQL][問題處理]是誰偷改登入帳號的密碼 ?

由於工作的關係,有些時候會遇到客戶的 SQL Server 主機有異常,需要協助去處理。一般來說,最讓我頭痛的不是 SQL Server 發生問題,而是遇到一些很奇葩的 MIS 人員,明明自己更改了設定卻又打死不承認。而最近遇到的一個狀況是,我們的系統會在 SQL Server 內建立一個登入者帳號,因此應用程式會使用該帳號登入資料庫去執行,但很特別的是在某個客戶端,時常發生該帳號的密碼被更改,造成系統無法登入,而客戶 MIS 又一值咬定他們沒有修改,是我們系統發生異常去更動的。因此前線的同事想找一個方法,來紀錄 SQL Server 登入帳號的變更。

 

基本上要來追查這個問題,就看您所使用的 SQL Server 版本,可以使用幾種不同的方法,其中最沒有限制的就是使用 SQL Trace,這個部份可以參考 MSDN 上的 sp_trace_setevent 的 Event 代號說明,可以看到透過 EventID 104 和 107 這兩組,就可以取得我們所需要的紀錄,因此我先利用 SQL Profile 匯出一個空的組態檔,再來做個修改。

   1: -- Create a Queue
   2: declare @rc int
   3: declare @TraceID int
   4: declare @maxfilesize bigint
   5: set @maxfilesize = 5 
   6:  
   7: exec @rc = sp_trace_create @TraceID output, 2, N'D:\Log\ChangeLogin', @maxfilesize, NULL , 20
   8: if (@rc != 0) goto error
   9:  
  10: -- Client side File and Table cannot be scripted
  11:  
  12: -- Set the events
  13: declare @on bit
  14: set @on = 1
  15:  
  16: -- Audit AddLogin Event
  17: EXEC sp_trace_setevent @TraceID, 104, 14, @on -- StartTime 
  18: EXEC sp_trace_setevent @TraceID, 104, 27, @on -- EventClass
  19: EXEC sp_trace_setevent @TraceID, 104, 21, @on -- EventSubClass 
  20: EXEC sp_trace_setevent @TraceID, 104, 34, @on -- ObjectName 
  21: EXEC sp_trace_setevent @TraceID, 104, 38, @on -- RoleName 
  22: EXEC sp_trace_setevent @TraceID, 104, 39, @on -- TargetUserName 
  23: EXEC sp_trace_setevent @TraceID, 104, 42, @on -- TargetLoginName
  24: EXEC sp_trace_setevent @TraceID, 104, 43, @on -- TargetLoginSid
  25:  
  26: EXEC sp_trace_setevent @TraceID, 104, 7, @on  -- NTDomainName
  27: EXEC sp_trace_setevent @TraceID, 104, 23, @on -- Success 
  28: EXEC sp_trace_setevent @TraceID, 104, 8, @on  -- HostName
  29: EXEC sp_trace_setevent @TraceID, 104, 64, @on -- SessionLoginName 
  30: EXEC sp_trace_setevent @TraceID, 104, 9, @on  -- ClientProcessID
  31: EXEC sp_trace_setevent @TraceID, 104, 41, @on -- LoginSid  
  32: EXEC sp_trace_setevent @TraceID, 104, 10, @on -- ApplicationName 
  33: EXEC sp_trace_setevent @TraceID, 104, 26, @on -- ServerName 
  34:  
  35: EXEC sp_trace_setevent @TraceID, 104, 11, @on -- LoginName  
  36: EXEC sp_trace_setevent @TraceID, 104, 4, @on  -- TransactionID
  37: EXEC sp_trace_setevent @TraceID, 104, 12, @on -- SPID 
  38: EXEC sp_trace_setevent @TraceID, 104, 28, @on -- ObjectType
  39: EXEC sp_trace_setevent @TraceID, 104, 6, @on -- NTUserName 
  40:  
  41: -- Audit Login Change Password Event
  42: EXEC sp_trace_setevent @TraceID, 107, 14, @on -- StartTime 
  43: EXEC sp_trace_setevent @TraceID, 107, 27, @on -- EventClass
  44: EXEC sp_trace_setevent @TraceID, 107, 21, @on -- EventSubClass 
  45: EXEC sp_trace_setevent @TraceID, 107, 34, @on -- ObjectName 
  46: EXEC sp_trace_setevent @TraceID, 107, 38, @on -- RoleName 
  47: EXEC sp_trace_setevent @TraceID, 107, 39, @on -- TargetUserName 
  48: EXEC sp_trace_setevent @TraceID, 107, 42, @on -- TargetLoginName
  49: EXEC sp_trace_setevent @TraceID, 107, 43, @on -- TargetLoginSid
  50:  
  51: EXEC sp_trace_setevent @TraceID, 107, 7, @on  -- NTDomainName
  52: EXEC sp_trace_setevent @TraceID, 107, 23, @on -- Success 
  53: EXEC sp_trace_setevent @TraceID, 107, 8, @on  -- HostName
  54: EXEC sp_trace_setevent @TraceID, 107, 64, @on -- SessionLoginName 
  55: EXEC sp_trace_setevent @TraceID, 107, 9, @on  -- ClientProcessID
  56: EXEC sp_trace_setevent @TraceID, 107, 41, @on -- LoginSid  
  57: EXEC sp_trace_setevent @TraceID, 107, 10, @on -- ApplicationName 
  58: EXEC sp_trace_setevent @TraceID, 107, 26, @on -- ServerName 
  59:  
  60: EXEC sp_trace_setevent @TraceID, 107, 11, @on -- LoginName  
  61: EXEC sp_trace_setevent @TraceID, 107, 4, @on  -- TransactionID
  62: EXEC sp_trace_setevent @TraceID, 107, 12, @on -- SPID 
  63: EXEC sp_trace_setevent @TraceID, 107, 28, @on -- ObjectType
  64: EXEC sp_trace_setevent @TraceID, 107, 6, @on -- NTUserName 
  65:  
  66: -- Set the trace status to start
  67: exec sp_trace_setstatus @TraceID, 1
  68:  
  69: -- display trace id for future references
  70: select TraceID=@TraceID
  71: goto finish
  72:  
  73: error: 
  74: select ErrorCode=@rc
  75:  
  76: finish: 
  77: go

 

主要是在第 17 ~ 64 的設定,這裡寫的比較多一點,正常來說如果只要知道發生時間和修改人員,是可以不用到這麼多資訊,但這裡我就一倂把主要會用到的全部整裡出來,因此在每個設定後面,我都有說明是記錄哪些資訊,有需要的人可以按照你的狀況去作調整,不一定要記錄到全部。

 

因此當我們使用這個 SQL Trace 去執行之後,我們可以透過 SSMS 去建立帳號、修改密碼、刪除帳號,再來查看 SQL Trace 內是否有相關的資訊,因此我們使用以下的指令來查看

   1: select 
   2:     StartTime,HostName,ApplicationName, EventClass,EventSubClass,Success,TargetLoginName
   3: from sys.fn_trace_gettable( 'D:\Log\ChangeLogin.trc',-1 )
   4: where EventClass in ( 104, 107 )

可以看到結果如下:

B01

 

可以參考 MSDN 內有篇 「Audit Login Change Password Event Class」的說明,EventClass = 104 EventSubClass=1 是建立帳號,EventClass = 107 EventSubClass=4 是密碼已重設,EventClass = 104 EventSubClass=2 是刪除帳號,因此看起來我們就可以透過 SQL Trace 來追蹤帳號的修改狀況了。但上述所提供的方式如果遇到關機,那可能就會失效了,因此這個部份可以參考另外一篇「設定長時間的 SQL Trace,避免因為關機和重新啟動造成中斷」,把這些設定寫成 Stored Procedure,再來配合「sp_procoption」讓開機就來執行,就不用擔心因為重開機導致沒有紀錄到的狀況了。

 

而在提供這個方式給同事的時候,有人問到說那 SQL Server 有一組 Default Trace ,是否在 Default Trace 內就有我們所要的資訊呢 ? 這個是一個蠻好玩的題目,關於這個部分我們可以用下面的指令來查看

   1: SELECT DISTINCT eventid, name 
   2: FROM  fn_trace_geteventinfo(1) a
   3: JOIN sys.trace_events b  ON a.eventid = b.trace_event_id 

 

從下面的結果中可以看出來, Default Trace 並不會去紀錄所有的事件,他主要是有記錄以下的 34 個事件,其中我們上面有提到的 EventID=104 關於帳號的新增和刪除,這個在 Default Trace 內是有記錄,但是Default Trace 並沒有 EventID=107 關於密碼修改的紀錄

image

 

因此 Default trace 提供的資訊並不足夠我們來使用,因此還是要自己去作紀錄會是比較保險的做法。而就如同我們一開始所談到的,配合不同的 SQL Server 版本,除了 SQL Trace 之外,我們還可以使用 DDL Trigger 或者是 Server Audit 來做記錄,關於這兩個的做法,我們就留到下次再來做說明了。