9.04.2015

Log Parser Studio (LPS)

Çok sevdiğim bir araç vardı: Log Parser. Her türlü log formatını okuyabilen, SQL sorguları ile logların üzerinde işlem yapılmasını sağlayan Microsoft aracı olan Log Parser, artık Log Parser Studio (LPS) olarak görsel bir arayüze kavuştu.

LPS'nin babası olan Log Parser, Exchange Server geliştiricileri tarafından logların incelenmesi amacıyla tasarlanmış bir araç. LPS de bu amaçla büyük işler başarıyor. Ama bununla sınırlı değil. Web server logları, Windows Evet Log'ları hatta başka log formatlarını kolayca okuyabiliyor. Dahası grafikler çizebiliyor.


Varsayılan olarak üzerinde bir çok örnek sorgu ile geliyor. Tek yapmak gereken logları nereden okuyacağını seçmek. Örnek olarak Exchange protokol loglarını (RECEIVE) incelemekle başlayalım. Server üzerinden ilgili loglara ister doğrudan erişebilir, istersek de bu dosyaları sabit diskinizin içindeki bir klasöre kopyalayıp devam edebiliriz. D:\Logs klasörüne kopyaladığımızı düşünelim. Araç çubuğundaki Log butonuna (soldan 5. buton) basarak loglarımızın yerini gösterelim.


Arından yeni bir sorgu yaratma butonuna (en soldaki) basarak pencerenin alt bölümündeki sorgu ekranına şu satırları yazarak başlayalım:
SELECT *
FROM '[LOGFILEPATH]'
WHERE (context LIKE '%LogonDenied%')
Bu şekilde SMTP receive logları üzerinden gelen yanlış kullanıcı adı / parola hatasına sebep olan LogonDenied kayıtlarına ulaşabiliriz. Log tipini seçmeyi unttum. Bunun için de sorgu ekranının hemen üzerinde kalan Log Type bölümünden EELLOG'u seçmek gerek. İstenirse SELECT * yerine daha net alanlar belirtilebilir. Örneğin şöyle bir sorgu sonuçları güzel oluyor:

