12 Kasım 2015

SNORT IDS (Saldırı Tespit Sistemi) Nedir?

Snort bir saldırı tespit sistemi olarak bilinir. Ancak yetenekli ellerde Snort bir ağ forensic aracı veya şüpheli durumların takip ve tespiti amacıyla çok etkili bir araç olarak kullanılabilir. Personel yetersizliği nedeniyle kurumların büyük çoğunluğu satın aldıkları ticari IDS veya IPS sistemlerini kullanırlar ve bu sistemlerin saldırı imzalarını güncellemekle yetinirler. Elbette bu güvenlik seviyesini artırır ama saldırı tespit süreci pek çok false positive üretmeye meyillidir. Ayrıca kurumlar kendi ihtiyaçlarına göre kuralları düzenleme ihtiyacındadırlar. Ancak yetkinlik ve/veya kullanılan aracın buna izin vermemesi IDS kaabiliyetini sınırlar.


Bu makale Snort’un resmi dokümantasyonunun yerine geçmez, ve Snort’un güncellemelerine de uyum sağlayamayabilir. Ancak kısa bir okumayla Snort’un neye benzediği ve fonksiyonalitesine ilişkin fikir sahibi olmak isteyenlere yönelik olarak yazılmıştır.

Snort üzerinde çalışmaya başlamadan hemen önce bir IDS operasyonunda en önemli ön bilginin temel TCP/IP bilgisi olduğunu belirtmeliyiz. Çünkü IDS kararlarını tamamen bu protokol kurallarına göre verir.

Snort Windows ve Linux platformlarını destekler. Kurulumu doğrudan derlenmiş kodlarla yapabileceğiniz gibi kaynak kodları derleyerek de yapabilirsiniz. Biz bir Ubuntu desktop sürümü üzerinde kaynak kodları derleyerek Snort’u kuracağız. Bu işlemin çok basit bir süreç olduğunu iddia edemem. Ama hatalarla boğuşma ve dokümantasyonu inceleme süreçlerinin sonunda büyük oranda sizin kontrolünüzde olan bir IDS sistemine sahip olabileceğinizi söyleyebilirim. Bunun bir sonraki aşaması da kaynak kodlara müdahale ederek çözümü daha da özelleştirmek olur.

Snort IDS görevini ağ paketlerini inceleyerek yapar. Bunu isterseniz bir ağ arayüzünü Snort ile dinleyerek isterseniz daha önce kaydedilmiş olan ağ paketlerini (pcap formatında) Snort’a okutarak yapabilirsiniz. Snort ayrıca Inline modu ile (yani routing işlemini de kendi üzerinden yaparak) bir IPS gibi de çalışabilir. Snort’un bir ağ üzerindeki olayları gözlemleyebilmesi için ağ üzerinde iletilen tüm paketleri gözlemleyebilmesi gerekir. Bunun için bir tap cihazı ile (iki switch arasındaki) trafiği kopyalayarak tap cihazının bir ayağına üzerinde Snort çalışan sunucumuzu bağlayabiliriz, ya da daha pratik (ama performans açısından sıkıntı oluşturabilecek) şekilde SPAN (Cisco) veya Monitor (HP) port gibi adlandırılan konfigürasyonları switch üzerinde gerçekleştirerek switch’in tüm portlarına gelen trafiğin bu port’a da kopyalanmasını ve bu port’a bağlı olan Snort sunucu arayüzünün tüm trafiği izlemesini sağlayabilirsiniz.

Snort alarmlarını çeşitli şekillerde üretebilir. Ancak Snort’un bir alarm motoru olduğunu unutmayın, üretilen alarmları ele almak için yine Snort uyumlu olarak geliştirilmiş olan açık kaynak kodlu bir projeyi kullanabilirsiniz veya ticari bir SIEM çözümünüzle entegre edebilirsiniz. Snort alarmları ekrana (konsola) yazabilir, bir dosyaya kaydedebilir veya syslog alt sistemine ileterek bu işletim sistemi altyapısını kullanabilir. Tüm önde gelen log yönetim sistemleri dosyaya yazılan ve syslog formatında üretilen logları işleyebilir ve alarm yönetim süreçlerinizi buradan sürdürebilirsiniz.

