|
|
|
|
Apache için ModSecurity Kullanıcı Kılavuzu
ModSecurity, web uygulamaları için açık kaynak kodlu saldırı tespit ve önleme motorudur (engine). ModSecurity aynı zamanda web uygulama güvenlik duvarı olarak da adlandırılabilir. ModSecurity web sunucunun içine gömülmüş bir şekilde, güçlü bir şemsiye gibi davranarak uygulamaları saldırılardan korumaya çalışır.
ModSecurity web saldırıları ile başa çıkma gücünüzü arttırarak web sunucu ile bütünleşir. Bahsetmeye değer bazı özellikleri:
· İstek filtreleme; gelen istekler, web sunucusu veya diğer başka bir modül tarafından alınmadan önce, anında analiz edilir. (Daha kesin olarak, ModSecurity’e ulaşmadan önce istekler üzerinde bazı işlemeler yapılır ama bu gömülü olarak çalışmanın gerekliliğindendir.)
· Anti-atlatma teknikleri: yollar (paths) ve parametreler, atlatma teknikleri ile savaşmak için analiz edilmeden önce normalize edilirler.
· HTTP protokolü; motor HTTP’den anladığı için, çok spesifik ve detaylı seviyede filtreleme yapar. Örnek olarak, bireysel parametrelere veya isimli cookie değerlerine bakmak mümkündür.
· POST veri analizi; ModSecurity motoru (engine) POST metodu kullanılarak gönderilen içerikleri de yakalar.
· Denetleme kaydı; her istekğin (POST dahil olmak üzere) bütün detayları sonradan adli analiz için kullanılabilir.
· HTTPS filtreleme; motor web sunucusuna gömüldüğü için, veriye şifre çözme işlemi uygulandıktan sonra erişir.
· Sıkıştırılmış içerik filtreleme; yukarıdaki gibi, motor, istek verisine şifre çözme işlemi uygulandıktan sonra erişir.
ModSecurity saldırıları saptamada veya önlemede kullanılabilir.
ModSecurity iki lisans altında kullanılabilir. Kullanıcılar, Açık Kaynak Kodlu / Bedava Yazılım ürünü olarak GNU General Public License (http://www.gnu.org/licenses/gpl.html) gerekleri altında yazılımı kullanmayı tercih edebilirler. Alternatif olarak: bireysel veya site-boyu üretim için son kullanıcı lisansları, uygulamalar, web sunucuları veya güvenlik araçları ile kapalı kaynak dağıtımı için OEM ticari lisansları kullanılabilir. Ticari lisanslar ile alakalı daha fazla bilgi için lütfen Thinking Stone ile bağlantıya geçin.
Bu modül, Apache web sunucusunu üreten ve Apache modül programlamayı öğrendiğim, saatlerini Apache modüllerini yapmak için harcayan güzel insanlar olmasaydı mümkün olmazdı.
ModSecurity, Ivan Ristic ve Thinking Stone tarafından geliştirilmiştir. Yorumlar ve özellik isteklerinizi iletebilirsiniz. Lütfen e-maillerinizi <ivanr@webkreator.com>’a yollayın.
Not
Lütfen destek isteklerinizi kişisel e-mail adresime yollamayın. Destek isteklerini cevaplamaya zaman harcıyorum ama artık özel olarak yanıtlamıyorum. Çünkü bu diğer kullanıcıların cevapları bulmak için mail arşivlerini kullanmalarını engelliyor. Eğer cevaplara çabucak ihtiyacınız varsa veya garantili cevap zamanlarına ihtiyacınız varsa Thinking Stone’dan ticari destek almayı düşünün.
Kuruluma başlamadan önce, tercih ettiğiniz kurulum metodunu seçmeniz gerekecektir. İlk olarak, CVS’ten ModSecurity’nin en yeni versiyonunu (en iyi özelliklerle ama daha kararsız) mu kuracağınızı veya en son kararlı dağıtımı mı kullanacağınızı seçmeniz gerekir. Eğer bir kararlı dağıtım seçerseniz, ModSecurity’i ikiliden (binary) kurmanız mümkün olabilir. Yine de her zaman kaynak kodundan derlemeniz mümkündür.
Aşağıdaki bir kaç sayfa, bir metodu diğerine seçmenizdeki avantajları hakkında size bilgiler verecek.
Eğer modülün en son verisyonuna erişmek istiyorsanız, CVS deposundan almanız gerekir. En son kararlı dağıtımından sonra yapılan değişiklikler listesi genellikle web sitesinden (ve CHANGES adlı dosyadan) ulaşılabilir. ModSecurity için CVS deposunu SourceForge (http://www.sf.net/) sunar. Direk olarak veya kullanıyorsanız webden şu adresi kullanarak ulaşabilirsiniz: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mod-security/
Bilgisayarınıza kaynak kodunu indirmek için aşağıdaki iki komutu çalıştırmanız gerekir:
$ cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/mod-security login
$ cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/mod-security \
> co mod_security
İlk satır sizin anonim kullanıcı olarak girişinizi sağlayacak, ve ikinci depodaki bütün mevcut dosyaları indirecektir.
Eğer CVS’i istemiyor ama hala en yeni sürümü istiyorsanız, gecelik tarball’ı aşağıdaki adresten indirilebilirsiniz:
http://www.modsecurity.org/download/snapshot/mod_security-snapshot.tar.gz
Yeni özellikler mod_security’e, her yeni değişiklikten sonra doğrulama testleri uygulanarak bir bir eklenir. Bu, CVS’teki her sürümün her zaman kullanılabilir olmasını sağlar.
Sabit (Stable) Dağıtım İndirme
Sabit (kararlı) dağıtımları indirmek için http://www.modsecurity.org/download/ adresine gidin. İkili (binary) dağıtımlar her zaman hazır değildir. Eğer hazırsa, indirme sayfasında listelenirler. Eğer hazır değilse, kaynak kodu dağıtımını indirin.
Kaynaktan kurarken iki seçeneğiniz vardır: modülü web sunucusuna kurmak, mod_security.c’yi dinamik paylaşılan nesnesine (DSO) derlemek.
DSO olarak kurmak daha kolaydır, ve prosedür bütün Apache dalları için aynıdır. İlk olarak, dağıtımı bir yere açın (her hangi bir yer olur), ve modülle beraber derleyin:
# /apachehome/bin/apxs -cia mod_security.c
Bundan sonra Apache’yi durdurup ve başlatmanız gerekir (Eğer yeniden başlatmaya (restart) çalışırsanız bir segfault alabilirsiniz).
# /apachehome/bin/apachectl stop
# /apachehome/bin/apachectl start
Not
apxs aracının kurulu olmadığı platformlar hakkında insanlardan şikayet e-postaları almıştım. Bazı Unix dağıtımlarında bu araç (apxs) ayrı bir pakette dağıtılmaktadır. Problem bu paketin kurulum ile gelmediğinde ortaya çıkmaktadır. Bu problemi çözmek için sağlayıcınızın verdiği ve kendi özel yapım modülünüzü nasıl ekleyeceğinizi açıklayan dokümanını okuyun. (Bazı RedHat platformlarında apxs aracına erişmek için http-devel paketini kurmanızı gerekir.)
Apache 1.x ile Statik Kurulum
Bir modül statik olarak derlendiğinde, web sunucunun gövdesine gömülür. Bu metod bir miktar daha hızlı bir çalıştırılabilir (executable) üretir ama derleme metodu (ve daha sonra yönetimi) biraz daha karmaşıktır.
$ cd <apache1-source>
$ cp <modsecurity-source>/apache1/mod_security.c ./src/modules/extra
$ ./configure \
> --activate-module=src/modules/extra/mod_security \
> --enable-module=security
Normal olarak yaptığınız gibi web sunucusunu derleyin, kurun ve başlatın.
Apache 2.x ile Statik Kurulum
Apache 2.x ile statik derleme için tek yapmanız gereken modülün kaynak kodunu Apache kaynak kodu ağacına kopyalamanız ve Apache’i yeniden yapılandırmanızdır:
$ cd <apache2-source>
$ cp <modsecurity-source>/apache2/mod_security.c ./modules/proxy
$ ./configure \
> -enable-security \
> --with-module=proxy:mod_security.c
Apache 2.x Kurulumuna Entegre Etmek
mod_security’i Apache 2.x kurulumuna entegre etmeyi seçebilirsiniz.
$ cd <modsecurity-source>/apache2
$ mkdir -r <apache2-source>/modules/security
$ cp mod_security.c Makefile.in config.m4 <apache2-source>/modules/security
$ cd <apache2-source>
$ ./buildconf
Bu noktadan sonra mod_security, Apache’iye kurulum ile beraber gelen diğer modüller gibi görünecektir ama varsayılı olarak (by default) derlenmeyecektir. Çalışır duruma getirmek için aşağıdakileri uygulayın:
$ ./configure --enable-security
İkiliden (binary) Kurulum
Bazı durumlarda, modülü ikili (binary) olarak kurmak isteyeceksinizdir. Şu an itibariyle indirmek için sadece Windows ikililerini bulunduruyorum. İkiliden kurarken, dağıtımda büyük ihtimalle her iki Apache dalına ait iki DSO kütüphanesine sahip olacaksınız. Kullandığınız sürüm için uygun olanı seçin. Sonra aşağıdaki gibi devam edin:
mod_security.so (Unix için) veya mod_security.dll (Windows için) dosyalarını libexec/ dizinine (bu dizin Apache kurulumuna bağıldır, kaynak ağacına değil) kopyalayın. Daha sonra httpd.conf dosyasına aşağıdaki satırı ekleyin.
LoadModule security_module libexec/mod_security.so
Hali hazırdaki yapılandırmanıza bağlı olarak (modül yükleme sırasını açık olarak belirtmiş olabilirsiniz) AddModule direktifi ile modülü kullanmayı aktive etmeniz gerekebilir.
Çoğu durumunda satırı nereye eklediğiniz önemlidir. mod_security’i modül zincirinde son olarak çalıştırmanız önerilir (ve aslında dahili chroot özelliğini kullanmayı amaçlıyorsanız bu adım gereklidir). Daha fazla bilgi için “chroot desteği için gerekli modül sıralaması (Apache 1.x)” bölümünü okuyun.
mod_security.so (Unix için) veya mod_security.dll (Windows için) dosyalarını modules/ dizinine (bu dizin Apache kurulumuna bağıldır, kaynak ağacına değil) kopyalayın. Daha sonra httpd.conf dosyasına aşağıdaki satırı ekleyin.
LoadModule security_module modules/mod_security.so
ModSecurity yapılandırma direktifleri yapılandırma dosyanıza (tipik olarak httpd.conf) direk olarak eklenir. Web sunucu çalışmaya başladığında, modülün çalışıp çalışmayacağının belli olmadığı (modülün var olup olmadığı) durumlarda geleneksel olarak modülün yapılandırma direktifleri <IfModule> kap etiketlerinin (container tag) içine eklenir. Bu Apache’nin, modül aktif olmadığı zamanlarda yapılandırma direktiflerini görmezden gelmesini sağlar.
<IfModule mod_security.c>
# mod_security configuration directives
# ...
</IfModule>
Apache, yapılandırma verilerinin birden fazla dosyada bulunmasına izin verdiği için ModSecurity yapılandırma direktiflerini tek bir dosyada (mesela modsecurity.conf) gruplamak ve httpd.conf ‘dan Include direktifi ile içermek mümkündür.
Include conf/modsecurity.conf
Varsayılı olarak filtreleme motoru kapalıdır. İstekleri gözlemek için aşağıdakini yapılandırma dosyanıza ekleyin:
Bu parametre için desteklenen parametre değerleri:
· On - her isteği analiz et
· Off - hiçbirşey yapma
· DynamicOnly - Sadece yürütme esnasında dinamik olarak üretilen istekleri analiz et. Bu seçeneği kullanarak web sunucunuzun değerli CPU çevrimlerini (cycle) statik dosyalar için gönderilen istekleri kontrol etmek için harcamasına engel olabilirsiniz. ModSecurity’nin, bir isteğin dinamik olarak üretilip üretilmediğine nasıl karar verdiğini anlamak için "Neyin kaydedileceğini seçme" bölümünü okuyun.
İstek gövde verisi (veya POST verisi) tarama özelliği varsayılı olarak (by default) kapalıdır. Kullanmak için açmanız gerekir:
mod_security, istek gövdesi için iki kodlama tipini destekler:
· application/x-www-form-urlencoded - form verisini iletmek için kullanılır
· multipart/form-data - dosya iletmek için kullanılır
Diğer kodlamalar çoğu web uygulamaları tarafından kullanılmazlar. Sadece bu kodlama tiplerinin web sunucusu tarafından kabul edilmesini sağlamak için aşağıdaki satırı yapılandırma dosyanıza ekleyin:
SecFilterSelective HTTP_Content-Type \
"!(^$|^application/x-www-form-urlencoded$|^multipart/form-data;)"
Tamponlamayı (Buffering) dinamik olarak durdurma
İstek bazında POST verisi tarama özelliğini kapatmak mümkündür. Eğer ModSecurity, MODSEC_NOPOSTBUFFERING çevre değişkeninin tanımlı olduğunu görürse POST veri taramasını yapmayacaktır. Mesela, karşıdan dosya yüklemeleri için POST veri tamponlama özelliğini kapatmak için aşağıdakini kullanın:
SetEnvIfNoCase Content-Type \
"^multipart/form-data;" "MODSEC_NOPOSTBUFFERING=Do not buffer file uploads"
Neden tamponlamanın kapatıldığını açıklamak için MODSEC_NOPOSTBUFFERING değişkenine atanan değer, hata ayıklama (debug) kaydına yazılacaktır.
ModSecurity’i dinamik olarak kontrol etme
İstek bazında ModSecurity’i açmak veya kapatmak da mümkündür. Bu da MODSEC_ENABLE çevre değişkeni ve SetEnvIf ve SetEnvIfNoCase direktifleri ile mümkündür. Eğer MODSEC_ENABLE tanımlı değilse SecFilterEngine ile belirlenen yapılandırma kullanılacaktır. Eğer MODSEC_ENABLE tanımlı ise SecFilterEngine direktifinin değeri görmezden gelinecektir. MODSEC_ENABLE değerler aynı SecFilterEngine direktifindeki gibidir: On, Off, veya DynamicOnly.
Bölünmüş transfer (Chunked transfer) kodlama
HTTP protokolü, veri boyutunun önceden bilinmediği hallerde kullanılan bir istek transfer metodunu destekler. İsteğin gövdesi (body) parçalar halinde ulaştırılır. Ve metodun ismi (bölünmüş transfer kodlama) de buradan gelir. ModSecurity şimdilik parçalanmış transfer isteklerini desteklemez; parçalanmış kodlama kullanılan bir istek yapıldığında isteğin gövdesini (body) görmezden gelir. Apache bu kodlama metodunu desteklese de çoğu modül (mesela, Apache 1.3.x PHP modülü) desteklemez.
Açık bırakıldığında bu metod saldırgana kötü amaçlı verileri gizleyerek yollama imkanı tanır. Saldırganların bu zayıflığı gerçeklemelerini önlemek için aşağıdaki satırı yapılandırma dosyanıza ekleyin:
SecFilterSelective HTTP_Transfer-Encoding "!^$"
Bu durum, parçalanmış (bölünmüş) transfer kodlama kullanma yoluyla cevap yollama kabiliyetinizi etkilemez.
Varsayılı (Default) İşlem Listesi
Ne zaman bir kural bir istekle eşleşse, bir veya daha fazla işlem uygulanır. Bireysel filtreler kendi işlemlerini içerebilir ama bütün filtreler için varsayılı bir işlem kümesi tanımlamak daha kolaydır. (İsterseniz her kural için işlem de koyabilirsiniz.) Varsayılı işlemleri SecFilterDefaultAction direktifi ile tanımlarsınız. Mesela, aşağıdaki satır, motoru her kural eşleşmesinde kayıt tutacak ve isteği 404 durum kodu ile reddecek şekilde yapılandıracaktır.
SecFilterDefaultAction "deny,log,status:404"
SecFilterDefaultAction direktifi sadece bir parametre kabul eder; virgül işaretiyle ayrılmış işlemler. Burada tanımladığınız işlemler, kendi işlemleri olan kurallar hariç, her filtre eşleşmesinde kullanılacaktır.
Not
1.8.6’dan itibaren, eğer hayati olmayan (non-fatal) varsayılı işlem listesi (istekleri reddetmeyen bir liste, mesela log,pass) tanımlarsanız böyle bir işlem listesi ilklendirme (initialization) safhasında görmezden gelinecektir. İlklendirme safhası istek hakkında bilgi edinmek için dizayn edilmiştir. Hayati olmayan işlemlere izin vermek, isteğin bazı bölümlerinin kaybolmasına neden olacaktır. Bu bilgiler dahili süreç için gerekli olacağından bu tür işlemler kabul edilemez. Eğer ModSecurity’nin “sadece algıla” modunda çalışmasını istiyorsanız bütün örtülü denetlemeleri kapatmalısınız (URL kodlama denetlemesi, Evrensel kod -Unicode- kodlama denetlemesi, cookie format denetlemesi, ve bayt aralığı kısıtlaması).
Not
Bazı işlemler varsayılı listede bulunamaz. Bunlar; id, rev, skipnext, chain, chained.
1.8.6. ile birlikte örtülü istek denetimi (yapılandırıldığı takdirde) sadece istek işleminin başlangıcında yapılacaktır. Örtülü denetim istek satırına ve başlıklarına yapılacak kontrollerden oluşur.
Not
1.9dev4 ile beraber evrensel kod denetimi ilk örtülü istek denetiminin parçası olduğunda Referer başlığına uygulanmaz. Bunun nedeni, bu başlığın çoğunlukla diğer web sitelerinden bilgiler içermesidir, ve bu sitelerdeki kodlamanın korunan sitenin kodlamasından farklı olmasıdır.
Üst dizinlerde tanımlanan filtreler normal olarak içiçe yazılan Apache yapılandırma kapsamı tarafından kalıtılırlar. Bu davranış çoğu durumda kabul edilebilir (ve bazen gereklidir), ama her zaman değil. Bazen bu kontrolleri sitenin bazı bölümlerinde gevşetmek gerekir. SecFilterInheritance direktifi kullanılarak:
ModSecurity’e üst filtrelerini görmezden gelmesini ve kurallara yeni baştan başlamasını söyleyebilirsiniz. Bu direktif sadece kuralları etkiler. Yapılandırma, her zaman üst kapsamdan kalıtılır ama bunu uygun yapılandırma direktiflerini kullanarak istediğiniz gibi değiştirebilirsiniz.
Not
Yapılandırma ve kural kalıtımı varsayılı olarak (by default) her zaman açıktır. Eğer kalıtım özelliği kapatılan kapsam altında alt kapsamınız varsa ve eğer bu alt kapsamda da kalıtımı kapatmak istiyorsanız kalıtımı tekrar doğrudan, direktif yardımı ile, kapatmanız gerekecektir.
Üst kapsamdan gelen kuralları kalıtım yoluyla almak istemiyorsanız, yeni kapsam için yeni kurallar yazabilirsiniz veya basitçe Include direktifini kullanarak aynı kuralları diğer bir çok kapsama dahil edebilirsiniz.
Bazen alt kapsamda sadece küçük değişiklikler gerekebilir. Bu tür durumlarda seçici kalıtım seçeneğini kullanmayı seçebilirsiniz. Bunu, aşağıdaki iki direktif yardımıyla başarabilirsiniz:
· SecFilterImport - üst kapsamdan tek bir kural dahil etmek için. Bu direktif alt kapsamda baştan başlamak için ve üst kapsamdan sadece seçilen kuralları dahil etmek için faydalıdır.
· SecFilterRemove - hali hazırdaki kapsamdan bir kural çıkarmak için. Bu direktif üst kapsamdaki ile aynı kural kümesi ile başlamak ve sadece seçilen kuralları silmek istediğiniz zaman faydalıdır.
SecFilterImport ve SecFilterRemove direktiflerinin her ikisi de bir kural ID’leri listesi kabul ederler. Hedef kuralların ID’leri olmak zorundadır (bu, ID işlemi kullanılarak yapılır). Bu direktifler yapılandırma dosyasında bulundukları sıra ile çalıştırılırlar. Bu nedenle, SecFilterRemove direktifi ile kural çıkarmak ve sonra SecFilterImport direktifi ile kural eklemek mümkündür. Aşağıda, aynı yapılandırma kurallarını farklı yollarla üreten iki örnek bulabilirsiniz.
Not
Eğer bir hedef kural ID’si zincirin bir parçası olan kuralı gösterirse, import ve remove direktifleri sadece ID’inin gösterdiği kuralı değil bütün zinciri etkileyecektir.
Örnek 1: üst kapsamındaki kurallar kalıtılmaz, ama sadece bir kural dahil edilir.
SecFilter XXX id:1001
SecFilter YYY id:1002
SecFilter ZZZ id:1003
<Location /subcontext/>
SecFilterInheritance Off
SecFilterImport 1003
</Location>
Örnek 2: iki kural çıkarılarak, kurallar üst kapsamdan kalıtılır (dahil edilir).
SecFilter XXX id:1001
SecFilter YYY id:1002
SecFilter ZZZ id:1003
<Location /subcontext/>
SecFilterRemove 1001 1002
</Location>
Not
Apache web sunucusu çok çeşitli kapsamları destekler (mesela, <Directory>, <Location>, <Files>, ...). Kapsamların birleştirildikleri sıra önemlidir. Kalıtımı ve çeşitli kapsamları birleştirmeyi denememelisiniz. Eğer birleştirmek zorundaysanız, düşündüğünüz gibi çalıştığını doğrulamak için yapılandırmayı test edin ve Apache kapsam birleştirme dokümanlarını dikkatlice okuyun: http://httpd.apache.org/docs-2.0/sections.html#mergin.
Çok kullanıcılı ortamlarda filtre kalıtımı
Çok kullanıcılı ortamlarda ModSecurity çalıştırıdığınızda, ve kullanıcılarınızın .htaccess dosyalarında kurallar kullanmalarına izin verildiğinde, üst kapsamdan kural dahil etmelerine izin vermeyebilirsiniz. Bunu başarmak için iki yol vardır.
Not
Kullanıcılarınıza güvenmiyorsanız (mesela, web hizmeti veriyorsanız), ModSecurity’e ulaşmalarına asla izin vermemelisiniz. .htaccess olanağı ModSecurity yapılandırmasını uygulama kodunda tuttuğundan, kısıtlı yönetim kontrol yetki dağıtımı için faydalıdır. Ama kullanıcıların yapılandırmayı değiştirme olasılıkları olan durumlarda değil. Eğer kötü niyetli (güvensiz) bir ortamdaysanız, .htaccess özelliğini ModSecurity’i -DDISABLE_HTACCESS_CONFIG sekmesi ile derleyerek tamamen kapatmalısınız.
Öncelikle, bazı kuralları zorunlu kılmak için zorunlu işlem zincirini kullanabilirsiniz. Bu tür kurallar alt kapsam tarafından her zaman kalıtılacaktır.
Diğer bir yöntem SecFilterInheritanceMandatory direktifini kullanarak kapsamdaki bütün kuralları alt kapsam için zorunlu hale getirmektir.
SecFilterInheritanceMandatory On
Not
SecFilterInheritance özelliğinin kapsamda açık olması gibi, SecFilterInheritanceMandatory özelliği de, üst kapsamda kullanılan değerler ne olursa olsun, bir kapsamda her zaman kapalıdır.
Bu tür bir durumda ne olacağını merak ediyor olabilirsiniz:
SecFilter XXX id:1001
SecFilterInheritanceMandatory On
<Location /subcontext/>
SecFilterInheritance Off
SecFilter YYY id:1002
SecFilter ZZZ id:1003,mandatory
</Location>
<Location /subcontext/another/>
SecFilterRemove 1001 1002 1003
SecFilter QQQ id:1004
</Location>
Ana kapsamda kural kalıtımı zorunlu olduğundan, /subcontext/ kapsamı 1001 numaralı kuralı, SecFilterInheritance Off kuralına rağmen, kalıtacaktır. Bu alt kapsam önce 1001 kuralını, daha sonra 1002 ve 1003 numaraları koşacaktır.
Ana kapsamdan, zorunlu kural 1001, silme çabalarına rağmen /subcontext/another/ kapsamına da iletilecektir. Bu, mandatory işlemi kullanılarak kalıtım için zorunlu hale getirilen kural 1003 için de geçerlidir. SecFilterRemove 1001 1002 1003 direktifi, öte yandan, 1002 numaralı kuralı silmekte başarılı olacaktır çünkü kalıtım /subcontext/ kapsamında zorunlu değildir. Bu nedenle, bu kapsam ilk olarak 1001 ve 1003 daha sonra 1004 kurallarını koşacaktır.
Not
skip işlemini kullanan kurallarını içermeden veya silmeden kaçınmalısınız. Eğer çok dikkatli değilseniz, istediğinizin dışında bir şeyler yapan bir yapılandırma ile karşılaşabilirsiniz.
Özel karakterler URL içerisinde gönderilmeden kodlanmalıdırlar. Her karakter üç karakterden oluşan ve XY’nin bir hexadecimal karakter kodunu temsil ettiği %XY kombinasyonu ile değiştirilebilir. (daha fazla detay için http://www.rfc-editor.org/rfc/rfc1738.txt) Hexadecimal sayılar sadece A’dan F’ye olan harfleri içerir, ama saldırganlar kod çözme algoritmasını kandırmak için diğer harfleri de kullanırlar. ModSecurity verilen bütün kodlamaları doğru olduklarını anlamak için kontrol eder.
URL kodlama denetimini aşağıdaki satır ile açabilirsiniz:
SecFilterCheckURLEncoding On
Not
Bu direktif multipart/form-data (dosya yükleme) kullanıldığında bir POST verisindeki kodlamayı kontrol etmez. Gerekmez çünkü bu kodlamada URL kodlama kullanılmaz.
Evrensel Kodlama Denetimi
Diğer bir çok özellik gibi Evrensel kodlama denetlemesi varsayılı olarak kapalıdır. Eğer uygulamanız veya alttaki işletim sisteminiz evrensel kodu kabul ediyor veya anlıyorsa bu özelliği açmalısınız.
SecFilterCheckUnicodeEncoding On
Bu özellik UTF-8 kodlamanın kullanıldığını varsayar ve üç tip hatayı kontrol eder:
· Yetersiz bayt. UTF-8 iki, üç, dört, beş ve altı baytlık kodlamaları destekler. ModSecurity bir veya daha fazla baytın eksik olduğu durumları bulur.
· Geçersiz kodlama. Bir çok karakterin ilk iki bitlerinin 0x80 olması gerekmektedir. Saldırganlar bunu kullanarak evrensel kod çözücülerini alt etmek için kullanabilirler.
· Çok uzun karakterler. ASCII karakterleri evrensel kod uzayına direk olarak eşlenirler ve bu nedenle sadece 1 bayt ile gösterilirler. Ama, bir çok ASCII karakterleri iki, üç, dört, beş ve altı karakterler şeklinde de kodlanabilir ve böylece kod çözücüleri bu karakterlerin farklı karakterler olduğuna inandırabilirler (ve böylece güvenlik kontrollerini geçebilirler).
İsteklerin içerisindeki baytların sadece belli bir aralıkta olmalarını sağlayabilirsiniz. Bu yığıt taşması (stack overflows) saldırılarını önlemekte faydalı olabilir (çünkü bu saldırılar genelde rasgele ikili -binary- içerik içerirler). Sadece 32’den 126’ya kadar (kapsayacak şekilde) bayt değerlerine izin vermek için, aşağıdaki direktifi kullanın:
SecFilterForceByteRange 32 126
Varsayılı aralık değerleri 0 ve 255’tir. Yani bütün bayt değerleri kabul edilir.
Not
Bu direktif POST içerisindeki bayt aralıklarını multipart/form-data kodlama kullanıldığında (karşıdan dosya yükleme) kontrol etmez. Bu şekilde ikili (binary) dosyaların karşıdan yüklenmesi bir problemle karşılanmaz. Ama, bu tür bir istekten parametreler alındıktan sonra geçerli bayt aralıkları kontrol edilir.
Diğerlerinin ModSecurity’i Görmesine İzin Verilmesi
1.9’dan önce ModSecurity SecServerResponseToken direktifini desteklerdi. Kullanıldığında, bu direktif web sunucusu imzasında modülün var olup olmadığını kontrol ederdi. Bu direktif 1.9’da artık çalışmıyor. Kullanıldığında, hata kaydına bir uyarı mesajı düşecektir.
Filtreleme motoru çalışır hale getirildiğinde, her gelen istek yakalanır ve işlemden geçirilmeden önce analiz edilir. Analiz istek formatını denetlemek için dizayn edilen bir seri kontrollerle başlar. Bu kontroller yapılandırma direktifleri kullanılarak kontrol edilebilir. İkinci aşamada, istek, kullanıcı tarafından tanımlanan ve eşlenen filtrelerden geçer. Bu eşleşmenin sonucu pozitif olursa, belli işlemler uygulanır.
Filtrelemenin en basit formu, isminden de anlaşılacağı gibi basittir. Şuna benzer:
Bunun gibi her basit filtre istek içerisinde anahtar sözcüğü arar. Arama çok geniş yapılır; isteğin ilk satırına (GET /index.php?parameter=value HTTP/1.0 gibi) uygulanır. POST isteklerinde, isteğin gövdesi de aranır (tabi ki istek gövdesi tamponlaması -buffering- desteklenirse).
Yol (path) normalizasyonu
Filtreler işlenmemiş istek verilerine uygulanmaz, normalize edilmiş kopyalarına uygulanır. Bunu, saldırganların farkedilmemek için kullandıkları bir çok değişik atlatma tekniklerini önlemek için yaparız. Örneğin, komut satırı çalıştırma saldırısını yakalayacak bir filtre yazdığınızı düşünün:
Ama saldırgan /bin/./sh şeklinde (aynı anlama gelen) bir dizgi kullanabilir.
ModSecurity aşağıdaki değişiklikleri otomatik olarak uygular:
· Sadece Windows’da, \ işaretini / işaretine çevirir.
· /./ işaretlerini /
işaretine çevirir.
· // işaretlerini /
işaretine çevirir.
· URL kodlanmış karakterleri çözer.
Aşağıdaki kontrolleri açıp kapamayı seçebilirsiniz:
· URL kodlamayı denetleme
· Belli aralıktaki baytları kullanmayı
Boş (Null) bayt saldırı önleme
Boş (null) bayt saldırıları C/C++ tabanlı yazılımların aklını karştırmaya ve onları dizginin bittiğine (bitmediği halde) inandırmaya çalışır. Bu çeşit bir saldırı aslında tipik olarak düzgün bir SecFilterByteRange filtresi ile engellenir. Ama, bunu yapmazsanız boş bayt ModSecurity’nin işlemini karıştırabilir. Bununla savaşmak için, ModSecurity çözme (decoding) sırasında boş baytları arar ve onları boşluğa dönüştürür. Yani,aşağıdaki filtre daha önce:
aşağıdaki istek içerisindeki saklanmış kelimeyi bulamazdı:
GET /one/two/three?p=visible%00hidden HTTP/1.0
Ancak şimdi beklendiği çalışmaktadır.
Düzenli İfadeler (Regular expressions
)
Daha önce bahsettiğim en basit filtreleme metodu aslında biraz daha karmaşıktır. Tam yazılım şekli (syntax) aşağıdaki gibidir:
SecFilter KEYWORD [ACTIONS]
İlk olarak, KEYWORD basit bir dizgi (text) değildir. Düzenli bir ifadedir (regular expression). Düzenli bir ifade, yazı içinde örüntü eşlemede (pattern matching) kullanılan mini bir programlama dilidir. Bu güçlü aracı, hakkını vererek kullanmak için düzenli ifadeleri çok iyi anlamanız gerekir. Aşağıdaki kaynaklar ile başlamanızı öneririm:
Not
Apache 1.x ve Apache 2.x için iki farklı düzenli ifade motoru (regular expression engine) kullanılmıştır. Apache 1.x’in düzenli ifade motoru POSIX uyumludur. Apache 2.x’in düzenli ifade motoru PCRE uyumludur. Ana kural olarak, Apache 1.x’de çalışan düzenli ifadeler Apache 2.x’de de çalışır, ama diğer şekilde değil. Eğer her ikisinde de çalışması gereken kurallar yazmanız gerekirse, iyi test etmeniz gerekir.
İkinci parametre, kuralın eşleşmesi durumunda yapılacak işlem listesi tanımıdır. İşlemler bu kılavuzda daha sonra açıklanacaktır.
Ünlem işareti bir düzenli ifadenin ilk karakteri ise, filtre düzenli ifadeyi tersyüz edilmiş olarak görür. Örneğin, aşağıdaki ifade:
php kelimesini içermeyen her isteği reddeder.
İleri (Advanced) filtreleme
Her ne kadar SecFilter’ı kullanmak kolay gelse de, er ya da geç çok geniş bir kapsamı olduğunu ve bu nedenle çok iyi çalışmadığını anlayacaksınız. Diğer direktif:
SecFilterSelective LOCATION KEYWORD [ACTIONS]
aramanın tam olarak nerede yapabileceğiniz seçeneğini size sunar. KEYWORD ve ACTIONS bölümleri SecFilter ile aynıdır. LOCATION bölümü daha detaylı bir açıklama gerektirir.
LOCATION parametresi bir hatla (pipe) ayrılmış bir seri yer belirtecinden oluşur.
Aşağıdaki örneğe bakın:
SecFilterSelective "REMOTE_ADDR|REMOTE_HOST" KEYWORD
Düzenli ifadeyi sadece istemcinin IP adresine ve sunucu ismine uygulayacaktır. Mümkün olan yer belirteçlerinin listesi bütün CGI değişkenlerini ve daha fazlasını kapsar. İşte bütün liste:
· REMOTE_ADDR
· REMOTE_HOST
· REMOTE_USER
· REMOTE_IDENT
· REQUEST_METHOD
· SCRIPT_FILENAME
· PATH_INFO
· QUERY_STRING
· AUTH_TYPE
· DOCUMENT_ROOT
· SERVER_ADMIN
· SERVER_NAME
· SERVER_ADDR
· SERVER_PORT
· SERVER_PROTOCOL
· SERVER_SOFTWARE
· TIME_YEAR
· TIME_MON
· TIME_DAY
· TIME_HOUR
· TIME_MIN
· TIME_SEC
· TIME_WDAY
· TIME
· API_VERSION
· THE_REQUEST
· REQUEST_URI
· REQUEST_FILENAME
· IS_SUBREQ
· POST_PAYLOAD - POST isteğinin gövdesini filterele
· ARGS - filtre argümanları, QUERY_STRING|POST_PAYLOAD ile aynı
· ARGS_NAMES - sadece değişken/parametre isimleri
· ARGS_VALUES - sadece değişken/parametre değerleri
· COOKIES_NAMES - sadece cookie isimleri
· COOKIES_VALUES - sadece cookie değerleri
· SCRIPT_UID
· SCRIPT_GID
· SCRIPT_USERNAME
· SCRIPT_GROUPNAME
· SCRIPT_MODE
· ARGS_COUNT
· COOKIES_COUNT
· HEADERS
· HEADERS_COUNT
· HEADERS_NAMES
· HEADERS_VALUES
· FILES_COUNT
· FILES_NAMES
· FILES_SIZES
· HTTP_header - istek başlığı "header"’ı ara (1.9 ile beraber HEADER_header’de kullanılabilir)
· ENV_variable - variable çevre değişkenini ara
· ARG_variable - variable istek değişkeni/parametresini ara
· COOKIE_name - name ismindeki cookie’yi ara
· FILE_NAME_variable - variable isminde karşıdan yüklenen dosyayı ara
· FILE_SIZE_variable - variable isminde karşıdan yüklenen dosyayının büyüklüğünü ara
· OUTPUT – bütün cevap gövdesi
· OUTPUT_STATUS – cevap durum kodu
Argüman filtreleme istisnaları
ARG_variable yer belirteci isimleri ARGS ile beraber kullanıldığında tersyüz kullanımı da destekler. Örneğin:
SecFilterSelective "ARGS|!ARG_param" KEYWORD
isimlendirilmiş parametre dışında diğer bütün argümanları arayacaktır.
ModSecurity cookieler için tam destek sunar. Varsayılı olarak, cookieler sürüm 0 formatına (Netscape stili cookieler) sahip olacak şekilde işlem görür. Ancak sürüm 1 cookieler (RFC 2965’te tanımlandığı şekilde) de desteklenir. Sürüm 1 cookie desteğini açmak için SecFilterCookieFormat direktifini kullanın:
# enable version 1 (RFC 2965) cookies
SecFilterCookieFormat 1
Varsayılı olarak, ModSecurity cookie isimlerini ve değerlerini normalize etmez. Ancak, bazı uygulamalar ve platformlar (mesela PHP) cookie içeriğini kodladığından, cookielere normalize tekniklerinin uygulanmasını seçebilirsiniz. Bu SecFilterNormalizeCookies direktifi kullanılarak yapılabilir.
SecFilterNormalizeCookies On
Not
Sürüm 1.8.7’e kadar ModSecurity SecFilterCheckCookieFormat direktifini desteklerdi. 1.8.7’de yapılan yeni değişiklikler sebebiyle bu direktif şu an yürürlükten kaldırılmıştır. Yapılandırmada hala kullanılabilir ancak bir etkisi yoktur. Bu direktif 1.9.x sürümlerinde tamamen kaldırılacaktır.
ModSecurity çıktı filtrelemeyi Apache 2 sürümünde destekler. Varsayılı olarak (by default) kapalıdır, bu nedenle önce aşağıdaki gibi açmalısınız:
Bundan sonra, özel değişken OUTPUT’u seçici filtrelerde kullanabilirsiniz:
SecFilterSelective OUTPUT "credit card numbers"
Beni http://www.webkreator.com/php/
deki sütunumdan tanıyanlar PHP’nin hayati hata mesajlarını önleme eksikliğine olan saplantımı bilirler. Bu hayati hataları önlemek için hataların son kullanıcılara ulaşmasını engellemekten (http://www.webkreator.com/php/configuration/handling-fatal-and-parse-errors.html) başlayarak epey uğraştım, ama artık, sonunda, bu konu hakkında daha fazla endişelenmiyorum. Aşağıdaki, PHP çıktı hatalarını cevap gövdesinde yakalayacak ve başka bir hata mesajı ile cevap gönderecektir.
SecFilterSelective OUTPUT "Fatal error:" deny,status:500
ErrorDocument 500 /php-fatal-error.html
Çıktı filtrelerini ile girdi filtrelerini beraber kullanabilirsiniz ama aynı anda çalışmayacaklarını bilmeniz gerekir. Girdi filtreleri Apache tarafından herhangi bir istek işlemden geçirilmeden çalıştırılırlar, öte yandan çıktı filtreleri Apache istek işlemlerini bitirdikten sonra çalışır.
Not
skipnext ve chain işlemleri çıktı filtreleri olmadan çalışmazlar.
Çıktı filtreleme sadece düz yazı ve HTML çıktıları için kullanışlıdır. İkili (binary) içeriğe düzenli ifadeler (regular expressions) uygulamak sadece sunucuyu yavaşlatacaktır. Varsayılı olarak ModSecurity içerik tipi (content type) olmayan veya içerik tipi text/plain veya text/html olan cevap çıktılarını tarayacaktır. Bu durumu SecFilterOutputMimeTypes direktifini kullanarak değiştirebilirsiniz.
SecFilterOutputMimeTypes "(null) text/html text/plain"
Aşağıdaki örnek gibi yapılandırıldığında ModSecurity çıktı filtrelerini düz yazı dosyalarına, HTML dosyalarına ve mime tipi "(null)" olarak belirtilen dosyalara uygulayacaktır.
Not
Çıktı tamponlaması (biriktirmesi, buffering) kullanılması ModSecurity’nin bütün sayfa çıktısını, ne kadar büyük olursa olsun, hafızada tutmasını sağlayacaktır. Bu nedenle hafıza tüketimi sayfa büyüklüğünün iki katından fazladır.
Bazı durumlarda çıktı gözetlemesi ne kadar kullanışlı olsa da, %100 güvenli olmadığının farkında olmalısınız. Eğer saldırgan istek işleme işine tamamen hükmediyorsa, çıktı gözetlemeyi iki şekilde atlatabilir:
1. Gözetlenmeyen bir Content-Type kullanabilir. (Performans nedenlerinden ötürü, bütün içerik tiplerinin gözetlenmesi mümkün değildir.)
2. Çıktıyı bir şekilde kodlar. Basit bir kodlama bile gözetleme işini atlatacaktır.
1.9 ile beraber diğer çıktı değişkeni de desteklenmektedir- OUTPUT_STATUS. Bu değişken cevap durum kodunu içerir.
Bir çok işlem tipi vardır:
· Ana işlem isteğin kabul edilip edilmeyeceğine karar verir. Sadece bir ana işlem bulunabilir. Eğer birden fazla ana işlem yazarsanız, sadece en son işlem çalıştırılacaktır. Ana işlemler şunlardır: deny, pass, and redirect.
· İkincil işlemler filtre eşleşmesi sonucu ana işlemlerden bağımsız olarak çalıştırılarlar. Birden fazla ikincil işlem bulunabilir. Örnek olarak, exec ikincil bir işlemdir.
· Akış işlemleri kuralların akışını değiştirebilir ve böylece filtrelemenin bir kuraldan diğer kurala atlamasını veya bir veya bir kaç kural atlamasına sebep olabilir. Akış işlemleri şunlardır: chain ve skip
· Parametreler tam olarak işlem değillerdir. Onlar filtrelere parametre ekleme metodudur. Bu parametrelerden bazıları gerçek işlemler tarafından da kullanılabilirler. Örnek olarak status ana işlem olan deny’a cevap kodunu bildirir.
İşlemleri belirteceğiniz üç yer vardır. Bunlardan bir tanesi ondan sonra gelen kuralların işlemleri olarak çalışmasını istediğiniz SecFilterDefaultAction’dir.
SecFilterDefaultAction "deny,log,status:500"
Bu örnek üç işlemden oluşan bir işlem listesi tanımlar. Virgüller listedeki işlemleri ayırmakta kullanılır. İlk iki işlem tek kelimeden oluşur. Ama üçüncü işlem bir parametre ister. Parametreyi işlemden ayırmak için iki nokta üst üste kullanın. İşlem parametreleri etraflarını tek tırnak ile çevirmediğiniz takdirde boşluklar içeremez (parametrede tek tırnağı ters bölü işareti ile kurtarın -kaçırın, escape-).
SecFilterDefaultAction "deny,log,status:'Hello World!'"
Not
1.8.6 ile birlikte, eğer hayati olmayan bir işlem (log,pass gibi) belirtirseniz ilklendirme fazında görmezden gelineceklerdir. İlklendirme fazı, istek hakkında bilgi edinmek için dizayn edilmiştir. Hayati olmayan işlem belirtmek, isteklerin bazı kısımlarının kaçırılmasını (ModSecurity’nin dahili çalışması için) sağlardı. Bu nedenle ModSecurity’nin “sadece bul” modunda çalışmasını isterseniz bütün örtülü denetlemeleri (URL kodlama, evrensel kod, cookie formatı, bayt aralığı denetimleri) kapatmalısınız.
Not
Yardımcı veri (meta-data) işlemleri (id, rev, msg, severity) ve kuralların akışını kontrol eden işlemler (skip/skipnext, chain) SecFilterDefaultAction direktifinde bulunamazlar.
Kural başına da işlemler belirtebilirsiniz. Her iki filtreleme direktifleri de (SecFilter ve SecFilterSelective) işlemleri opsiyonel parametreler olarak kabul ederler. Kural başına işlemler en güncel SecFilterSignatureAction direktifindeki işlemlerle (varsayılı değer log,deny,status:403) birleştirilirler. Aşağıdaki kurallar birleştirme işleminde uygulanırlar:
1. İşlem listesi başına sadece bir ana işleme izin verilir. Bir “kural başına işlem” varsayılı listedeki ana işlemi iptal eder.
2. Kural başına yapılandırmasında belirtilen işlemler varsayılı işlem listesindeki eş işlemleri iptal eder.
3. Kısıtlı mod (SecFilterActionsRestricted direktifini görün) açıkken sadece yardımcı veri işlemleri kural başına işlem listesinde bulunabilirler.
4. Kurallar yapılandırma zamanında (sezgisel olarak tercih edilen) veya yürütme zamanında (sezgisel olarak daha az tercih edilen) birleştirilebilirler. Aradaki farklar için okumaya devam edin.
1.9RC1’dan bu yana kullanılan SecFilterSignatureAction direktifi kural kümelerini yönetmeyi kolaylaştırır. 1.9RC1’dan önce eğer birisi kural başına işlem listesi kullanmak isteseydi bütün işlem listeleri tam olmalıydı, yani her işlem listesi ana işlemi, durum kodunu, vb. belirtmeliydi. Bu durum kuralların yapılandırma politikasından ayrılmasını çok zor kılıyordu. SecFilterSignatureAction direktifi tek bir yapılandırma kapsamında birden fazla yerde belirtilebilir ve hemen onu izleyen bütün kurallara uygulanır. Tutarlı olması açısından özel yapım işlemleri içermeyen kurallar bu direktiften işlem listelerini kalıtır. Örnek olarak:
SecFilterDefaultAction log,deny,status:500
# Aşağıdaki kural çalıştırıldığı kapsamdaki
# işlemler ile yanıt verir
# Bir kuralın çalıştırıldığı kapsam
# yazıldığı kapsam olmayabileceğine dikkat etmelisiniz.
# Kalıtım yolu ile bir kural birden fazla
# kapsamda çalıştırılabilir.
SecFilter 000
# Uyarı kuralları
SecFilterSignatureAction log,pass
SecFilter 111 id:1
SecFilter 222 id:2
# Hata kuralları
SecFilterSignatureAction log,deny,status:403
SecFilter 333 id:3
SecFilter 444 id:4
# Aşağıdaki kural da, 403 durum kodu ile reddeder
SecFilter 555
SecFilterActionsRestricted ile beraber kullanıldığında bu direktif yapılandırmaya üçüncü parti kural kümelerinin konulmasını kolaylaştırır.
Not
SecFilterSignatureAction direktifinin değeri alt kapsamlar tarafından kalıtılmaz.
Kural başına işlem listesinde belirebilecekleri kısıtlama
Bazen, yapılandırmanıza üçüncü parti kuralları koymak istediğinizde, içlerinde hangi işlemlerin bulunması gerektiğini belirtmek isteyebilirsiniz. Bunu SecFilterActionsRestricted direktifinin yardımı ile yapabilirsiniz:
SecFilterSignatureAction log,deny,status:403
SecFilterActionsRestricted On
Include conf/third-party-rules.conf
Kısıtlı mod açıldığında kural başına yapılandırmada izin verilecek işlemler sadece yardımcı veri (meta-data) kurallarıdır: id, msg, rev, ve severity. Diğer kurallar sessizce görmezden gelinir.
Kurulum ile gelen işlemler
Filtre eşleşmesinde isteğin devam etmesini sağlar. Bu işlem, eşleşmeyi sadece kaydetmek (başka bir işlem yapmamayı) istediğinizde kullanışlıdır.
SecFilter KEYWORD "log,pass"
Bu bir önceki filtrenin daha güçlü versiyonudur. Bu işlem uygulandıktan sonra istek diğer hiçbir filtre uygulanmadan devam edecektir:
# filtreleme işlemini yöneticinin bilgisayarından
# gelen istekler için durdur
SecFilterSelective REMOTE_ADDR "^192\.168\.2\.99$" allow
Filtre eşlemesinde işlemi kes. Durum kodu da kullanılmadığı takdirde, ModSecurity hemen HTTP 500 hata kodu dönecektir. Bir istek reddedildiğinde mod_security-action başlığı istek başlık listesine eklenecektir. Bu başlık kullanılan durum kodunu içerecektir.
İstek reddedildiğinde belirtilen HTTP durum kodunu kullan. Aşağıdaki kural:
SecFilter KEYWORD "deny,status:404"
Tetiklendiğinde "Page not found" dönecektir. Eğer yapılandırma dosyasında var ise Apache ErrorDocument direktifi tetiklenecektir. Bu nedenle eğer daha önceden belirtilen bir durum kodu için özel yapım bir hata sayfası tanımladıysanız, bu sayfa çalıştırılacak ve kullanıcıya gösterilecektir.
Filtre eşleşmesinde kullanıcıyı verilen URL’ye yönlendir. Örnek olarak:
SecFilter KEYWORD "redirect:http://www.modsecurity.org"
Bu yapılandırma direktifi her zaman HTTP durum kodunu veya deny anahtar kelimesini silecektir (override). URL virgül içermemelidir.
Filtre eşleşmesi durumunda dahili ters vekil (inverse proxy) yolu ile isteği yeniden yaz (rewrite):
SecFilter KEYWORD "proxy:http://www.example.com"
Bu işlemin çalışması için mod_proxy kurulmuş olması gerekir.
Filtre eşleşmesinde bir ikili (binary) çalıştır. İkili için tam yol belirtilmelidir:
SecFilter KEYWORD "exec:/home/ivanr/report-attack.pl"
Bu direktif var olduğunda ana işlemleri etkilemez. Bu işlem, betiği bütün çevre değişken bilgilerini sağlayarak ama parametresiz çağıracaktır. Normalde bulunan bütün CGI çevre değişkenleri sağlanacaktır.
Her filtre eşleşmesinde tek bir ikili çalıştırabilirsiniz. Bu işlem mod_security-executed başlığını istek başlıklarına ekleyecektir.
Not
İş parçacıklı (kanallı, threaded) bir süreci (process) başlatmanın (forking), yeni süreçte bütün iş parçacıklarının kopyalanacağından haberdar olmanız gerekir. Bu nedenle süreç başlatma çok iş parçacıklı (multi-threaded) operasyonda büyük bir performans yükü getirir.
Filtre eşleşmesini Apache hata dosyasına kaydet.
Filtre eşleşmesini kaydetme. Bu aynı zamanda denetleme (audit) kaydının da olmasını engelleyecektir
Bu işlem bir veya birden fazla kuralı atlamanıza izin verir. Bu işlemi bazı isteklerde daha fazla test gerçekleştirmeyi istemediğinizde kullanacaksınız. Varsayılı olarak (by default), işlem diğer kurala atlar. Opsiyonel parametreyi sağlamanız durumunda istediğiniz kadar kural atlayabilir.
SecFilterSelective ARG_p value1 skipnext:2
SecFilterSelective ARG_p value2
SecFilterSelective ARG_p value3
Kural zincirlemesi bir çok kuralı daha büyük bir test haline getirmenize izin verir. Sadece zincirdeki en son kural zinciri etkileyecektir ama ona ulaşmak için diğer bütün kurallar da eşleşmelidir. İşte bu özelliği nasıl kullanabileceğinize bir örnek:
Yönetici hesabına sadece belli bir IP’den girilmesini istiyorum. Ama yönetici giriş paneli diğer kullanıcılar ile paylaştırılmış ve bu nedenle Apache’nin standard özelliklerini kullanamıyorum. Bu nedenle bu iki kuralı kullandım:
SecFilterSelective ARG_username admin chain
SecFilterSelective REMOTE_ADDR "!^SİZİN_IP_ADRESİNİZ_BURAYA$"
İlk kural sadece username parametresi varsa ve değeri admin ise eşleşir. Ondan sonra ikinci kural çalışır ve istekteki istemcinin adresini belli bir IP adresine eşleştirmeye çalışır. Eğer bir eşleşme olmazsa (baştaki ünlem işaretine dikkat edin) istek reddedilir.
Bir isteğe cevap vermeden belli bir milisaniye kadar bekle. Bu bazı otomatik web tarayıcılarının yavaşlatmak veya tamamen kafasını karıştırmak için kullanışlıdır. Eğer bekleme süresi çok fazla ise bazı tarayıcılar taramayı bırakır.
Not
Bu opsiyonu kullanırken dikkat edin çünkü bir yan etkisi vardır. Bütün web sunucu kurulumları bir limit ile yapılandırılır, verilen herhangi bir zamanda hizmet edilecek en fazla istek sayısı. Bu seçenekle kullanılacak uzun bir bekleme zamanı açıklık tarayıcıları istekleri paralel yapıyorsa bir hizmet dışı saldırısına davetiye çıkarabilir.
İşlem bilgisini denetleme (audit) kaydına kaydet.
İşlem bilgisini denetleme (audit) kaydına kaydetme.
Bu dört işlemin hepsi bir parametre ister ve ModSecurity tarafından çıktı olarak üretilen her kayıt mesajında bu parametreleri koyarlar. Buradaki fikir problemleri sınıflandırmak ve hata kayıt dosyalarına daha fazla bilgi koymabilmektir.
· id - biricik kural ID’si
· rev - kural revizyonu; eğer yoksa “1” olarak kabul edilir; ne zaman bir kural değişse revizyon değeri arttırılmalıdır.
· msg - hata kayıt mesajlarında çıkacak bir yazı mesajı
· severity - tanımlanmamış özel yapım önem dizgisi (string)
Not
Bu işlemler sadece bağımsız kurallarda veya kural zincirinin başlangıç kuralında kullanılır.
Her ne kadar id işlemi her hangi bir yazıyı içerebilse de, sadece tam sayıların kullanılması önerilir. Geçerli kural ID’lerinin ilerde sadece tam sayıları içermeyeceğini kimse garanti edemez. Eğer kurallarınızı halka açmayı düşünmüyorsanız, yerel aralığı kullanmalısınız: 1-99,999. Bunlar ayrılmış aralıklardır:
· 1 - 99999 dahili ihtiyaçlarınızı için ayrılmışlardır, istediğiniz gibi kullanın ama başkalarına yaymayın.
· 100,000-199,999 motorun dahili kullanımı için ayrılmıştır, belirlenmiş ID’leri olmayan kurallara eşitlemek için
· 200,000-299,999 modsecurity.org tarafından yayınlanacak kurallar için ayrılmıştır.
Aralık rezervasyonu için Ivan Ristic ile bağlantı kurun.
Bu işlemi bir kuralı veya bir kurallar zincirini alt kapsamlarda zorunlu kalıtılacak (inherited) şeklinde işaretlemek için kullanın. Daha detaylı bilgi için filtre kalıtımı bölümünü okuyun.
Not
mandatory işlemi sadece bağımsız kurallarda veya kural zincirinin başlangıç kuralında kullanılır.
Örnek olarak:
veya
SecFilter 111 mandatory,chain
SecFilter 222
Bu iki işlem, Apache’nin veya çevre değişkeninin değerini değiştirir veya kaldırır. Kullanabileceğiniz üç format vardır.
İsim ve değer:
SecFilter KEYWORD setenv:name=value
Sadece isim, bir değer olarak “1” kabul edilecektir:
SecFilter KEYWORD setenv:name
Varolan bir değişkeni, değişken isminin başına bir ünlem işareti koyarak silin:
SecFilter KEYWORD setenv:!name
mod_security
tarafından eklenen istek başlıkları
Mümkün oldukça, ModSecurity istek başlıklarına bilgi ekleyecektir, böylece betiklerinizin onları bulup kullanmasına izin verecektir. Tabi ki, ModSecurity’i betiklerinizin çalışması için istekleri reddetmeyecek şekilde yapılandırmanız gerekecektir. İlk bakışta çevre değişkenlerinin yerine istek başlıklarını bu sebep için kullanmam garibinize gidebilir. Çevre değişkenlerini kullanmak daha şık olabilirdi ama girdi başlıkları, ErrorDocument direktifi (aşağıda) ile çalıştırılan betiklere görünürken, çevre değişkenleri görünmez.
Bu eklenen başlıkların listesidir:
· mod_security-executed; çalıştırılan ikiliye (binary) olan yol ile
· mod_security-action; dönülen durum kodu ile
· mod_security-message; tespit edilen problem hakkındaki ve hata kaydına eklenen mesajla
İstek gövdesini (body) kaydetmek
ModSecurity bir istek gövdesini mod_security-body notu ile ihraç (export) eder. Bunu kayıdetmek için kullanabilirsiniz:
LogFormat "%h %l %u %t \"%r\" %>s %{mod_security-body}n
Not
Eğer istek multipart/request-data (karşıdan dosya yüklemek) tipindeyse, gerçek istek gövdesi taklit bir application/x-www-form-urlencoded içeriği ile değiştirilir.
ErrorDocument
kullanarak kural eşleşmelerini yönetmek
Eğer yapılandırmanız HTTP 500 durum kodunu dönüyorsa, ve bu durum oluştuğunda Apache’yi özel yapım (custom) bir betik çalıştırması için ayarlarsanız (mesela ErrorDocument 500 /error500.php), hatalara karşı, sevdiğiniz betik motorunu cevap vermesi için kullanabilirsiniz. Hata üzerindeki bilgi REDIRECT_* ve HTTP_MOD_SECURITY_* çevre değişkenleri olacaktır. (burada bahsedildiği gibi: http://httpd.apache.org/docs-2.0/custom-error.html)
ModSecurity’nin güvenlik duvarınızla konuşmasını sağlamak
Bazı durumlarda, tehlikeli saldırıları veya bir seri saldırı durumunu belirledikten sonra aynı kaynaktan daha fazla saldırı gelmesini engellemek isteyebilirsiniz. Bunu güvenlik duvarınızı belli bir IP adresinden gelen trafiği önleyecek şekilde değiştirerek yapabilirsiniz. (iptables ile çalışan yardımcı bir betik yazmıştım, buradan indirebilirsiniz: http://www.apachesecurity.net/)
Bu metot çok tehlikeli olabilir çünkü bir hizmet dışı saldırısı (DoS) ile sonuçlanabilir. Mesela, bir saldırgan saldırıyı başlatmak için bir vekil (proxy) kullanabilir. Bir vekilden gelen bütün istekleri reddetmek çok tehlikeli olabilir çünkü diğer bütün meşru kullanıcılar da bundan etkilenecektir.
Bir çok vekil, orijinal istemcileri tanımlayan bilgiler gönderdiğinden (bu konu hakkında bazı bilgilere buradan ulaşılabilir http://www.modsecurity.org/documentation/modsecurity-apache-manual-1.9.html???, "Stop hijacking" başlığı altında), akıllıca davranıp gerçek IP adresini bulabilirsiniz. Bu mümkündür, ama bir de aşağıdaki senaryoyu düşünün:
· Saldırgan uygulamaya direk olarak erişir ama gerçek kaynak IP adresi olarak rasgele veya geçerli bir IP adresi koyarak bir vekilmiş gibi davranır. Eğer bu bilgiyi göz önünde bulundurarak istekleri reddetmeye başlarsak, saldırgan IP adresini değiştirip devam edecektir. Sonuç olarak saldırgan uygulamanın açıklıklarını bulmaya çalışırken geçerli kullanıcıları reddetmiş oluruz.
Bu nedenle bu metod sadece vekillerden uygulamaya ulaşılmasına engel olursanız veya sadece çok iyi tanınan veya daha önemlisi güvenilen vekillerden uygulamaya ulaşılmasını sağlarsanız işe yarar.
Eğer hala IP tabanlı olarak istekleri reddetmek istiyorsanız (bütün uyarılarımıza rağmen), filtre eşleşmesinde çalışacak bir betik yazmanız gerekir. Betik çevre değişkenlerinden saldırganın IP adresini alıp, iptables veya ipchains’i verilen IP adresini reddetmeleri için çağırmalıdır. mod_security ileri bir sürümünde böyle bir betik içerecektir.
Karşıdan dosya yükleme desteği
ModSecurity, POST istekleri ve multipart/form-data kodlaması veya (1.9 ile beraber) PUT istekleriyle karşıdan yüklenen dosyaların yakalanabilmesini sağlar.
Karşıdan yüklenen dosyaların nereye yükleneceğini seçme
ModSecurity her zaman dosyaları geçici bir dizine yükleyecektir. Bu dizini SecUploadDir direktifi ile belirtebilirsiniz:
Sadece web sunucu kullanıcısının ulaşabileceği bir dosya alanın kullanılması daha iyidir. Öteki türlü, diğer sunucu kullanıcıları web sunucu tarafından yüklenen dosyalara erişebilirler.
Dosyaların doğruluklarını sağlama
Web sunucusundan uygulamaya geçmeden dosyaların doğruluklarını sağlayacak harici bir betik çalıştırmayı seçebilirsiniz. SecUploadApproveScript direktifi bu fonksiyonu kullanmaya açar. Aşağıdaki örnekte ki gibi:
SecUploadApproveScript /full/path/to/the/script.sh
Betiğe komut satırından sadece bir parametre sağlanır – karşıdan yüklenen dosyanın tam yolu. Betik dosya ile istediği her şeyi yapabilir. Dosyayı işledikten sonra, cevabını standard çıktıya (stdout) yazmalıdır. Eğer cevabının ilk karakteri “1” olursa dosya kabul edilir. Bunun dışında herşey dosyanın reddedilmesine sebep olur. Betiğiniz satırın geri kalanını daha yararlı bir hata mesajı için kullanabilir. Bu mesaj hata ayıklama kaydına (debug log) yazılacaktır.
Karşıdan yüklenen dosyaları depolama
Web sunucu aracılığı ile karşıdan yüklediğiniz dosyaları tutmak isteyebilirsiniz. Aşağıdaki satırı yapılandırmanıza ekleyin:
SecUploadDir direktifi tarafından belirtilen yere dosyalarınız depolanacaktır. Eğer sadece seçtiğiniz bazı dosyalarınızı tutmak istiyorsanız:
SecUploadKeepFiles RelevantOnly
Böylece sadece ilgili olarak tanımlanmış isteklerinize ait dosyalar depolanacaktır.
Geri plandaki diğer programlarınız ile etkileşim
Geri plandaki diğer programlarınızla etkileşime izin vermek için (mesela daha sonra açıklanacağı gibi ClamAV), 1.9dev1 ile birlikte dosyalar, grup okumasına izin verecek şekilde gevşetilmiş izinlerle oluşturulmaktadırlar. Bunu yapmak için, Apache’nin httpd ve geri plandaki programın clamav olarak koştuğunu farzedersek:
# mkdir /tmp/webfiles
# chown httpd:clamav /tmp/webfiles
# chmod 2750 /tmp/webfiles
Bu yapılandırma sonrası, clamav kullanıcısı dizine ulaşabilecektir. Aynı şey, clamav grup sahibi olduğundan, diğer dosyalar için de geçerlidir. Dosyaları /tmp/webfiles dizinine yüklemek için SecUploadDir direktifini kullanmayı unutmayın.
Not
Eğer dosyaları tutuyorsanız, onları bulundukları yerde web sunucu kullanıcısı hakları ile saklamanız güvenli olmayabilir. Mesela, web sunucunuzda modül olarak PHP ve güvenmediğiniz kullanıcılar koşuyorsanız, dosyalara ulaşabilirler. Dosyaları sadece root tarafından okunabilir hale getirmek için bir cron betiği yazmayı ve dosyaları tamamen başka bir yere taşımayı düşünün.
ModSecurity, dosya kabul mekanizmasını ClamAV virüs tarayıcısı ile bütünleştirmek için bir betik içerir. Bu özellikle, karşıdan dosya yükleme yolu ile web sunucusuna bulaşan virüsleri ve etkileyen açıklıkları engellemek için kullanışlıdır.
#!/usr/bin/perl
#
# modsec-clamscan.pl
# mod_security, http://www.modsecurity.org
# Copyright (c) 2002-2004 Ivan Ristic <ivanr@webkreator.com>
#
# $Id: modsecurity-manual.xml,v 1.7 2005/11/01 13:59:55 ivanr Exp $
#
# This script is an interface between mod_security and its
# ability to intercept files being uploaded through the
# web server, and ClamAV
# by default use the command-line version of ClamAV,
# which is slower but more likely to work out of the
# box
$CLAMSCAN = "/usr/bin/clamscan";
# using ClamAV in daemon mode is faster since the
# anti-virus engine is already running, but you also
# need to configure file permissions to allow ClamAV,
# usually running as a user other than the one Apache
# is running as, to access the files
# $CLAMSCAN = "/usr/bin/clamdscan";
if (@ARGV != 1) {
print "Usage: modsec-clamscan.pl <filename>\n";
exit;
}
my ($FILE) = @ARGV;
$cmd = "$CLAMSCAN --stdout --disable-summary $FILE";
$input = `$cmd`;
$input =~ m/^(.+)/;
$error_message = $1;
$output = "0 Unable to parse clamscan output [$1]";
if ($error_message =~ m/: Empty file\.$/) {
$output = "1 empty file";
}
elsif ($error_message =~ m/: (.+) ERROR$/) {
$output = "0 clamscan: $1";
}
elsif ($error_message =~ m/: (.+) FOUND$/) {
$output = "0 clamscan: $1";
}
elsif ($error_message =~ m/: OK$/) {
$output = "1 clamscan: OK";
}
print "$output\n";
Karşıdan yükleme hafıza limiti
Apache 1.x istek yakalamak için yeterli bir alt yapı sağlamaz. Ancak tamamen işlem hafızasında tutabilinen istekler yakalanabilir. Apache 1.x ile iki seçenek mevcuttur: multipart/form-data isteklerini aynı hafızada analiz etmek veya hiç analiz etmemek.
Ama Apache 2.x ile beraber ayrıştırmak (parse) isteğiniz multipart/form-data isteklerine hafızada ayrılacak büyüklüğü tanımlayabilirsiniz. Eğer istek belirttiğinizden daha fazla hafıza kaplıyorsa, geçici bir dosya kullanılacaktır. Varsayılı değer 60 KB’dir ama SecUploadInMemoryLimit direktifi kullanılarak limit değiştirilebilir:
SecUploadInMemoryLimit 125000
Sunucu kimlik maskelemesi
Saldırganların kafasını karıştıran veya yavaşlatan bir teknik web sunucusunun kimliğinin değiştirilmesidir. Web sunucuları tipik olarak kimliklerini bütün HTTP cevaplarında Server başlığı altında yollarlar. Apache özellikle bu nokta faydalıdır, sadece kendi kimliğini ve tam sürüm numarasını vermekle kalmaz, sunduğu modüllerin de sürüm numaralarını da ekler.
Apache web sunucusunun kimliğini değiştirmek için, kaynak koduna gitmeniz, “Apache”nin yazıldığı yeri bulmanız, değiştirmeniz ve sunucuyu yeniden derlemeniz gerekir. Aynı etki, SecServerSignature direktifi ile de başarılır.
SecServerSignature "Microsoft-IIS/5.0"
Bu iyi çalıştığı halde yetenekli saldırganlar (ve araçlar) web sunucunuzun kimliğini başka yollarla da bulabileceklerini bilmeniz gerekir. Mesela, varsayılı dosyalar, hata mesajları, cevap başlıklarının sıralaması, sunucunun belli isteklere verdiği cevaplar – bütün bunlar web sunucunuzun kimliğini ortaya koyar. mod_security’nin ilerki versiyonlarında web sunucusu kimliğiniz daha iyi gizlenmesi hakkında geliştirmeler yapacağım.
If you change Apache signature but you are annoyed by the strange message in the error log (some modules are still visible - this only affects the error log, from the outside it still works as expected):
Eğer Apache imzasını değiştirip, hata kayıtlarında garip mesajlar görürseniz (bazı modüller hala görünür – bu sadece hata kaydını etkiler, dışarıdan hala umulduğu gibi çalışmaktadır.):
[Fri Jun 11 04:02:28 2004] [notice] Microsoft-IIS/5.0 mod_ssl/2.8.12 OpenSSL/0.9.6b \
configured -- resuming normal operations
modüllerinizin yüklenme sırasını değiştirip mod_security’nin en son çalışmasına izin vermelisiniz, chrooting için anlatıldığı gibi (aşağıda).
Not
Bu direktifin çalışması için ServerTokens için Full değerini vermeniz gerekir.
SecServerSignature direktifi sunucu kimliğini değiştirmek için kullanıldığında, web sunucuyu tanımlamanız ve hangi modüllerin kullanıldığını anlamanız için, ModSecurity gerçek imzayı hata mesajlarına yazmaya başlayacaktır
[Fri Jun 11 04:02:28 2004] [notice] mod_security/1.9dev1 configured - Apache/2.0.52 \
(Unix) PHP/4.3.10 proxy_html/2.4
ModSecurity, Apache dosya sistemi izolasyonuna, diğer bir deyişle chrooting işlemine destek verir. Chrooting, bir uygulamayı dosya sisteminin bazen “hapishane” de denilen belli bir bölümüne hapsetmektir. Chroot (change root’ın kısaltılmışı) operasyonu uygulandığında uygulama, hapishanenin dışındakilere artık ulaşamaz. Sadece root kullanıcısı hapishaneden kaçabilir. Chrooting işleminin hayati bölümlerinden bir tanesi, root ile alakalı herhangi bir şeyin (root işlerinin -processes- veya root suid ikililerinin -binary-) hapishane içine erişememesidir. Ana fikir, herhangi bir saldırgan web sunucusunu kırmayı başarsa da çok fazla bi şey yapamayacaktır, çünkü o da hapishanede olacağı için kaçacak bir yeri olmayacaktır.
Uygulamalar chrooting’e destek vermek zorunda değildirler. Chroot ikilisi (binary) kullanılarak herhangi bir uygulama chroot içinde kullanılabilir. Aşağıdaki satır:
chroot /chroot/apache /usr/local/web/bin/apachectl start
dosya sistemini /chroot/apache dizinin altında ne varsa değiştirerek Apache’yi başlatacaktır.
Ne yazık ki, işler bu kadar kolay değildir. Uygulamaların düzgün çalışmak için paylaşılan kütüphanelere (shared libraries) ve diğer bir çok dosyalara ve ikililere ihtiyaç duymaları problem yaratır. Bu nedenle, ihtiyaç duydukları dosyaların kopyalarını alıp hapishane içine koymanız gerekir. Bu kolay bir iş değildir (Apache web sunucusunu chroot yapmak üzerine bilgiler için buraya bakınız: http://www.modsecurity.org/documentation/modsecurity-apache-manual-1.9.html???).
Apache’ye chrooting işlemi yaparken sıkılmış ve işlemi daha basitleştirmek için yollar aramaya başlamıştım. Sonuç olarak, chrooting özelliğini mod_security modülünün kendisine ekleyerek bütün işlemi daha az karmaşık hale getirdim. Yapılandırma dosyasına sadece bir satır eklemeniz gerekir:
SecChrootDir /chroot/apache
ve böylece web sunucunuza başarılı bir şekilde chroot işlemini uygulamış olacaksınız.
Basitliği bir tarafa, ModSecurity chrooting işlemi diğer bir avantajı da beraberinde getirir. Harici chrooting’den (daha önce bahsedildiği gibi) farklı olarak, ModSecurity chrooting hapishanede bulunmak için extra dosyalara ihtiyaç duymaz. Chroot çağrısı web sunucu ilklendirmesinden sonra ama sürecin başlatılmasından (forking) önce yapılır. Bütün bunlardan dolayı, bütün paylaşılan kütüphaneler çoktan yüklenmiş, bütün web sunucu modülleri ilklendirilmiş ve kayıt dosyaları açılmıştır. Sadece bilgilerinizin hapishanede bulunması gerekecektir.
Ancak CGI betikleri ve sistem ikililerini çalıştırmak istediğinizde hapishaneye koymanız gereken ek dosyalar olacaktır. Bu dosyaların kendi dosya gereksinimleri olabilir. Eğer bu kategoride iseniz normalde yapacağınız gibi harici chroot prosedürünü uygulamanız gerekir.
Not
Apache 2.x ile, AcceptMutex direktifinin varsayılı değeri pthread dir. Bazen bu yapılandırma ayarı chroot özelliği kullanıldığında Apache’yi çalışmaktan alıkoyar. Bu problemi aşmak için AcceptMutex değerini herhangi bir değere eşitleyin (mesela posixsem).
.
Eğer chroot’u kayıt dosyalarını hapishane dışında tutacak şekilde yapılandırırsanız, Apache’nin hapishane dışındaki dosyalara işaret eden dosya tanımlayıcıları (file descriptors) olacaktır. Chroot mekanizması ilk önceleri güvenlik için dizayn edilmemiştir ve bazı insanlar bu durum hakkında pek rahat değillerdir. Kendi kararınızı verin. Bu özelliği deneme amaçlı kullanın.
Not
Eğer Apache kurulumunuz mod_ssl kullanıyorsa, dosya tabanlı SSL mutex’i kullanıldığında kayıt dizinini hapishane dışında bırakmanın mümkün olmadığını anlarsınız. Çünkü mod_ssl açılış ile beraber hemen bir kilit (lock) dosyası oluşturur, ama daha sonra bulamadığından başarısızlığa uğrar. Bu problem diğer bir mutex çeşidi (mesela SSLMutex sem) kullanıldığında veya mod_ssl‘ye bu dosya tabanlı mutex’i hapishane içerisindeki bir dizine koymasını söylediğinizde ortadan kalkar (SSLMutex file://path/to/file kullanarak).
Not
Eğer chroot özelliğini birçok kanallı Apache kurulumu ile kullanmaya çalışırsanız, şu mesajı alabilirsiniz "libgcc_s.so.1 must be installed for pthread_cancel to work". Bu problemi çözmek için Apache yapılandırmanıza LoadFile /lib/libgcc_s.so.1 ekleyin.
Kimlik doğrulama için Apache tarafından kullanılan dosyalar her istek sırasında açıldıklarından hapishane içerisinde olmalıdırlar.
chroot desteği için gerekli modül sıralaması (Apache 1.x)
Not
Kayıt dosyalarını hapishane içerisinde bırakırsanız bu adıma gerek kalmaz.
Yukarıda da anlatıldığı gibi, chroot çağrısı Apache ilklendirmesinin (initialization) belli bir anında yapılmalıdır (diğer bütün modüller ilklendirildikten sonra). Bu ModSecurity’nin listelenen modüllerden ilki olmasını gösterir. Bunu sağlamak için, aşağıdaki yapılandırma direktiflerini kullanarak modül sıralamasında bir kaç değişiklik yapmanız gerekecektir.
ClearModuleList
AddModule mod_security.c
AddModule ...
AddModule ...
AddModule ...
İlk direktif listeyi temizler. ModSecurity’i hemen sonrasına koymanız gerekir, daha sonra kullanmak istediğiniz diğer bütün modüller (her zaman otomatik olarak eklenen ve kafanıza takmanız gerekmeyen http_core.c hariç) sıralanır. Kurulu modüllerin listesini httpd ikilisini –l sekmesi ile koşarak görebilirsiniz:
Not
Eğer Apache ikilisini ve destekleyen dosyaları hapishanenin dışında bırakmayı seçerseniz, apachectl graceful ve apachectl restart komutlarını daha fazla kullanamazsınız. Bu Apache’nin hapishanenin dışında çıkmasını gerektirir ki bu durm imkansızdır. Apache 2 ile beraber apachectl stop komutu bile çalışmayabilir. İlerki dağıtımlarda çözüm için bir değiştirici (replacement) betik oluşturabilirim.
chroot desteği için gerekli modül sıralaması (Apache 2.x)
Not
Kayıt dosyalarını hapishane içerisinde bırakırsanız bu adıma gerek kalmaz.
Apache 2.x ile beraber modül sıralamasını elle yapılandırmanıza gerek yoktur. Çünkü Apache 2.x’in dahili olarak zaten modül sıralaması için desteği vardır. ModSecurity bu özelliği kullanarak tam olarak ne zaman çağırılacağını Apache 2.x’ye anlatır ve böylece chroot çalışır (Eğer bir problem yaşıyorsanız bana bildirin).
Apache 2’de sürecin nasıl çalıştırılacağı hakkında bir değişiklik vardır. httpd ikilisinin kendisi süreç numarısı ile pid dosyasını oluşturur. Bu nedenle Apache’yi hapishanenin dışında olduğu gibi hapishanenin içinde de aynı dizine koymanız gerekir. Hapishane dışındaki Apache’nin /usr/local/web/apache olduğunu ve hapishanenin /chroot olacağını farzedersek /chroot/usr/local/web/apache/logs dizinini oluşturmanız gerekir.
Çalıştırıldığıda, Apache pid dosyasını orda oluşturacaktır (httpd.conf dosyasındaki pid dosyasının yerini değiştirmediğinizi farzederek).
Adım adım chroot kılavuzu
Eğer bu adım adım kılavuzu izlerseniz, modül sıralaması ile uğraşmak zorunda bile kalmazsınız. Önce normalde yapacağınız gibi Apache’yi kurun. Burada Apache’nin /usr/local/apache dizinine kurulduğunu farzedelim. Ayrıca hapishanenin /chroot/apache dizinine yerleştirileceğini de farzedelim. Kurulumun başarılı olup olmadığını kontrol etmek için sunucuyu başlatmak her zaman iyi bir fikirdir.
# mkdir -p /chroot/apache/usr/local
# cd /usr/local
# mv apache /chroot/apache/usr/local
# ln -s /chroot/apache/usr/local/apache
Şimdi ModSecurity’e başladığında chroot işlemi yapmasını gösterin:
SecChrootDir /chroot/apache
Ve Apache’yi başlatın:
/usr/local/apache/bin/apachectl startssl
Not
Bu prosedür, Apache dosyalarının chroot işlemi gerçekleştikten sonra hapishanenin içerisinde bırakılacağı bir yaklaşımı gösterir. Bu yaklaşım, önerilen bir yaklaşımdır çünkü her zaman çalışır ve çünkü chroot yapılmayan bir Apache’den chroot yapılan birine geçiş çok kolaydır (yapılandırma dosyasında SecChrootDir direktifini basitçe yorum haline getirmekle). Ancak dosyaların çoğunun dışarıda bırakılacağı bir hapishane oluşturmak tamamen mümkündür. Ama bu seçeneğin doğru çalışması çok zordur. Bu seçeneğin doğru çalışması için chroot mekanizmasının çok iyi anlaşılması gerekir.
Not
Sürüm 1.8’den beri, eğer ModSecurity herhangi bir nedenden dolayı başarısız olursa sunucunun başlamasına izin vermez. Yapılandırma fazında chroot başarısızlığını belirlemez ve sonra yürütme zamanında anlarsa, bunun hakkında hata kaydına bir mesaj düşer ve alt süreci bitirir. Bu güzel olmayabilir ama çalıştığını düşündüğünüz ama gerçekte çalışmayan bir chroot olmasından daha iyidir.
1.9dev1’de ModSecurity’nin Apache 2 sürümünde performans ölçümü için deneysel bir destek getirmiştim. İstemciler yavaş bir bağlantı üzerinde iseler betik performansının ölçülmesi bazen zordur. Cevap hem üretilip hem de istemciye yollandığından ikisini birbirinden ayırmak mümkün değildir. Performansı ölçmenin tek yolu cevabı parçalar halinde göndermeyip, sadece tam olarak üretimi bittiğinde yollamaktır. ModSecurity’nin de tam olarak yaptığı budur (güvenlik sebeplerinden) ve böylece bu durumu performans ölçümünde kullanmak mantıklı hale gelir. Üç zaman ölçümü yapılır ve sonuçlar Apache notlarında kayıt edilir. Bütün zamanlar mikrosaniye biriminde süreç başlangıcına göre ölçülür.
· mod_security-time1 – ModSecurity ilklendirmesi biter. Eğer istek bir gövde (body) içeriyorsa, şimdiye kadar çoktan okunacaktır (POST taraması açıksa).
· mod_security-time2 – ModSecurity işlem çalışmasını bitirir. En son çalışmak istediğimizden, istek bir işleyici tarafından işlenmeden hemen önce, bu zaman işlemin başlamasından kabaca hemen öncedir.
· mod_security-time3 – cevap üretilmiş ve istemciye yollanmak üzeredir.
Bu değerleri özel yapım bir kayıt dosyasında kullanmak için şunu yapın (tekrar, bu sadece Apache 2’de çalışır):
CustomLog logs/timer_log "%h %l %u %t \"%r\" %>s %b - \
%<{mod_security-time1}n %<{mod_security-time2}n \
%<{mod_security-time2}n %D"
Kayıttaki her eleman aşağıdaki gibi gözükecektir:
82.70.94.182 - - [19/Nov/2004:11:33:52 +0000] "GET /cgi-bin/modsec-test.pl HTTP/1.1" \
200 1418 - 532 1490 13115 14120
Yukarıdaki örnekte işlemin ModSecurity’e ulaşması 532 mikrosaniye sürmüştür. ModSecurity tanımlanmış kuralları çalıştırmak için 958 mikrosaniye (1490 - 532) harcamıştır ve CGI betiğinin çıktıyı üretmesi 11652 mikrosaniye (13155 - 1490) sürmüştür ve Apache’nin isteği istemciye yollaması 965 mikrosaniye sürmüştür.
Hata ayıklama çıktısının yazılacağı dosyayı seçmek için SecFilterDebugLog direktifini kullanın. Eğer parametre kesme işareti ile başlamıyorsa, Apache home yolu değerin başına eklenecektir.
SecFilterDebugLog logs/modsec_debug_log
Hata ayıklama kaydının ne kadar detaylı olmasını SecFilterDebugLevel direktifi ile ayarlayabilirsiniz:
Alabileceği değerler:
· 0 – hiç (bu değer üretim sistemlerinde her zaman kullanılmalıdır)
· 1 – önemli olaylar (bunlar aynı zamanda error_log dosyasında da raporlanacaktır)
· 2 – bilgilendirici mesajları
· 3 – daha detaylı bilgilendirici mesajlar
Not
ModSecurity dahili olarak 9’a kadar kayıt seviyeri kullanır ama bunlar sadece hata ayıklama amaçları için faydalıdır.
Standard Apache kayıt tutması belli bir kullanıcının veya saldırganın adımlarını geriye doğru izlemenizde çok yardımcı olmaz. Problem, her isteğin sadece bir parçasının kayıt dosyasına yazılmasıdır. Bu problem ModSecurity’nin denetleme kayıt tutma özelliği ile iyileştirilebilir. Aşağıdaki iki direktif
SecAuditEngine On
SecAuditLog logs/audit_log
mod_security’e audit_log dosyasında kapsamlı bir denetleme kaydının olmasını istediğinizi söyleyecektir. İşte bir isteğin nasıl kayıt edildiğine dair bir örnek:
========================================
Request: 192.168.0.2 - - [[18/May/2003:11:20:43 +0100]] "GET /cgi-bin/printenv?p1=666 \
HTTP/1.0" 406 822
Handler: cgi-script
----------------------------------------
GET /cgi-bin/printenv?p1=666 HTTP/1.0
Host: wkx.dyndns.org:8080
User-Agent: mod_security regression test utility
Connection: Close
mod_security-message: Access denied with code 406. Pattern match "666" at \
ARGS_SELECTIVE
mod_security-action: 406
HTTP/1.0 406 Not Acceptable
========================================
Bunu normalde Apache’den alacağınız gibi ilk satırda görebilirsiniz. İkinci satır, isteği halledecek işleyicinin (handler) ismini içerir. Tam istek (ek mod_security başlıkları ile beraber) ayraçtan sonra verilir ve cevap başlıkları (bu durumda sadece bir satır vardır) bir boş satırdan sonra verilir.
POST filtrelemesi açık olduğunda, POST verileri her zaman denetleme kaydında olur. Gerçek cevap asla olmaz (en azından bu sürümde).
Not
Denetleme kayıt verilerini işlerken dikkat edin. Dosyalar ağ üzerinden alınmış ama filtrelenmemiş ikili (binary) veriyi bulundurabilir. Bu veriler doğru şekilde halledilmezse tehlikerli olabilir (mesela terminal değişim karakterlerini içerebilirler).
Şu anda, modülün kayıt tutma parçası Apache 1.x hata mesajlarını Handler: satırının altındaki satırda kaydedecektir. Satır her zaman Error: ile başlayacaktır. Bu fonksiyonellik mümkün olursa, modülün Apache 2.x sürümüne eklenecektir.
Not
Kayıt tutma alt sistemi zamanı dolan istekleri kaydetmez.
Not
Kayıt başlıkları Date ve Server çıktı başlıklarını içermez. Bu, Apache’nin bu başlıkları cevap üretme işleminin en sonunda ekleyip bir modülün onları elde etmesini imkansız hale getimesindendir.
Cevap durum koduna bakarak neyin kaydedileceğini seçmek
1.9 ile beraber ModSecurity, istekleri uyarı veya hata üretmeseler bile seçmeli olarak denetleme kaydına düşürmek için kullanılan SecAuditLogRelevantStatus direktifini destekler. Web sunucusu üzerindeki uygulamalar ile basit bir iletişim kanalı kurmak gerçekten faydalı olabilir. Mesela, eğer uygulamanın her hangi bir dahili hata durumunda veya saldırı olduğunda her zaman HTTP 500 durum kodu ile cevapladığını bilirseniz, ModSecurity’i bu tür istekleri tam olarak kayıt edecek şekilde yapılandırabilirsiniz:
SecAuditLogRelevantStatus ^5
Bu direktif bir parametre kabul eder; cevap durum kodu ile eşleşen bir düzenli ifade (regular expression). Eğer bir eşleşme olursa, işlem ilgili kabul ve kaydedilir.
Biricik (Unique) istek tanımlayıcıları
If you add mod_unique_id to the Apache configuration mod_security will detect it and use the environment variable it generates (UNIQUE_ID). Its value will be written to the audit log. You could write the unique ID in an error page to the user and use it later to track and fix a false positive.
Eğer Apache yapılandırmasına mod_unique_id eklerseniz, mod_security anlar ve ürettiği çevre değişkenini kullanır (UNIQUE_ID). Değeri denetleme kaydına yazılır. Kullanıcıya hata sayfası içerisinde
Ne kaydedileceğini seçmek
SecAuditEngine parametresi 4 değerden birini alır:
· On - bütün istekleri kaydet
· Off - hiçbir isteği kaydetme
· RelevantOnly – sadece ilgili istekleri kaydet. İlgili istekler bir filtre eşleşmesine sebebiyet veren isteklerdir.
· DynamicOrRelevant – dinamik olarak üretilen veya ilgili istekleri kaydet. İstek ancak bir işleyicisi varsa dinamik olarak kabul edilir.
ModSecurity’i dinamik isteklerin de kaydını almasına çalışmak yapılandırmanıza bağlı olarak bazen biraz iş gerektirir. Apache teorisinde, bir isteğe cevap işleyici (handler) ismi verilen bir yapı tarafından üretilir. Eğer bir isteğe bağlanan bir işleyici varsa, dinamik bir yapı olarak düşünülmelidir. Pratikte ise, Apache dinamik sayfalar servisini işleyicileri kullanmadan da verebilir (MIME çeşidine göre modülü seçer). Bu, eğer PHP’yi ana dağıtımda gelen şekilde yapılandırırsanız olur:
AddType application/x-httpd-php .php
Bu çalışır ama tam olarak doğru değildir. Ancak, eğer yukarıdaki satırı aşağıdaki ile değiştirirseniz:
AddHandler application/x-httpd-php .php
PHP’nin normal çalışacağı gibi Apache’nin de isteğe atanmış bir işleyicisi olacak ve denetleme kaydedicisi seçmeli olarak kayıt tutabilecektir.
1.9 ile beraber denetleme kaydedicisi bir şeyin ilgili olup olmadığına karar vermek için cevap kodunu dikkate alır. Şu an itibarıyle 4xx ve 5xx ilgili sayılmaktadırlar. Bu herhangi bir web uygulamasında gelen istekler üzerinde denetleme kaydının yapılmasını kolaylaştırır. Bir hata oluştuğunda normalde vereceğiniz gibi cevap verin ama sadece cevap kodunu mesela 500’e çevirin.
Yeni Denetleme Kayıt Çeşidi
Yeni denetleme kayıt çeşidi ModSecurity 1.9 ile beraber getirildi. Eski denetleme kayıt çeşidi gelişi güzel kayıt kullanımı için hala kullanışlıdır. Yeni denetleme kayıt çeşidi performansı arttırmak (paralel istekler arasında yazma işlemini senkronize etme işlemini ortadan kaldırmak için her yeni işlem için bir dosya oluşturulması), kaydı tutulan bilgi miktarını arttırmak ve gerçek zamanlı denetleme kaydı bir araya getirilmesi (aggregation) amacıyla oluşturuldu. Yeni denetleme kayıt çeşidi cevap gövdelerini (body) de kaydedebilir.
Not
Yeni denetleme kayıt çeşidinin çalışması için mod_unique_id modülünün aktif olması gerekir.
Örnek yapılandırma:
# Yes, we want to use the new format
SecAuditLogType Concurrent
# Directory where the files will be stored
# MUST NOT BE THE SAME AS THE APACHE LOGS FOLDER
SecAuditLogStorageDir /var/www/audit_log/
# The index of all files created
SecAuditLog /var/www/audit_log/index
# Choose what to log – everything (default is ABCFHZ)
SecAuditLogParts ABCDEFGHZ
Her denetleme kayıt dosyası için index dosyasında bir satır giriş oluşturulacaktır. Gerçek zamanlı denetleme kaydı bir araya getirilmesi (aggregation) gerçeklemek isteyenler kanallama kayıt mekanizmasını kullanarak denetleme kayıt girişleri hakkında bilgi almak için bir betik yapılandırmaları gerekir.
Tipik bir kayıt girişi aşağıdaki şekilde gözükür:
192.168.2.101 192.168.2.11 - - [15/Jul/2005:11:56:52 +0100] \
"POST /form.php HTTP/1.1" 403 3 "http://192.168.2.101:8080/form.php" \
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 \
Firefox/1.0.4" G3yTd38AAAEAAAM7BLwAAAAA "-" \
/20050715/20050715-1156/20050715-115652-G3yTd38AAAEAAAM7BLwAAAAA 0 1031 \
md5:dc910f6d647d47b32ae6e47326f0ca42
Satır bir “vcombined” kayıt formatı ile başlar ama sonra aşağıdaki alanları ekler:
· unique_id
· session_id (şu anda kullanılmamaktadır)
· filename
· offset
· size
· denetleme kayıt girişinin kriptografik özeti (hash) (şu anda MD5 kullanılmaktadır)
Tipik bir kayıt girişi aşağıdaki şekilde gözükebilir:
--67458b6b-A--
[15/Jul/2005:11:56:52 +0100] G3yTd38AAAEAAAM7BLwAAAAA \
192.168.2.11 4236 192.168.2.101 8080
--67458b6b-B--
POST /form.php HTTP/1.1
Host: 192.168.2.101:8080
User-Agent: Mozilla/5.0
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-9,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://192.168.2.101:8080/form.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
--67458b6b-C--
f=111
--67458b6b-E--
403 (Response body)
--67458b6b-F--
HTTP/1.1 403 Forbidden
Last-Modified: Fri, 08 Jul 2005 14:25:30 GMT
ETag: "decb4-3-34b96a80"
Accept-Ranges: bytes
Content-Length: 19
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html
--67458b6b-H--
Message: Pattern match "111" at POST_PAYLOAD \
[id "1"] [rev "2"] [msg "3"] [severity "4"]
Apache-Handler: application/x-httpd-php
Stopwatch: 1126536042708000 11024 (7276* 7375 9842)
--67458b6b-Z--
Not
Denetleme kayıt verilerini incelerken dikkat ediniz. Dosyalar ağdan alınan ve filtrelenmemiş veriler içerebilirler. Eğer doğru bir şekilde işlenmezlerse bu tür veriler tehlikeli olabilir (yani bazı terminal kaçırma dizgileri (escape sequences) içerebilirler).
Kullanılabilir denetleme kayıt bölümleri:
· A – denetleme kayıt başlığı (zorunlu)
· B – istek başlıkları
· C – istek gövdesi (body) (sadece eğer istek gövdesi varsa ve ModSecurity bunları yakalamak için yapılandırılmışsa)
· D – ara (intermediary) cevap başlıkları (Sadece cevap gövdesinde ModSecurity’nin istemciye ulaşmasını engelleyecek bir problem oluştuğunda bu bölüm bulunur).
· E – ara (intermediary) cevap gövdeleri (Sadece ModSecurity cevap gövdesini yakalayacak şekilde yapılandırıldığında, ve denetleme kayıt moturu bu durumu kayıt edecek şekilde yapılandırıldığında). Ara cevap gövdeleri gerçek cevap gövdesi ile ancak ModSecurity ara cevap gövdesini yakalamaz ise aynı olur. Ki bu durumda gerçek cevap gövdesi hata mesajını içerir (Apache varsayılı hata mesajını veya ErrorDocument sayfasını).
· F – son cevap başlıkları (Apache tarafından her zaman son anda eklenen Date ve Server başlıklarını dışarıda tutarak).
· G – RESERVE EDİLMİŞ (gerçek cevap gövdesi, şu anda gerçekleştirilmedi)
· H – denetleme kayıt izleri
· Z – son sınır (boundary), girişin (entry) sonunu belirtmesi amacıyla (zorunlu)
1.9’dan beri ModSecurity yeni bir direktifi destekler, SecGuardianLog. Bu direktif bütün erişim verisini kanallama kayıt (piped logging) özelliğini kullanarak diğer bir programa göndermek için dizayn edildi. Apache tipik olarak, veri paylaşımını zorlaştıran çoklu süreç şeklinde koşulduğu için, ana fikir bütün istekleri durumları muhafaza edilecek şekilde (stateful) gözleyecek ve böylece ek koruma sağlayacak bir tek harici süreç çalıştırılmasıdır.
Harici bir koruma aracı geliştirmesi bundan sonraki ModSecurity dağıtımlarının ana konusu olacaktır. Ama, bütün özellikleri ile çalışan bir araç, Apache httpd araçları projesinin bir parçası olarak zaten kullanılabilir (http://www.apachesecurity.net/tools/). Aracın ismi httpd-guardian ve Hizmet Dışı Bırakma saldırılarına karşı kullanılabilir. iptables tabanlı güvenlik duvarları ile iletişim kurmak için blacklist aracını kullanır ve dinamik olarak saldıran IP adreslerini bloke eder. httpd-guardian’ın hali hazırda kurulduğunu farzederek (daha detaylı talimatlar için kaynak koduna bakın) kurmak için Apache yapılandırmanıza sadece bir satır eklemeniz gerekir:
SecGuardianLog |/path/to/httpd-guardian
Varsayılı olarak (by default) httpd-guardian dakikada 120 veya beş dakika içerisinde 360 istekten fazla yollayan istemcilere karşı koruyacaktır.
Özel yapım (custom) kayıt tutma
1.8’den beri Apache’nin özel yapım kayıt tutmasını sadece mod_security’nin işin içine karıştığı isteklerde kullanmak mümkündür. Çünkü ModSecurity şimdi herhangi bir işlem yaptığında mod_security-relevant çevre değişkenini tanımlar. Özel yapım kayıt dosyasını kullanmak için, yapılandırmanıza aşağıdakini (veya benzerini) ekleyin:
CustomLog logs/modsec_custom_log \
"%h %l %u %t \"%r\" %>s %b %{mod_security-message}i" \
env=mod_security-relevant
Empedans (Impedance) uyumsuzluğu
Web uygulama güvenlik duvarları korudukları uygulama ve onların kullandıkları iş mantığını bilmeden, gelip geçen verilerden anlam çıkarmakta zorlanır. Getirdikleri koruma dışarıdan sağladıkları bağımsız bir güvenlik katmanı ile gelir. Veri denetlemesi iki kere yapıldığından uygulamaya dokunulmadan güvenlik sağlanmış olur. Ama bazı durumlarda her şeyin iki kere yapılması beraberinde problemler getirir. Problemler, iletişim protokollerinin tam olarak anlatılamadığı veya, aracın veya uygulamanın spesifikasyonlara uyumsuzluk içerdiği durumlarda oluşabilir.
En kafa karıştıranı cookie spesifikasyonudur. (Aslında dördü de: http://wp.netscape.com/newsref/std/cookie_spec.html, http://www.ietf.org/rfc/rfc2109.txt, http://www.modsecurity.org/documentation/<?xml version=%221.0%22?> <ns:clipboard xmlns:ns=%22http://www.xmlmind.com/xmleditor/namespace/clipboard%22 ><ulink url=%22???%22 >http://www.ietf.org/rfc/rfc2964.txt</ulink ></ns:clipboard >, http://www.ietf.org/rfc/rfc2965.txt.) Gerçek hayattaki bir çok durumda spesifikasyon ile uygun olmayan ve programcıyı neyi uygun görürlerse onu gerçekleyecekleri durumla karşılaşırsınız. Büyük bölüm için bu bir problem değildir çünkü bir çok cookie doğru oluşturulmuştur. Aynı zamanda birçok uygulama kendi oluşturduğu cookieyi ayrıştırdığı için uyumsuzluk problemi çok yaygın olarak göze çarpmaz. Bir web uygulaması güvenlik duvarı veya atlatmaya çalışan bir saldırgan gözüyle baktığınızda bir problemin olduğunu görürsünüz. 1.8.x dalında ve 1.8.6’ya kadar, ModSecurity (1.8.7’e değişiklikler yapılmıştır) bir v1 ayrıştırıcısı kullanmıştır. Ama v0 ve v1 arasındaki farklar, v1’in sadece bir v0 ayrıştırıcısının ise birden fazla cookie göreceği şekilde saldırlarda kullanılabilir. Aşağıdakini düşünün:
Cookie: innocent="; nasty=payload; third="
Bir v0 ayrıştırıcısı çift tırnaktan anlamaz. Tipik olarak noktalı virgülleri arar ve başlığı (header) buna göre böler. Böyle bir ayrıştırıcı cookieleri innocent, nasty, ve third şeklinde görür. Ama diğer taraftan bir v1 ayrıştırıcısı cookieleri sadece olarak innocent görür.
Empedans uyumsuzluğu web uygulama güvenlik duvarı kullanıcılarını ve geliştiricileri nasıl etkiler? İşimizi daha zor hale sokar ama önemli değil – ne de olsa oyunun bir parçası. Geliştiriciler daha akıllı ve iyi ayrıştırıcı (parser) fonksiyonları bulmaya çalışmalıdırlar. Mesela, ModSecurity 1.8.7’de iki cookie ayrıştırıcısı vardır ve kullanıcı hangisini kullanacağını seçebilirler. (Varsayılı olarak şimdi bir v0 ayrıştırıcısı kullanılmaktadır) Ama bu gelişmeler, otomatikleştirilemedikleri için, güvenlik duvarını kullanmayı daha zor hale getirir – kullanıcılar için düşünülmesi ve yapılandırılması gereken bir şey daha.
Diğer taraftan, cookie ayrıştırıcıları hakkında düşünmek istemezlerse kullanıcılar daha iyi tanımlanmış HTTP parçalarını kullanabilirler. Mesela başlıklar. Bireysel bir cookieyi hedef alan COOKIE_innocent kullanmak dışında HTTP_Cookie kullanarak bütün cookie başlığını hedef alabilirler. ARGS gibi diğer değişkenler, saldırganlar ne kadar saklamaya çalışırlarsa çalışşınlar, bütün değişkenleri inceleyeceklerdir.
ModSecurity ile beraber küçük bir HTTP test etme aracı da geliştirilmiştir. Sunucuya özel yapım HTTP isteklerini göndermek ve sonra saldırının anlaşılıp anlaşılmadığını kontrol etmek içim kolay ve basit bir yol sağlar.
Aracın hiç bir parametre ile çağırılmaması kullanılma biçimini çıktı olarak basacaktır:
$ ./run-test.pl
Usage: ./run-test.pl host[:port] testfile1, testfile2, ...
İlk parametre, port numarası opsiyonel olacak şekilde, sunucunun ismidir. Diğer bütün parametreler özel yapım HTTP isteklerinin bulunduğu dosyalardır.
İşinizi biraz daha kolaylaştırmak için, araç bazı istek başlıklarını otomatik olarak üretecektir:
· Host: hostname
· User-Agent: mod_security regression testing utility
· Connection: Close
Eğer gerekiyorsa bu başlıkları istekte de bulundurabilirsiniz. Ordalarda, araç bu değerleri eklemeyecektir.
İşte bir HTTP isteğinin nasıl gözüktüğü:
# 01 Simple keyword filter
#
# mod_security is configured not to allow
# the "/cgi-bin/keyword" pattern
#
GET /cgi-bin/keyword HTTP/1.0
Diğer ek başlıklar olmadan, bu istek sadece bir satırdan oluşur. İstediğiniz kadar karmaşık istekler üretebilirsiniz. İşte POST metodunun kullanılışına dair bir örnek:
# 10 Keyword in POST
#
POST /cgi-bin/printenv HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
p=333
Dosyanın başında bulunan ve # ile başlayan satırlar yorum olarak işlenirler. İlk satır özeldir ve testin ismini içermelidir.
Araç sonuç olarak 200 durum kodunu bekler ve bu şekildeki cevapları başarılı olarak algılar. Eğer başka cevaplara ihtiyacınız varsa, bunu ilk satırda (herhangi bir yerinde) göstermeniz gerekir. Şunun gibi:
# 14 Redirect action (requires 302)
GET /cgi-bin/test.cgi?p=xxx HTTP/1.0
Parantezler ve “requires” anahtar kelimesi gerekli değildirler ama daha iyi okunabilmeleri için önerilirler.
Yaygın Güvenlik Problemlerini Çözmek
Size ModSecurity’nin yeteneklerinin bir örneği olarak bazı yaygın güvenlik problemlerini nasıl yakaladığını ve engellediğini göstereceğiz. Burada problemler hakkında detaylara girmeyeceğiz ama çok iyi bir açıklama Open Web Application Security Project kılavuzunda bulunabilir, http://www.owasp.org/documentation/guide/guide_downloads.html.
Dizin gezinimi (Directory Traversal)
Eğer betiğiniz dosya sistemi ile uğraşıyorsa o zaman bazı yardımcı karakterlere ve yapılara dikkat etmeniz gerekir. Mesela, bir dizindeki ../ karakter kombinasyonu dizin seviyesinde bir seviye yukarı çıkmak isteği anlamına gelir.
Normalde bu karakter kombinasyonunun isteklerde bulunmasına gerek yoktur ve aşağıdaki filtreyi kullanarak yasaklayabilirsiniz:
Siteler arası betik çalıştırma (Cross site scripting) saldırıları
Siteler arası betik çalıştırma (XSS) saldırıları, saldırgan Web sayfalarına HTML ve/veya JavaScript kodu enjekte eder ve sonra bu kod daha sonra diğer kullanıcılar tarafından çalıştırılır. Bu genellikle beklemediğiniz yerlere HTML eklemekle olur. Başarılı bir XSS saldırısı saldırganın oturumunuzun cookiesini elde etmesi ile ve uygulamaya tam yetki ike erişmesiyle sonuçlanabilir.
Bu saldırı için düzgün savunma parametre filtrelemesidir (yani zararlı HTML/Javascript’ların silinmesi) ama genellikle hali hazırda bulunan uygulamaları değiştirmeden korumanız gerekir. Bu aşağıdaki filtrelerden herhangi birisi ile yapılabilir:
SecFilter "<script"
SecFilter "<.+>"
İlk filtre, <script> etiketi (tag) ile yapılan JavaScript enjeksiyonuna karşı koruma sağlar. İkinci ise daha geneldir ve parametreler içerisindeki bütün HTML kodunu reddeder.
Bu tür bir filtreyi uygularken çok dikkat etmeniz gerekir çünkü bir çok uygulama parametrelerde HTML ister (mesela, CMS uygulamaları, forumlar, v.b.). Bunu seçmeli filtreleme ile başarabilirsiniz. Örneğin, ikinci filtreyi genel bir site-boyu kuralı olarak alabilir ama daha sonra belli uygulamalar için aşağıdaki kodla durumu gevşetebilirsiniz:
<Location /cms/article-update.php>
SecFilterInheritance Off
# other filters here ...
SecFilterSelective "ARGS|!ARG_body" "<.+>"
</Location>
Bu kod parçası sadece isimli parametre gövdesindeki HTML’I kabul edecektir. Gerçekte bu listeye bir kaç daha fazla isimli parametre eklemek isteyebilirsiniz.
SQL/veritabanı saldırıları
Şimdilerde bir çok web uygulaması veri manipulasyonu için çoğu zaman veritabanlarını kullanılırlar. Veritabanı erişimi büyük bir özenle güvenli hale getirilmezse, bir saldırgan gelişigüzel SQL komutlarını veritabanına enjekte edebilir. Bu da saldırganın hassas verileri okuması, değiştirmesi veya silmesi ile sonuçlanabilir.
Aşağıdaki gibi filtreler:
SecFilter "delete[[:space:]]+from"
SecFilter "insert[[:space:]]+into"
SecFilter "select.+from"
sizi bir çok SQL ile ilgili saldırıdan koruyabilir. Bunlar sadece örnektirler ve gerçekte kullandığınız veritabanı motoruna göre dikkatlice filtreler hazırlamanız gereklidir.
İşletim sistemi komut yürütme (command injection)
Web uygulamaları bazen işlemler gerçekleştirmek için işletim sistemi komutları çalıştıracak şekilde yazılırlar. Kararlı bir saldırgan bu kapsamda bir açıklık bulursa, sistemde gelişigüzei komutlar çalıştırabilir.
Aşağıdaki gibi bir filtre:
SecFilterSelective ARGS "bin/"
Unix gibi işletim sistemlerinde değişik dizinlerde bulunan ikililerin (binaries) çalıştırılmasını engeller.
Arabellek taşması saldırıları
Arabellek taşırması bir programın yürütme yığıtını taşırmak ve çalıştırma amacıyla assembly komutlarını ekleme tekniğidir. Bazı durumlarda aşağıdakine benzer bir satır ile bu tür saldırıları engellemek mümkündür:
SecFilterByteRange 32 126
Çünkü böylece sadece bazı bayt aralığında olan istekler kabul edilecektir. Bu tür bir korumayı kullanıp kullanmayacağınız nasıl bir uygulamanız olduğuna ve hangi karakter kodlamalarının kabul edildiğine göre değişir.
Birden fazla aralığı desteklemek isterseniz, düzenli ifadeleri (regular expression) kullanabilirsiniz. Bunun gibi bir şey kullanabilirsiniz:
SecFilterSelective THE_REQUEST "!^[\x0a\x0d\x20-\x7f]+$"
PHP uygulamalarını korumak amaçlı kod yazarken PHP’ye has özelliklerin akılda bulundurulması gerekir. Çoğu zaman kendi kendinize saldırırken çalışan bir kuralın başka bir saldırı çeşidini kaçırması kolaydır. Aşağıda bildiğim bazı durumların listesi vardır:
· register_globals On olarak kullanıldığında, istek parametreleri global değişkenler olurlar. (PHP 4.x’te GLOBALS dizgisini bile değiştirmek mümkündür)
· Cookieler istek parametreleri şeklinde işleme tabi tutulurlar.
· Parametrelerin başındaki boşluklar görmezden gelinir.
· (Parametre isimlerindeki) geri kalan boşluklar alt çizgi haline dönüştürülür.
· Çevre değişkenlerinden ve isteklerden alınan parametrelerin sırası EGPCS’dir ((environment, get, post, cookies, kurulu -builtin- değişkenler). Bu, bir POST parametresinin istek satırındaki parametreleri değiştireceği anlamına gelir.
· magic_quotes_gpc On olarak kullanıldığında, PHP ters bölme işaretini kullanarak şu karakterleri kaçırır (escape): tek tırnak, çift tırnak, ters bölme ve NULL
· Eğer magic_quotes_sybase On olarak kullanılıyorsa, sadece tek tırnak diğer bir tek tırnak ile kaçırılır (escape). Bu durumda magic_quotes_gpc değeri bir anlam ifade etmez.
register_global problemlerini engelleme
Bu günlerde, PHP’nin register_globals özelliğinin kullanılmasının güvenlik açıkları oluşturduğu kabul edilir, ama her zaman böyle değildir (bu özelliğin ne olduğunu bilmiyorsanız, büyük ihtimalle kullanmıyorsunuzdur, ama okumaya devam ederseniz bilginiz artmış olur). Aslında, register_globals özelliği 4.2.0 sürümüne kadar varsayılı olarak açıktı. Sonuç olarak, varolan bir çok uygulama bu özelliğe bağımlıdır (daha fazla detay için http://www.php.net/register_globals).
Eğer bir seçme şansınız varsa, bu özelliği kullanmayacak şekilde kodu değiştirmek en iyisidir. Ama o veya bu şekilde bunu yapamazsanız, bir uygulamayı bilinen bir açıklıktan ModSecurity kullanarak koruyabilirsiniz. Problemli kod parçası genellikle şu şekilde gözükür:
<?php
// this is the beginning of the page
if ($authorised) {
// do something protected
}
// the rest of the page here
?>
Ve saldırgan bu durumu URL’ye ek bir parametre ekleyerek avantaj elde eder. Mesela, http://www.modsecurity.org/examples/test.php?authorised=1
Problemdeki parametreyi doğrudan belirten istekleri reddetmek uygulamayı bütün saldırganlardan korumaya yeterli olacaktır:
Yukarıdaki filtre, “authorised” değişkeninin boş olmadığı bütün istekleri reddeder. Aynı zaman filtrelemeyi web sunucusunun sadece ilgili parçalarına uygulamak için <Location> başlıklarını kullandığımızı görebilirsiniz.
ModSecurity tarafından sağlanan korumanın bir bedeli vardır, ama genellikle çok düşüktür. Web sunucunuz çok az yavaş ve biraz daha fazla hafıza tüketir hale gelir.
Bir isteği analiz etmek için, ModSecurity istek verisini hafızada tutar. Bir çok durumda istekler küçük olduğundan bu durum bir sorun yaratmaz. Ama, web sitesinin, dosyaların karşıdan yüklendiği bölümlerinde bir problem oluşturabilir. Bu problemi önlemek için web sitesinin o bölümlerinde istek gövde (body) tamponlamasını kapatmanız gerekir (Bu sadece Apache 1.x sürümünde bir problem yaratır. Apache 2.x bir istek saklamak için çok büyük olduğunda disk üzerinde geçici bir dosya kullanacaktır). Her durumda Apache yapılandırmasında bazı kısıtlandırmaları değerlendirmeli ve yapılandırmalısınız (İlgili direktifler LimitRequestBody, LimitRequestsFields, LimitRequestFieldsize and LimitRequestLine için http://httpd.apache.org/docs/mod/core.html#limitrequestbody).
Hata ayıklama özelliği gerçekten yardımcı olabilir ama her istek için büyük ölçülerde veriyi dosyaya yazar. Bu nedenle meşgul sunucular için bir dar boğaz yaratır. Üretim sunucularında hata ayıklama özelliğini açık tutmak için hiçbir neden yoktur.
Denetleme kayıt özelliği de aynı şekildedir ve dahası açık tutulduğunda iki dar boğaz yaratır. Öncelikle, büyük ölçülerdeki veri diske yazılır ve ikincisi dosyaya erişim senkronizasyonlu olmalıdır. Eğer yine de denetleme kaydını kullanmak istiyorsanız, senkronizasyon performans kaybını minimize etmek için bir çok denetleme kayıt dosyası (sunucuda çalışan her uygulama için) oluşturmaya çalışın (bu öneri Apache 2.x’deki performans kaybını ortadan kaldırmaz çünkü senkronizasyon merkezi bir mutex tarafından sağlanmaktadır).
Lütfen aşağıdaki notları okuyun:
· Yapılandırma dosyasına eklediğiniz her filtrenin etkisini dikkatlice düşünmelisiniz. Özellikle erişimi, çok geniş kurallar kullanarak, kapatmak istemezsiniz. Geniş kurallar çoğunlukla yanlış artılar (false positives) yaratırlar.
· ModSecurity .htaccess dosyalarında (bunu yapabilmek için AllowOverride Options gereklidir) kullanılabilse de, güvenmediğiniz kişiler tarafından kullanılabilecek şekilde açılmamalıdır. Eğer bu konuda paranoyaksanız, bu özelliği ModSecurity’i -DDISABLE_HTACCESS_CONFIG parametresi ile derleyebilirsiniz (apxs aracına bir parametre olarak).
mod_security’nin koştuğu Apache kancasını (hook) değiştirme
Varsayılı olarak mod_security Apache istek ön-işlemesinin mümkün olan en son noktasında, ama isteği çalışamaya başlayacağı ilk noktada çalışmaya (mesela mod_php tarafından çalıştırılmadan) çalışacaktır. Böyle bir yaklaşımı uygun gördüm çünkü mod_security’nin en önemli fonksiyonu uygulamayı korumaktır. Diğer taraftan böyle yaparak, hakkında yapacağımız şeyler olduğu halde, Apache’nin bazı bölümlerini korumasız bırakırız. Denemek isteyenler için, 1.9dev3 ile beraber mod_security, mümkün olabilecek en erken noktada çalışacak şekilde derlenebilir. -DENABLE_EARLY_HOOK ile derlemeniz yeterli. Bunun deneysel bir özellik olduğu aklınızda bulunsun. Keşfedeceğiniz bazı farklılıklar:
· Apache işlemeden geçersiz istekleri yakalamak artık mümkün olmalıdır
· Diğer türlü, Apache tarafından işlenecek istekleri değerlendirmek mümkün olacaktır (mesela TRACE)
· Sadece sunucu boyu kurallar koşacaktır. Çünkü bu noktada Apache isteği yola eşleştirmemiştir.
ModSecurity’nin ilerki sürümleri büyük ihtimalle kural işlemeyi iki faza ayıracaktır. Birisi mümkün olabilecek en erken zamanda ve diğeri mümkün olan en geç zamanda.
Düzenli ifadeler (regular expressions) çok güçlü olabilirler. Aşağıdaki ile bir tam sayının 0 ile 99999 aralığında olup olmadığını kontrol edebilirsiniz:
SecFilterSelective ARG_parameter "!^[0-9]{1,5}$"
Uygulamanın bütününde karşıdan dosya yüklemeyi yasakla ancak bir alt dizin için izin ver:
# Reject requests with header "Content-Type" set
# to "multipart/form-data"
SecFilterSelective HTTP_CONTENT_TYPE multipart/form-data
# Only for the script that performs upload
<Location /upload.php>
# Do not inherit filters from the parent folder
SecFilterInheritance Off
</Location>
FormMail
’i güvenli hale getirme
FormMail’in önceki sürümleri herhangi bir alıcıya e-posta göndermek için kullanılabilirdi (Düzgün olarak güvenli hale getirilebilen yeni bir sürümü olduğunu duydum).
# Only for the FormMail script
<Location /cgi-bin/FormMail>
# Reject request where the value of parameter "recipient"
# does not end with "@webkreator.com"
SecFilterSelective ARG_recipient "![a-zA-Z0-9]+@webkreator\.com$">
</Location>
Ek A: Önerilen Yapılandırma
Aşağıda önerilen en kısa mod_security yapılandırması verilmiştir. Sadece, size ani bir baş ağrısı vermemesi için dizayn edilmiş bir başlangıç noktasıdır. Yapabildiğiniz her noktada yapılandırmayı sıkılaştırmalısınız.
# ModSecurity’i aç
SecFilterEngine On
# 403
durumlu istekleri reddet
SecFilterDefaultAction "deny,log,status:403"
# bazı akıllıca işlemler
SecFilterScanPOST On
SecFilterCheckURLEncoding On
SecFilterCheckUnicodeEncoding Off
# hemen hemen her bayt aralığını kabul et
SecFilterForceByteRange 1 255
# sunucu maskelemesi isteğe bağlı
# SecServerSignature "Microsoft-IIS/5.0"
SecUploadDir /tmp
SecUploadKeepFiles Off
# sadece ilginç şeyleri kaydet
SecAuditEngine RelevantOnly
SecAuditLog logs/audit_log
# normalde hata ayıklama kaydına ihtiyaç duymazsınız
SecFilterDebugLevel 0
SecFilterDebugLog logs/modsec_debug_log
# sadece nasıl işleneceğini bildiğimiz istek kodlamaları kabul et
# sadece GET isteklerini dışarıda tutuyoruz çünkü
# bazı (otomatik) istemciler Content-Type olarak "text/html" gönderir
SecFilterSelective REQUEST_METHOD "!^(GET|HEAD)$" chain
SecFilterSelective HTTP_Content-Type \
"!(^application/x-www-form-urlencoded$|^multipart/form-data;)"
# gövdeleri (body) olan GET veya HEAD isteklerini kabul etme
SecFilterSelective REQUEST_METHOD "^(GET|HEAD)$" chain
SecFilterSelective HTTP_Content-Length "!^$"
# Content-Length alanının bütün POST isteklerinde
# bulunmasını denetle
SecFilterSelective REQUEST_METHOD "^POST$" chain
SecFilterSelective HTTP_Content-Length "^$"
# nasıl işleneceğini bilmediğimiz transfer kodlamalarını kabul etme
SecFilterSelective HTTP_Transfer-Encoding "!^$"
Yazar & Kaynak: EnderLinux http://www.thinkingstone.com/
Eklenme tarihi: 23-8-2006
|

| Bu Makaleye Verilen Puan: |
Bu makaleye puan verilmemiş.
|
Kullanıcı Yorumları
Bu makaleye yorum gönderilmemiş, ilk yorumu sen gönder !
Yorum Ekle
İlgili Dökümanlar
|
Apache kurulumu
Bugün internette web sunucuların %60'ını Apache oluşturmaktadır. Sağlamlık, güvenilirlik ve yüksek performansın yanı sıra Apache'nin bu yaygınlığının en önemli nedenleri de çok...
|
|
Hile Kılavuzu
Artık bizlerde oyun için yazılım üretebiliyoruz. Her ne kadar, şimdiye kadar dünya piyasalarına yönelik oyun üretmesekte, bunun sinyalini veren bir programımız var. Hile Kılavuzu. ...
|
|
Uzay aracı yapma kılavuzu!
Ay'a giden ilk uzay aracı herkesin malumu. Lunar ismini taşıyan bu özel araç, yıllar önce Ay'ın üzerinde hareket ettiğinde gündeme bomba gibi düşmüş,...
|
|
Knightonline Kullanıcı Ara Yüzü
Bir oyunu oynamak için öncelikle karşımıza çıkan pencere ve tuşların ne işe yaradığını bilmemiz gerekli. Bir oyunun profesörü de olsanız, yapmak istediğiniz şeyi nasıl yapacağınızı bilmiyorsanız ekran...
|
|
|
|