CRLF Injection ve HTTP Response Splitting Zafiyeti

Sven Morgenroth - 23 Ocak 2017 -

Bu yazımızda CRLF Injection zafiyetinin ne olduğu ve bu zafiyetin kurbanın web tarayıcısını kandırmaya yönelik yapılan HTTP response splitting veya HTTP header injection saldırılarına nasıl zemin hazırladığını anlattık.

CRLF Injection ve HTTP Response Splitting Zafiyeti

CRLF Nedir?

Web tarayıcısı sunucuya bir istekte bulunduğunda sunucu, yanıt olarak HTTP header’ları ve web sitesinin içeriğini birlikte gönderir. Söz konusu HTTP header’lar ve HTML yanıtı(web sitesinin içeriği) birtakım özel karakterler yardımıyla birbirlerinden ayırılırlar. Bu karakterler carriage return(satır başı) ve line feed(yeni satır) karakterleri olarak bilinir. Ayrıca kısaltılmış hali CRLF’dir.

Sunucu, yeni bir header başladığında, bir başkasının CRLF ile bittiğini bilir. Ayrıca bir web uygulamasına ya da kullanıcıya yeni satırın bir dosya ya da bir metin bloğunda başladığını da söyleyebilir.

CRLF Injection Zafiyeti Nedir?

Saldırgan, bir CRLF Injection saldırısında sunucuyu, web uygulamasını ya da kullanıcıyı bir nesnenin sonlandığı diğerinin ise başladığı yönünde kandırmak için kullanıcı input’una carrige return, line feed karakterlerini ya da ikisini birlikte girer.

Web Uygulamalarında CRLF Injection Zafiyeti

CRLF Injection açığının etkileri, web uygulamasına bağlı olarak büyük önem arz edebilmektedir. Bu etkiler, bilgi ifşasından kod çalıştırmaya kadar geniş bir aralıktadır. Örneğin, bir admin panelindeki kayıt(log) dosyalarını manipüle etmek mümkündür.

Kayıt Dosyasında Bir CRLF Injection Örneği

IP - Zaman - Ziyaret Edilen Yol biçiminde bir kayıt dosyası olduğunu düşünün. Dolayısıyla girdiler şöyle görünecektir:

123.123.123.123 - 08:15 - /index.php?page=home 

Şayet saldırgan sorguya CRLF karakterlerini ekleyebilirse söz konusu kayıt girdilerini taklit edebilir ve girdilerin şununla yer değiştirmesini sağlayabilir:

/index.php?page=home&%0d%0a127.0.0.1 - 08:15 - /index.php?page=home&restrictedaction=edit 

%0d ve %0a karakterleri sırasıyla CR ve LF’nin encode edilmiş halidir. Yani saldırgan, karakterleri ekledikten sonra kayıt girdileri bu şekli alır ve uygulama tarafından böyle gösterilir:

IP - Zaman - Ziyaret Edilen Yol

123.123.123.123 - 08:15 - /index.php?page=home& 
127.0.0.1 - 08:15 - /index.php?page=home&restrictedaction=edit 

Saldırgan bir nevi, yapacağı zararlı işleri gizlemek için bir CRLF zafiyetini suistimal ederek kayıt dosyasındaki girdilerin sahtesini üretir. Örneğin, bir saldırganın admin parolasına sahip olduğu ve sadece admin tarafından kullanılabilen restrictedaction parametresini çalıştırdığı bir senaryoyu düşünelim.

Problem şu ki eğer admin, restrictedaction parametresinin bilinmeyen bir IP tarafından kullanıldığının farkına varırsa bir şeylerin yanlış gittiğini anlayacaktır. Fakat burada uygulanan yöntemle eylemin localhost(yani sunucuya erişimi olan admin gibi biri) tarafından gerçekleştirilmiş olarak gösterilmesi sağlanacaktır. Ki bu da şüphenin ortadan kalkmasını sağlayacaktır.

Sorgunun %0d%0a karakterleriyle başlayan bölümünün tamamı sunucu tarafından tek parametre olarak ele alınır. Ampersand(&) karakterinin hemen sonrasındaki restrictedaction parametresi de ayrı bir parametre olarak işlenir. Yani şu hali alır:

/index.php?page=home&restrictedaction=edit 

HTTP Response Splitting

Açıklama

Bir saldırgan, HTTP yanıt başlığının ve yanıt gövdesinin CRLF karakterleri ile ayrılmasından dolayı buraya bir enjeksiyon yapmayı deneyebilir. Bir CRLFCRLF kombinasyonu tarayıcıya header’ın sona erdiğini ve body’nin başladığını söyleyecektir. Böylelikle saldırgan, HTML kodun bulunduğu yanıt body’sine veri yazabilir duruma gelir. Bu da Cross Site Scripting (XSS) açığına neden olur.

XSS’e Neden Olan Bir HTTP Response Splitting Örneği

Örnek olarak, isteğe bağlı bir header set eden bir uygulama hayal edelim:

X-Your-Name: Bob 

Yukarıdaki header’ın aldığı değer “name” adındaki GET parametresine set edilir. Eğer URL encoding işlemi uygulanmamışsa ve değer direkt olarak header’a yansıtılıyorsa bir saldırganın daha önce bahsedilen CRLFCRLF kombinasyonunu araya ekleyerek tarayıcıya istek body’sinin başladığını söylemesi mümkün hale gelir. Bu şekilde XSS payload’u gibi verilerin eklenebilmesi kaçınılmaz olur. Örneğin:

?name=Bob%0d%0a%0d%0a<script>alert(document.domain)</script> 

Yukarıdaki ifade, saldırıya maruz kalan domainin kontekstinde bir pop-up gösterecektir.

HTTP Header Injection

Açıklama

Bir saldırgan, CRLF injection açığını suistimal ederek ayrıca tarayıcıların Same Origin Policy ya da XSS filtreleri gibi güvenlik mekanizmalarını bertaraf edebilen HTTP header’larını enjekte edebilir. Bunun sonucunda saldırgan CSRF token'ları gibi hassas bilgilere erişme imkanı elde eder. Bunun yanı sıra saldırgan, suistimale açık olmayan Cross Site Scripting (XSS) açıklarını exploit ederek ya da cookie'leri set ederek kurbanın, saldırganın kendi belirlediği bir hesap olarak siteye giriş yapmasını sağlayabilir.

Hassas Bilgiyi Elde Etmek İçin Kullanılan Bir HTTP Injection Örneği

Eğer bir saldırgan, CORS(Cross Origin Resource Sharing)’u aktifleştiren header’ları eklerse, farklı originlerdeki sitelerin birbirlerine erişimini kısıtlayan SOP(Same Origin Policy)’un koruduğu kaynaklara erişmek için javascript’i kullanabilir.

CRLF Injection Zafiyetinin Etkileri

Bu zafiyetin etkileri çeşitlilik göstermekle birlikte bilginin ifşa edilmesi konusunda XSS'in sahip olduğu etkileri de bünyesinde barındırmaktadır. Ayrıca kurbanın tarayıcısındaki XSS filtreleri ve SOP gibi bazı güvenlik kısıtlamalarını da saldırılara elverişli hale getirerek etkisizleştirebilir.

CRLF / Header Injection Nasıl Engellenir?

En iyi önlem, kullanıcıların yanıt header’larına direkt olarak input sağlamalarına izin vermemek olacaktır. Şayet bu mümkün değilse CR ve LF karakterlerini encode eden bir fonksiyon kullanmalısınız. Ayrıca kullanılan programlama dilinin, CR ve LF karakterlerinin header set eden fonksiyonlara enjekte edilmesini engellemek amacıyla güncellenmesi de gerekir.