24 Kasım 2012 Cumartesi

HTTP DoS'a Karşı Javascript'le Mücadele - Nass oluyor da oluyor?

Uygulama katmanında TCP protokolüne dayalı sunulan hizmetleri hedef alan saldırılar çoğunlukla gerçekleştirilmesi ve engellenmesi en zor olanlardır. Gerçekleştirilmesi zordur çünkü genellikle 3WHS ( 3-way-handshake ) gerektirir yani sahte IP adresleri kullanamazsınız, bu durumda saldırıyı ya kendi bilgisayarınızdan ya da zararlı ( hedeftekilere göre :) ) yazılımınızı bir şekilde bulaştırdığınız,yüklediğiniz ve bot sürünüze dahil ettiğiniz zombie bilgisayarlar aracılığıyla yapmalısınız kardeşlerim. Saldırı kaynağı gerçek,kanlı canlı olunca zararlıyı zararsızdan ayırd etmesi ve bu nedenle engellenmesi de zorlaşır.

Bu yazıda özellikle son birkaç yılın durdurulması en zor saldırı yöntemlerinden HTTP DoS ( ya da HTTP Flood ya da HTTP GET Flood ya da HTTP DDoS ) ile mücadelede javascript'ten nasıl faydalanabileceğinizi anlatmaya çalışacağım,bu yazı sadece yol gösterici ve fikir verici olacak çok büyük beklentiler içine girmeyin. Ele alacağımız senaryoda saldırının bant genişliğini doldurmak değil, web sunucusu kaynaklarını meşgul etmek suretiyle hizmet veremez hale getirmek amaçlı olduğunu da peşin peşin belirteyim. Bant genişliğini doldurma hedefli dağıtık bir saldırıyı artık ISP'de alınabilecek önlemler de engelleyemiyor. Anycast routing,visitor reputation gibi yöntemler kullanan farklı coğrafi konumlardaki veri merkezleri ile bu konuda profesyonel hizmet firmalardan destek almalısınız.


Dağıtık yedince katman saldırılarında saldırıyı engelleme başarısı normal istekleri saldırı niyetli isteklerden ayırd etme başarısıyla paralellik gösterir. Bu da hiç kolay bir iş değildir aslında. Eskiden bu tip saldırı ya da tarama araçlarından kaynaklanan erişim trafiğinde kolayca fark edilebilen ve engellemede kullanılan "User Agent header değerinin XX olması", "X header'ın Y header'ından önce gelmesi", istekte "Z header'ının olmaması" gibi özellikler kod yazarlar temel protokolleri öğrendikçe ya da tam tersi, protokol bilgisi olanlar kod yazmayı öğrendikçe ortadan kalkmaya başladı. Bu da saldırı ya da tarama araçları kaynaklı HTTP istekleri normal isteklerden ayırt etmeyi zorlaştırdı.Şöyle ki, günümüzde saldırı araçları ile gönderilen HTTP istekleri,normal bir web tarayıcısıyla (browser) gönderilen isteklerdeki tüm headerları olması beklendiği ve gerektiği gibi standartlara uygun olacak şekilde içerebilmekte. Zararlı ya da kötü niyetli erişim isteklerini normal ( iyi niyetli müşteri ya da ziyaretçi ) isteklerinden ayırt etmek için "captcha" kullanma gibi yöntemler tercih edenler oldu. Ama bu tip saldırılarla mücadele ederken amacınız zararlı olmayan ziyaretleri de karmaşık captcha kodlarıyla işkenceye çevirmek olmamalı. Benzer şekilde bazı web sunucular için geliştirilen güvenlik modüllerinin çoğunun kullandığı "rate-limiting" temelli "bir ip'den saniyede x istek gelirse engelle" benzeri yöntemlerde normal ve zararsız isteklerin engellenmesine,kuruyla birlikte yanmasına,arada kaynamasına neden olabilir.

Daha akılcı yöntemlere ihtiyaç var ve şu an itibariyle (bir çok ticari güvenlik cihazında ve yukarda bahsettiğim profesyonel firmada da kullanılan) bu akılcı yöntemlerden biri javascript ile cookie kullanımı. Saldırı araçlarının büyük çoğunluğu browser stack'ini kullanmaz,dolayısıyla en yaygın tarayıcı ürünlerin desteklediği javascript gibi script dillerini ya da flashplayer gibi eklentileri desteklemez. Biraz saçma oldu saldırı aracının bir dili ya da eklentiyi desteklemesi ama siz eminim anlatmak istediğimi anlamışsınızdır. Temel prensip gelen her isteği asıl ( hedef ) sunucudan önce karşılamak ( Resim 1) , isteğin kanlı canlı bir insan evladından gelip gelmediğini anlamak olmalı.İnsan evladından gelen istekleri hedefteki sunucuya gönderirken de asıl hizmet dışı bırakılmak istenen sunucunun IP adresini ya da URL'ini belli etmemelisiniz, HTTP Redirection bu yüzden kullanmanızı önermeyeceğim bir yöntem.Saldırı araçlarının çoğunluğu web sunucusunun gönderdiği cevaplarla da ilgilenmez, tek istedikleri web sunucunun normal karşılayacağı bir istek göndermek bir 1-2 dakikalığına da olsa sunucu kaynaklarını bu gereksiz,fuzuli istekle meşgul etmektir. HTTP Redirection ile çoğu zaman ilk saldırı trafiğinden arınmak da bu nedenle mümkün (*).Saldırıyla mücadele ederken şunu da akılda tutmanız lazım, saldırının başındaki kişi ya da kişiler bir yandan komutaları altındaki sürüye (bot-net,zombie-net)  "haydi aslanlar yardırın" şeklinde hedef gösterirken diğer yandan da "hedefte herhangi bir yönlendirme var mı? hedef URL ya da IP adresini değiştirmeye gerek var mı?" diye kontrol ederler. Alemin tek akıllısı siz olmayabilirsiniz. (*) .