Snort üzerinde 3 basit demo gerçekleştireceğiz:

  • Ağ üzerindeki bir ICMP Echo Request (ping) aktivitesinin tespiti
  • www.btrisk.com sitesine erişmeye çalışan bilgisayarların tespiti
  • Port tarama aktivitesi tespiti

Bizim stratejimiz şu olacak:
  • Snort’u kaynak kodlarından kuracağız
  • Snort konfigürasyon dosyasını demo hedeflerimize göre düzenleyeceğiz
  • Snort kural dosyalarını demo hedeflerimize göre düzenleyeceğiz
  • Snort’u ağ arayüzümüzü dinleyecek ve alarmları konsola yazacak şekilde başlatacağız
  • Alarmları üretecek senaryoları işleterek Snort’un ürettiği sonuçları inceleyeceğiz

Daha önce de belirttiğim gibi kurulum ve diğer işlemler için en güncel bilgileri Snort’un resmi internet sitesinden bulabilirsiniz (www.snort.org). Burada belli bir zamanda ve ortamda bu işlemin nasıl gerçekleştirildiğinden bahsediyor olacağız.

Kurulumumuzu bir Ubuntu Desktop üzerinde gerçekleştireceğiz. Normalde Snort’un root hakları ile çalışmasını istemeyiz. Çünkü bu çözüm de bir yazılım ve ağ üzerinden gelen girdileri işlediği için hafıza taşma saldırılarına maruz kalabilir. Bu durumda sistemin hemen ele geçirilmesini istemeyiz. Ancak demo ortamımızı pratik bir şekilde oluşturabilmek için tüm işlemlerimizi root kullanıcısı olarak gerçekleştireceğiz.

Snort dokümantasyonunda linux’un sağladığı bazı imkanların iptal edilmesi öneriliyor. Bunlar performansı artırma amaçlı olarak belli bir oturumla ilgili paketlerin bir araya getirilmesini sağlıyor. Ancak bu Snort’un 1518 byte’lık paket sınırını aştığı için bazı olayların snort’un gözünden kaçmasına neden olabileceğinden istediğimiz bir durum değil. Bunun için aşağıdaki iki komutu işletmeliyiz:

# ethtool -K eth0 gro off
# ethtool -K eth0 lro off


Ne yazık ki ikinci komutumuz gerçekleşmedi. Demo amaçlarımızla çelişmediği için bu konunun üzerinde durmayacağım.

Komutları işletmeden önce “sudo su” komutunu işletirseniz “root” kullanıcısına geçiş yapabilirsiniz. Böylece bundan sonraki tüm komutların başına “sudo” komutunu eklemek zorunda kalmazsınız.

İkinci olarak Ubuntu güncelleme linklerini güncelleyelim ve kaynak koddan derleme işlemi öncesinde gerekli uygulamaları kuralım:

# apt-get update
# apt-get install -y build-essential
# apt-get install -y libpcap-dev libpcre3-dev libdumbnet-dev
# apt-get install -y bison flex
# apt-get install -y zlib1g-dev


Artık kaynak kodlarımızı derlemek için hazırız. Bunun için yeni bir dizin oluşturalım.

# mkdir snort_src
# cd snort_src


Snort’un son versiyonunu resmi internet sitesinden bularak indirebilirsiniz. Snort’un yanı sıra Snort tarafından kullanılan ağ kütüphanesi olan DAQ (Data Acquisition) kütüphanesini de indirmeliyiz.

# wget https://www.snort.org/downloads/snort/daq-2.0.6.tar.gz
# wget https://www.snort.org/downloads/snort/snort-2.9.7.6.tar.gz



Kurulumları gerçekleştirmek için tar arşivlerini indirdiğimiz dizin içinde sırasıyla aşağıdaki komutları çalıştıralım:

# tar -xvzf daq-2.0.6.tar.gz
# cd daq-2.0.6
# ./configure
# make
# make install


# cd ..
# tar -xvzf snort-2.9.7.6.tar.gz
# cd snort-2.9.7.6
# ./configure --enable-sourcefire
# make
# make install


Shared library’leri güncellemek için:

# ldconfig

ve snort çalıştırılabilir koduna /usr/snort/bin dizini altında bir sembolik link eklemek için:

# ln -s /usr/local/bin/snort /usr/sbin/snort


Snort kurulumumuzu kontrol etmek için aşağıdaki komutu çalıştırabiliriz:

# snort –V


Maalesef işimiz burada bitmedi. Daha konfigürasyon dosyaları için hazırlık yapmamız lazım. Yalnız bizim hazırlığımız yine oldukça sade ve sadece demo’ya yönelik olacak. Kurulum paketi ile birlikte gelen snort.conf dosyasına müdahalemiz sınırlı olacak, ama kural dosyalarının tamamına yakınını sileceğiz. Sadece bizim kullanacağımız kural dosyalarını oluşturacağız veya öntanımlı kural dosyalarından faydalanacağız.

Konfigürasyon dosyaları için aşağıdaki dizinleri oluşturuyoruz:

# mkdir /etc/snort
# mkdir /etc/snort/rules
# mkdir /etc/snort/preproc_rules


Ayrıca loglarımızı da saklayacak bir dizine ihtiyacımız olacak

# mkdir /var/log/snort


Kurulum dosyaları ile gelen şablon konfigürasyon dosyalarını yeni oluşturduğumuz snort dizinine kopyalayalım (aşağıdaki komutları aynen kullanmak isterseniz kaynak kod dizini içinde olduğunuzdan emin olunuz):

# cp ./etc/*.conf* /etc/snort
# cp ./etc/*.map /etc/snort


Şimdi snort.conf konfigürasyon dosyamızı amaçlarımıza uygun olarak düzenleyelim. Aşağıdaki işlemlerin yine belli bir versiyon için geçerli olduğunu belirtmeliyim, farklı bir versiyon için dokümantasyonu okumanız şart.

/etc/snort dizini altında kurulum paketinden aldığımız öntanımlı snort.conf dosyasını yerleştirmiştik. Bu dosyayı nano editörü ile açabiliriz:


Öncelikle RULE_PATH değişkenlerindeki dizin yapısını düzeltmemiz lazım (bir üst dizini gösteren .. yerine içinde bulunduğumuz dizini gösteren . karakterini bırakmamız lazım). Aslına bakarsanız demo çalışmamızda bunlardan sadece RULE_PATH ve PREPROC_RULE_PATH değişkenlerini kullanacağız.


Kural (rule) dosyalarından site specific rules (local.rules dosyası) dışındaki tüm include satırlarını siliyoruz. Normal bir kurulumda bunları kullanmak isteyebilirsiniz, ancak bu dosyaların her birinin içeriğine hakim olmanızı öneririm. Üretilen alarmın ne anlama geldiğini anlamadan bir olay müdahalesi yapamazsınız.

Nano editörü ile bir satırı Cut Text (Ctrl + K) komutu ile silebilirsiniz.

(include satırlarını silmeden önce)


(include satırlarını sildikten sonra)


Demomuzda göstermek istediğimiz konulardan birisi port tarama olaylarının Snort ile tespiti. Bu noktada Snort mimarisinden bahsetmemiz gerekiyor.


Snort kuralları paketler üzerinde çalışır. Ancak bazı güvenlik olayları tek bir pakete bakılarak tespit edilemez, örneğin port tarama olayı gibi. Port tarama işlemi pek çok paketin belli bir zaman aralığında ve belli sunuculara yönelik olarak gönderilmesi şeklinde gerçekleşir. Böyle bir durumu tespit etmek için özel bir işleme ihtiyaç vardır. Bu tür işlemler için preprocessor modülleri geliştirilmiştir. Preprocessor modülüne ihtiyaç olan başka bir tipik durum da fragmented paketlerin paket inceleme öncesinde birleştirilme ihtiyacıdır. Örneğin kuralımızın bir paketin içeriğinde “root” kelimesini aradığını düşünün. Eğer saldırgan paketi iki veya daha fazla parçaya fragment ederek “ro” harflerinin bir pakette, “ot” harflerinin ise bundan sonra gelecek bir pakette yer almasını sağlarsa Snort bu olayı tespit edemeyecektir. Bu nedenle Snort içinde yer alan bir preprocessor modülü (örneğin frag2 modülü) paketleri kurallar ile karşılaştırmadan önce parçalanmış olan paketleri birleştirme işlemini gerçekleştirdikten sonra detection engine’inin incelemesi için bir sonraki aşamaya geçirir. Preprocessor’ların gerekli olduğu bir başka durum da encode edilmiş verilerin decode edilmesi ihtiyacıdır. Örneğin kuralımız ASCII bir içerik ararken saldırgan paket içeriğini URL encoded olarak gönderirse kuralımız olayı tespit edemeyecektir. Bu tür verilerin decode edilmesi işlemi de preprocessor modülleri (örneğin HTTP_decode) tarafından gerçekleştirilir.

Demomuzda göstermeyi hedeflediğimiz durumlardan birisi de port tarama işleminin tespiti idi. Bunu gerçekleştirebilmek için “sfPortscan” preprocessor’ını kullanacağız. Bu modül daha sonra işlenebilmesi için port tarama işlemleri neticesinde özel bir paket oluşturur ve detection engine’inin işleyebilmesi için sonraki aşamaya geçirir. Bu tür durumlar için geliştirilen kurallar da normal kurallardan biraz farklıdır.

Öncelikle sfPortscan preprocessor’ının aktif olduğundan emin olalım:


Snort.conf konfigürasyon dosyasına göz attığımızda gördük ki sfPortscan preprocessor’ı aktif değil. Biz bu modülü kullanmak istediğimiz için snort.conf dosyasında comment işaretini kaldırarak bu özelliği aktif hale getireceğiz:


“snort.conf” konfigürasyon dosyamız içinde sfPortscan modülünün tespit edeceği olayların raporlanabilmesi için Preprocessor kurallarının tanımlandığı dosyanın (preprocessor.rules) include edilebilmesi için gerekli satırı da aktif hale getirmemiz lazım.


Snort.conf dosyamızın geri kalan kısmını şimdilik olduğu gibi bırakıyoruz. Snortu çalıştırmaya çalıştığımızda alacağımız hatalara göre tekrar elden geçireceğiz. Elbette gerçek bir kurulumda bu dosyadaki tüm ayarların üzerinden geçilmesi ve değerlendirilmesi lazım.

Yaptığımız değişiklikleri kaydetmek için Ctrl + X tuşlarına bastıktan sonra mevcut snort.conf ismi ile dosyayı saklayarak çıkabiliriz.


Şimdi sıra kurallarımızı belirlemekte.

Demomuzun amaçları için 2 adet kural dosyasına ihtiyacımız var:

  • $RULE_PATH/local.rules
  • $PREPROC_RULE_PATH/preprocessor.rules

Bunlardan local.rules dosyası içine sıfırdan kendimiz 2 kural tanımlayacağız. Preprocessor.rules için biraz kopya çekmeye ihtiyacımız var. Bunun için kurulum dosyası ile birlikte gelen preprocessor.rules dosyasını kopyalayacağız, ancak bunun içindeki sfPortscan modülünü ilgilendirmeyen tüm kuralları sileceğiz. Bu kural dosyalarının içine yerleştirileceği dizinleri daha önce oluşturmuştuk.

Kurallarımızı tanımlamadan önce sıradan bir kuralın ana bölümlerini açıklayalım.


Kuralın ilk bölümü aksiyonu belirtiyor. Yukarıda da görüldüğü üzere aksiyonlar alarm üretme ve loglama, sadece loglama, paketin geçişine izin verme ve başka hiçbirşey yapmama, snort IPS modunda çalıştığında paketin drop edilmesi ve loglanması ve dokümantasyonda bulunabilecek diğer aksiyonlar olabilir.

Protokol paketin protokolünü belirtmektedir. Kaynak ve hedef IP adresleri ve portları ile paketin yönü rahatlıkla anlaşılabilir.

Options bölümü ise pek çok parametre barındırabilir. Biz örneklerimizde sadece “content” özelliğini işleyeceğiz. Ancak bunun dışındaki pek çok parametre hakkında detaylı bilgi snort dokümantasyonunda bulunabilir.

Biz local.rules dosyamızın içine aşağıdaki kuralları tanımlayacağız.


ICMP protokolü için port kavramı bulunmamasına rağmen kural yapısına uygun olabilmek için port bölümünü de any olarak tanımlıyoruz.

Content option’ı paket veri alanında belirtilen veriyi arayan bir opsiyon. Yukarıdaki örnekte pipe (|) işareti ile ayrılan kısım (yani |03|) nokta karakterini temsil eden ASCII karakterinin hexadecimal karşılığır. Yukarıdaki ikinci kuralımız DNS isteklerinin içinde “btrisk.com” verisini arıyor. Eğer bulursa bunu “BTRisk DNS sorgusu” olarak raporluyor.

Sid, snort id, rev parametresi de revizyon numarası anlamında kullanılıyor.

Kurallarımızı tanımlamak için “/etc/snort/rules” dizini içinde “local.rules” dosyasını oluşturacağız ve kuralları yazacağız. “nano local.rules” komutu ile bu dosyayı açabiliriz.


Port tarama olaylarının tespiti için ise preprocessor kural şablon dosyasından faydalanacağız. sfPortscan preprocessor’ı için mevcut şablon kural dosyasında grup id’si 122 olan kurallar geçerli olacak. Diğer tüm kuralları dosyadan temizleyeceğiz.

Ancak öncelikle şablon dosyamızı kopyalayalım:


Mevcut şablon dosyamız aşağıdaki gibi olacaktır:


Burada gid: 122 dışındaki tüm kuralları temizleyeceğiz (nano içinde yine Ctrl + K işlemi ile satırları silebiliriz). Temizlemesek ne olur, aslında bize bir zararı olmaz, ancak bunu denerseniz aslında bir saldırı veya farklı olumsuz bir durum olmasa bile sistemlerin protokol kurallarına uyumsuzlukları nedeniyle anomali alarmlarının olduğunu görürsünüz. Bu nedenle bence snort kullanıcılarının en ince detayda kuralların anlamlarını, bunlara güvenlik ihtiyaçları dolayısıyla ihtiyaç olup olmadığını incelemeleri gerekiyor.

Gördüğünüz gibi sfPortscan preprocessor’ı pek çok farklı tarama türünü tespit edebiliyor ve ayırt edebiliyor.


Ayrıca buradaki kural tanımları yukarıdaki kural örneklerinden de farklılaşıyor. Olay tespitleri ise temel olarak options bölümündeki parametrelerle yapılıyor. Gördüğünüz gibi bu kuralları yazmak Snort hakkında çok detaylı ve derin bilgi sahibi olmadan mümkün değil. İşte bu yüzden şablon kurallardan faydalanmayı tercih ettik.

Nano’dan Ctrl + X tuşu ile çıkarak yaptığımız değişiklikleri saklıyoruz.

Artık snortu çalıştırmaya hazırız.

Snort’u aşağıdaki komutla çalıştıracağız:

# snort -A console -q -c /etc/snort/snort.conf -k none -i eth0

Bu komutla snort’a alarmları konsola yazmasını (-A console), “-q” switch’i ile snort’un açılış banner bilgilerini ekrana yazmamasını (yani sessiz – quiet olmasını), “-c” switch’i ve sonrasında gelen dosya adı ile hangi konfigürasyon dosyasını esas alması gerektiğini, “-i” seçeneği ile hangi ağ arayüzünü dinleyeceğini belirtiyoruz. “-k” seçeneği ise ancak dene ve yanıl yöntemi ile tespit edilebilecek bir ihtiyaç. Bu seçeneği kullanmadan önce eth0 interface’imizden dışarı doğru giden DNS sorgularını tespit edemiyorduk. Kısa bir araştırma sonrasında bunun snort’un interface’in dışına giden paketleri incelediği sırada paket checksum değerlerinin henüz hesaplanmamasından ve snort’un da checksum değeri doğru olmayan paketleri göz ardı etmesinden kaynaklandığını anladık. “-k” seçeneği ile snort’un checksum değerini kontrol etmemesini sağladık ve kuralımız çalışmaya başladı. Yani gördüğünüz gibi bu tür çözümlerde herşey güllük gülistanlık olmayabiliyor, aynı durum ticari ürünler için de geçerli elbette.


Maalesef Snort hata vererek sonlandı. Hatayı incelediğimizde snort.conf dosyasında tanımlı bir kural dosyasının bulunamadığını görüyoruz. Bu dosyanın bizim amaçlarımızla bir ilgisi olmadığı için bu satırı da snort.conf dosyasını nano ile açarak geçersiz hale getireceğim:

# nano /etc/snort/snort.conf

Ctrl + W ile “dynamicrules” kelimesini arayalım ve hataya neden olan satırın yerini bulalım ve satır başına “#” karakterini koyarak satırı geçersiz hale getirelim.


Şimdi snort’u tekrar başlatmayı deneyelim:


Bir başka hata daha, sanırım snort.conf dosyası içindeki tüm rule dosyalarını tekrar gözden geçirmemizde fayda var.


Snort.conf dosyasını incelediğimizde problemin “reputation” preprocessor’ından kaynaklandığını görebiliriz. Bu preprocessor’ın tanımının içinde white_list.rules ve black_list.rules dosya isimleri de geçiyor. Bu dosyalar da mevcut olmadığı için snort başlarken hata alıyoruz. Bu preprocessor’a da demo amacıyla yaptığımız çalışmada ihtiyaç olmayacak, bu nedenle reputation preprocessor’ının tanımlandığı alanın tamamını yukarıda gördüğünüz gibi comment haline getiriyoruz.

Tekrar snort’u başlatalım.


Nihayet snort aktif hale geldi. Artık kurallarımızı aktif hale getirecek olan senaryoları deneyelim.

Önce bir ICMP paketinin oluşmasına neden olacak “ping” komutunu çalıştıralım:


Örneğimizin niteliği gereği iki kuralımız da devreye girdi. www.btrisk.com adresine ping’lediğimizde önce www.btrisk.com alan adının DNS çözümlemesi yapıldığı için içinde btrisk.com geçen DNS sorgu kuralı devreye girdi. Bunun ardından da iletilen 2 ICMP echo request paketinin sonucu olarak 2 alarm daha görüldü.

Şimdi port tarama senaryomuzu işletelim. Bunun için öncelikle Ubuntu bilgisayarımızın eth0 arayüzünün IP adresini bulalım:


Benim ortamımda bu IP adresi 192.168.163.144

Şimdi Ubuntu sanal makinemin üzerinde çalıştığı Windows bilgisayarımdan bu IP adresine doğru standart bir nmap port taraması gerçekleştireceğim:


Bakalım Snort bu aktiviteyi tespit edebilmiş mi?


Evet, snort yaptığımız taramayı TCP Port scan olarak tespit etmiş.

Bu makaledeki amacımız snort’un ne olduğu ve hangi amaçlarla kullanılabileceği ile ilgili pratik ve kısa bir giriş yapmak idi. Eğer snort’un kurumsal ihtiyaçlarınıza bir çözüm sağlayabileceğini düşünüyorsanız bu ürünle çok içli dışlı olmak ve bolca okumak zorundasınız. Bu çabanızın karşılığını müthiş esnek ve tam ihtiyaçlarınıza uygun bir çözüm kullanarak alabilirsiniz.