SELECT ADD(TO_TIMESTAMP(EXTRACT_PREFIX([#Fields: date-time],0,'.'),'yyyy-MM-ddTHH:mm:ss'),SYSTEM_UTCOFFSET()) AS LocalDateTime,
session-id, connector-id, [sequence-number] AS SeqNum, [remote-endpoint] AS RemoteIP, event, data, context FROM '[LOGFILEPATH]'
WHERE (context LIKE 'User Name:%')
Burada SELECT'ten sonra gelen ilk alanda log satırındaki tarih ve saat alanı uygun TIMESTAMP'e çevrilip yerel saate göre ayarlanıyor.

Başka bir örnek olarak WEB sunucu üzerindeki muhtemel SQL injection denemeleri görülebilir:

SELECT TO_TIMESTAMP(date,time) as DateTime, cs-uri-stem as page, cs-uri-query as query, c-ip as RemoteIP, sc-status as StatCode, cs(User-Agent) as UserAgent
FROM '[LOGFILEPATH]'
WHERE ((query LIKE '%--%') or (query LIKE '%@@%') or (query LIKE '%version%') or (query LIKE '%exec%') or (query LIKE '%declare%') or (query LIKE '%cast%') or (query LIKE '%select%') or (query LIKE '%union%') or (query LIKE '%update%')) and (StatCode=200)
ORDER BY DateTime ASC
Burada adres satırıından gönderilen bazı anahtar kelimelerin varlığı denetleniyor. Bu tam bir SQL injection varlığı belirlemesi olmayabilir, ama yine de faydalı bilgiler verir.

Ve en sevdiklerimden biri, domain controller'lar üzerinde oluşan account lockout olaylarının takibi için Security log'da 4625 (hatalı kullanıcı adı/parola) ve 4740 (lockout) olayları aranıyor.
SELECT TOP 100 TimeGenerated, EventID, ComputerName,
EXTRACT_TOKEN(Strings,0,'|') AS Field_0,
EXTRACT_TOKEN(Strings,1,'|') AS Field_1,
EXTRACT_TOKEN(Strings,4,'|') AS Field_4,
EXTRACT_TOKEN(Strings,5,'|') AS Field_5,
EXTRACT_TOKEN(Strings,19,'|') AS Field_19
FROM \\server1\security,\\server2\security
WHERE (EventID=4740 OR EventID=4625)
ORDER BY TimeGenerated DESC
Bu sorgu için Log Type kısmından EVTLOG seçilmeli. Burada FROM'dan sonra '[LOGFILEPATH]' yazmaya gerek yok. Field_0'dan Field_19'a kadar olan alanlar 4625 ve 4740 olayları için önemli olabilecek bazı alanlar içeriyor. Buradaki Field_0'dan Field_26'ya kadar olan alanların nelere denk geldiği bilgisini, event viewer'ı açıp, detail view'a geçip görebiliriz. Field_0 -> SubjectUserSid'den başlıyor, Field_26 -> ElevatedToken'a kadar gidiyor.

Son olarak bir de FileZilla FTP server logları için olan sorgusu var. FileZilla FTP Server nedense garip bir log formatı seçmiş. Örneğin satırlar şöyle:

(000233) 19.09.2014 23:01:14 - (not logged in) (xxx.xxx.xxx.xxx)> Connected, sending welcome message...
(000233) 19.09.2014 23:01:14 - (not logged in) (xxx.xxx.xxx.xxx)> disconnected.
(000234) 19.09.2014 23:01:22 - (not logged in) (xxx.xxx.xxx.xxx)> Connected, sending welcome message...
(000234) 19.09.2014 23:01:24 - (not logged in) (xxx.xxx.xxx.xxx)> USER zxin10
(000234) 19.09.2014 23:01:24 - (not logged in) (xxx.xxx.xxx.xxx)> 331 Password required for zxin10
(000235) 19.09.2014 23:01:25 - loggedinuser (xxx.xxx.xxx.xxx)> 200 Type set to I
(000235) 19.09.2014 23:01:25 - loggedinuser (xxx.xxx.xxx.xxx)> TYPE A
(000234) 19.09.2014 23:01:26 - (not logged in) (xxx.xxx.xxx.xxx)> QUIT
(000234) 19.09.2014 23:01:26 - (not logged in) (xxx.xxx.xxx.xxx)> 221 Goodbye
(000234) 19.09.2014 23:01:26 - (not logged in) (xxx.xxx.xxx.xxx)> disconnected.

Log dosyaları günlük olarak tutuluyor. Bu durumda yukarıdaki veriyi bir CSV (virgülle ayrılmış değerler) dosyasına yazmak için şu sorgu kullanılabilir:

SELECT SUBSTR(EXTRACT_TOKEN(Text,0,' - '),1,6) as order,
TO_TIMESTAMP(SUBSTR(EXTRACT_TOKEN(Text,0,' - '),9),'dd.MM.yyyy HH:mm:ss') as datetime,
EXTRACT_TOKEN(EXTRACT_TOKEN(EXTRACT_TOKEN(Text,1,' - '),0,'> '),0,' (') as user,
REPLACE_STR(EXTRACT_TOKEN(EXTRACT_TOKEN(EXTRACT_TOKEN(Text,1,' - '),0,'> '),1,' ('),')','') as ip,
EXTRACT_TOKEN(EXTRACT_TOKEN(Text,1,' - '),1,'> ') as message
INTO 'D:\Log\Filezilla.csv'
FROM '[LOGFILEPATH]'

EXTRACT_TOKEN() ve diğer fonksiyonlar hakkında yardım için şu sayfadan yararlanılabilir. Sayfa aslında Log Parser Plus için, ama LPS'ye de uygulanabilir.

Alanın değerinin belli bir liste içinde olup olmadığını kontrol etmek için IN operatörü kullanılabilir. Bundan sonra parantez içinde noktalı virgüllerle ayrılmış değerler girmek lazım. Örneğin belli session-id değerleri içinde sadece MAIL FROM 'ları görmek için

SELECT * FROM '\\exchange\logpath\ex*.log'
WHERE (session-id IN ('asdfasdf';'qwerqwer';'wertwert';...)) AND (data LIKE 'MAIL FROM%')


Yetenekleri bununla kısıtlı değil. Biraz yaratıcılık, biraz da  deneme yanılmayla herşey mümkün.

15.07.2016 ekleme:
Log Parser Studio'nun bir sürü klavye kısayolu varmış; yeni keşfediyorum. Örneğin her seferinde FROM'dan sonra gelecek ve ayarlanmış log dosyası konumunu belirten '[LOGFILEPATH]' yazmak yerine F7 tuşuna basabilir ve eğer sonuçları bir CSV dosyası olarak export etmek isterseniz F8'e basabilir ve '[OUTFILEPATH]\Output.CSV' ekleyebilirsiniz. Klavye kısayollarının tam listesi için şu sayfa çok faydalı olabilir diye düşünüyordum ama sayfanı sonuna kadar okuyunca farkettim ki aslında Ctrl+K kombinasyonu klavye kısayolları sayfasını görüntülüyormuş :)