Resim 1
(http://habrahabr.ru/post/139931/)

Yapılması gereken şey basit, HTTP isteğinin javascript ya da flashplayer destekleyen bir uygulamadan gelip gelmediğini kontrol etmek, ki bu yazıda sadece javascript üzerine duracağım. Resim 1'deki akış bunu yapmanın en basit yollarından birini gösteriyor. HTTP isteğini karşılayan mekanizma istemcide cookie oluşturmaya neden olacak kodu çalıştırarak, istemciden aynı URL'e ikinci bir itekte bulunmasını istiyor. İstemci şayet javascript koduyla cookie'yi oluşturabilir ve ikinci isteğiyle birlikte gönderdiği cookie'yi doğrulatabilirse, isteğin bir insandan geldiği kanaatine varılıyor ve istek hedefteki asıl sunucuya iletiliyor. Eğer HTTP isteği bir bottan,zombi'den ya da otomatik istek gönderen bir araçtan geliyorsa cookie oluşturma,aynı sayfaya tekrar cookie ile erişme gibi adımlara geçemiyor zaten ve gönderdiği tüm istekler ilk karşılayan ve Resim 1'de "Nginx" ile gösterilen bloğu aşamıyor. Böylece asıl hizmetin sunulduğu ve Resim 1'de "Backend" bloğuyla gösterilen sunucu zararlı ya da normal olmayan istekten etkilenmiyor. Nginx'i bilmeyenler olabilir,birçok büyük ve çok ziyaretçili web sitesinde kullanılan, IIS ve Apache ile kıyaslandığında çok daha düşük donanım kaynağıyla çok daha fazla yükü kaldırabilen bir web sunucu platformudur kendisi. Dinamik programlama dili desteği az olduğu için pek tercih edilmiyor ama özellikle bu tip saldırılarla mücade için ideal, url-rewrite / reverse-proxy gibi özellikleri mevcut. Yukarda bahsettiğim gibi normal ve zararsız olsa dahi, bir HTTP isteğini yanıtlarken hedefteki asıl sunucunun IP adresi,URL'i gibi bilgileri afişe etmemeye çalışın (url rewriting ya da reverse proxy yöntemleri kullanın), saldırının başındaki kişi tüm istekleri her an farklı IP'lere yada URL'lere yönlendirebilir. Oluşturulacak cookie'nin değişken olması da önemli. İstek yapan IP ve sunucu tarafında kullanılacak bir anahtar kelime ( secret key) kullanılarak hesaplanacak ve istemcide oluşturulacak cookie,aynı cookie'nin birden fazla bot'ta hatta bütün bot sürüsünde kullanılmasını önleyecektir.

ASP'ye aşina olduğum ve php kodlamayalı uzun zaman olduğu için örnek olması bakımından aşağıdaki gibi bir sayfa hazırladım,fikir versin şifa olsun; daha da kestirme yoldan gitmeyi düşünenler "nginx roboo" eklentisini inceleyebilirler.

aspcookie.asp
<!--#include file="md5.asp"-->
<%
Response.CacheControl = "no-cache"
Response.AddHeader "Pragma", "no-cache"
Response.Expires = -1
%>
<html>
<head>
</head>
<body>
<%
istemci_ip=Request.ServerVariables("REMOTE_ADDR")
secret="cantddosme"
response.write istemci_ip&"<br>"
cookiemd5=md5(istemci_ip&secret)
response.write md5(istemci_ip&secret)&"<br>"
if Request.Cookies("insanbot")<>"" Then
 'Beklenen cookie var,cookie değeri kontrol edilecek
 if cookiemd5=Request.Cookies("insanbot") then
  'Cookie değeri beklenen değer,istek bottan gelmiyor.
  'Bundan sonrasi sizin hayal gücünüze kalmış.Asil
  'Sunucuyu belli etmeden istekleri cevaplamalısınız
  'URL Rewrite veya Reverse Proxy yöntemlerini
  'kullanabilirsiniz.
 else
  response.write "Cookie var ancak doğru değil."
 end if
else
' cookie yok,javascriptle cookie set et
%>
<script type="text/javascript">
var exdate=new Date();
exdate.setDate(exdate.getDate() + 365);
var c_value=escape("<%=cookiemd5%>") + "; expires="+exdate.toUTCString();
document.cookie="insanbot=" + c_value;
window.location = "aspcookie.asp?try=2"
</script>
<% 
end if
%>
</body>
</html>


Şimdiye kadar birkaç paranoyak dışında browserlarında javascript çalıştırma özelliğini devre dışı bırakan,cookie oluşturma özelliğini kapatan görmedim. Dolayısıyla yapılacak kontrollerde javascriptin kullanılmasının en kötü ihtimalle en fazla 1-2 saniyelik bir gecikme dışında problem çıkaracağını hiç düşünmüyorum. Zararlı trafiği filtrelemek için güzel bir yöntem,en azından saldırganlar sunucudan dönecek cevapları yorumlayan, cookie kullanabilen saldırı araçları geliştirene kadar.

İlgili Yazılarım
(*) Low Orbit Ion Cannon ( LOIC ) ve Http Redirection Yanılsaması - Nass oluyor da oluyor?

2 yorum: