Bu yazımızda Logon trigger lar ile SQL Server’a bizim iznimiz dışında herhangi bir bilgisayardan kullanıcı adı şifre bilinse bile (SA kullanıcısı dahil) girilmesini engelleme uygulaması yapacağız.
Burada bir izin verilen bilgisayar listemiz var ve bunlar bir tabloda tutuluyor. Biz bu listenin dışında herhangi bi client dan login olma işlemi geldiğinde şunları yapabiliriz.
1.Kayıt altına alabiliriz.
2.Kayıt altına alıp anında sistem yöneticisine mail attırabiliriz.
3.Login olmasını engelleyebiliriz.
İşte bütün bu işlemleri yapmak için Logon Trigger yazmamız gerekiyor.
Trigger ları normalde tabloların altında insert,update,delete işlemleri için kullanırız. Ancak pek az bilinse de SQL Server 2008 sürümünden bu yana hem ddl trigger lar hem de logon trigger lar mevcut. Bu trigger lar sayesinde bir çok brut force atağın önüne kolaylıkla geçilebilir.
Böylece Kullanıcı adı, şifre, port önlemlerinin üstüne bir de client adı kontrolü ile ekstra bir koruma sağlamış oluyoruz.
Şimdi bu işlemi adım adım nasıl yaptığımızı anlatalım.
1.Öncelikle sisteme Audit isimli bir database oluşturalım. Bu database bizim loğları tutacağımız ve izin verilen bilgisayarları tanımlayacağımız yer.
2.Bu database in içine AuditLog isimli bir tablo oluşturalım.
CREATE TABLE [dbo].[AUDITLOG](
[SESIONID] [INT] NULL,
[LOGONTIME] [DATETIME] NOT NULL,
[NET_TRANSPORT] [VARCHAR](250) NOT NULL,
[PROTOCOL_TYPE] [VARCHAR](250) NULL,
[AUTH_TYPE] [VARCHAR](250) NOT NULL,
[NET_PACKETSIZE] [INT] NULL,
[CLIENT_NETADDRESS] [VARCHAR](250) NULL,
[PROGRAM_NAME] [VARCHAR](250) NOT NULL,
[HOSTNAME] [VARCHAR](250) NOT NULL,
[NT_USERNAME] [VARCHAR](250) NOT NULL,
[NET_LIBRARY] [VARCHAR](250) NOT NULL,
[NT_DOMAIN] [VARCHAR](250) NOT NULL
) ON [PRIMARY]
Burada gördüğümüz üzere
SESIONID: SQl Server a bağlanan kullanıcının id si.
LOGONTIME: Sisteme login olmaya çalıştığı zaman
NET_TRANSPORT: TCP , Shared Memory, Named Pipes gibi protokollerden hangisini kullandığı
PROTOCOL_TYPE: SQL Server ile konuşma dili (TSQL)
AUTH_TYPE: Authentication türü (NTLM,SQL)
NET_PACKETSIZE: Network paketi boyutu (4096,8000….)
CLIENT_NETADDRESS: Bağlanan kullanıcının Ethernet ya da IP Adresi
PROGRAM_NAME: SQL e bağlantı kurulmaya çalışılan uygulama (Management studio…)
HOSTNAME: Bağlanan kullanıcının bilgisayarının adı
NT_USERNAME: Bağlanan kullanıcının Windows kullanıcısının adı
NET_LIBRARY: Network kütüphanesi (TCP/IP, LPC…)
NT_DOMAIN:Kullanıcı domaini
3.Hangi bilgisayarlara izin vereceğimizi tutmak adına ALLOWEDHOST isimli bir tablo oluşturalım ve altına kendi bilgisayarımızı ekleyelim ki bağlanmamıza izin versin.
CREATE TABLE ALLOWEDHOST (HOSTNAME VARCHAR(200))
INSERT INTO ALLOWEDHOST (HOSTNAME) VALUES (‘OMERLENOVO’)
4.Şimdi trigger ımızı yazıyoruz. Trigger aşağıdaki gibi. Kodların ne işe yaradığını yorum satırlarında yazdım.
CREATE TRIGGER [connection_AUDIT] –TRIIGER ADI
ON ALL SERVER — BÜTÜN DATABASE LER İÇİN GEÇERLİ
FOR LOGON –LOGON İŞLEMİ SIRASINDA ÇALIŞACAK
AS
BEGIN
DECLARE @HOSTNAME AS VARCHAR(200) –KULLANICININ HOST BİLGİSİNİ ALMAK İÇİN DEĞİŞKEN TANIMLIYORUZ
SELECT @HOSTNAME=HOST_NAME() –HOST_NAME() FONKSİYONU CLIENT MAKİNENİN ADINI VERİR
IF NOT EXISTS (SELECT * FROM AUDIT.DBO.ALLOWEDHOST WHERE HOSTNAME=@HOSTNAME)
–EĞER KULLANICI BİLGİSAYARI BİZİM İZİN VERDİĞİMİZ LİSTEDE YOK İSE
–master.sys.dm_exec_connections VE master.dbo.sysprocesses SİSTEM VIEWLARINI KULLANARAK İHTİYACIMIZ OLAN BİLGİLERİ
–ALIYORUZ VE AUDITLOG TABLOSUNA INSERT EDIYORUZ.
BEGIN
INSERT INTO AUDIT.DBO.AUDITLOG (SESIONID, LOGONTIME, NET_TRANSPORT, PROTOCOL_TYPE, AUTH_TYPE, NET_PACKETSIZE, CLIENT_NETADDRESS,
PROGRAM_NAME, HOSTNAME, NT_USERNAME, NET_LIBRARY, NT_DOMAIN)
select
cnn.session_id SESIONID,cnn.connect_time LOGONTIME,cnn.net_transport NET_TRANSPORT,
cnn.protocol_type PROTOCOL_TYPE,
cnn.auth_scheme AUTH_TYPE,
cnn.net_packet_size NET_PACKETSIZE,
cnn.client_net_address CLIENT_NETADDRESS,
prc.program_name PROGRAM_NAME,
hostname HOSTNAME,
nt_username NT_USERNAME,
net_library NET_LIBRARY,nt_domain NT_DOMAIN
from master.sys.dm_exec_connections cnn
inner join master.dbo.sysprocesses prc
on prc.spid = cnn.session_id
WHERE PRC.spid=@@SPID
END
END
5.Management studioda Server Objects kısmında yazdığımız trigger ı görebiliriz.
6.Şimdi sisteme Login olalım.
Sistem girmeye izin verdi. Çünkü girdiğim makinenin adı OMERLENOVO ve bu isim ALLOWEDHOST tablosunda mevcut.
7.Kendi bilgisayarımızın adını izin verilen bilgisayarlar listesinden çıkaralım. Bunun için OMERLENOVO yazan yeri OMERLENOVO1 diye değiştiriyorum.
8.Şimdi yeni bir ekrandan bağlanmaya çalışıyorum.
Gördüğümüz gibi sisteme yine login olduk.
9.Log tablomuza bakalım.
OMERLENOVO makinesinden login olma işlemi kayıt altına alındı. Çünkü bu makine ALLOWEDHOST tablosunda yok ve yabancı bir makine. Burada otomatik olarak çalıştıracağımız bir job ile sistem yöneticisine bu durumu mail de attırabiliriz.
10.Eğer biz belirli bilgisayarlar dışında hiçbir bilgisayarın sisteme girememesini istiyorsak bu kez ROLLBACK yaparak bunu sağlayabiliriz.
ALTER TRIGGER [connection_AUDIT] –TRIIGER ADI
ON ALL SERVER — BÜTÜN DATABASE LER İÇİN GEÇERLİ
FOR LOGON –LOGON İŞLEMİ SIRASINDA ÇALIŞACAK
AS
BEGIN
DECLARE @HOSTNAME AS VARCHAR(200) –KULLANICININ HOST BİLGİSİNİ ALMAK İÇİN DEĞİŞKEN TANIMLIYORUZ
SELECT @HOSTNAME=HOST_NAME() –HOST_NAME() FONKSİYONU CLIENT MAKİNENİN ADINI VERİR
IF NOT EXISTS (SELECT * FROM AUDIT.DBO.ALLOWEDHOST WHERE HOSTNAME=@HOSTNAME)
–EĞER KULLANICI BİLGİSAYARI BİZİM İZİN VERDİĞİMİZ LİSTEDE YOK İSE DOĞRUDAN ROLLBACK YAPIYORUZ
ROLLBACK
END
11.Şimdi sisteme login olmaya çalışalım. (Bu kısım tehlikeli yeni bir management studio açalım çünkü bir daha hiç giremeyebiliriz.
Görüldüğü üzere sisteme girmeye izin vermedi.
12.Şimdi ALLOWEDHOST tablosunu OMERLENOVO1 yazan yeri OMERLENOVO olarak tekrar düzeltelim.
Tekrar girmeyi denediğimizde görüldüğü gibi giriş yapabiliyoruz.
Sonuç:
Eğer SQL Server sistemine bir saldırı olma ihtimali üzerine önlem alıyorsak,
Diyelim ki portları kontrol ettik,
Kullanıcı adı ve şifreleri kompleks yaptık
Ancak kullanıcı adı ve şifre birinin eline geçebilir ve bizim networkümüze başka bir bilgisayar da dahil olabilir.
Ya da yabancı bir bilgisayar brut force yaparak şifre denemesinde bulunabilir.
Bunun önüne geçmek adına LOGON triggerlar hem izleme hem de engelleme noktasında oldukça faydalı.
Son olarak bu denemeleri dikkatli yapmak gerekir. Ziraz kendi kendimizi engelleyebilirizJ. Siz siz olun bu işlemleri yapmadan önce master.mdf ve mastlog.ldf dosyalarını yedekleyin. Olur ki kendi kendinizi engellersiniz yapacağınız tek şey bu master database ine ait dosyaların eskisine dönmek.