Yusuf Can Çakır tarafından yazılmıştır.
Merhabalar herkese, bugün sizlere Basic Authentication’ın ne olduğundan, saldırılarının nasıl olduğundan ve nasıl analiz edileceğinden bahsedeceğim, keyifli okumalar.
İlk olarak basic authentication nedir bundan bahsedelim. Türkçe olarak Temel Kimlik Doğrulama olarak çevirebiliriz ve temel bir güvenlik olarak kullanılmaktadır. Yani temel olarak bir kullanıcının o sayfaya girebilmek için kendisini doğrulaması gerekir. HTTP protokolünde yer alan kimlik doğrulama sistemidir. HTTP isteklerinde
Authorization: Basic YWRtaW46cGFzc3dvcmQxMjMK
Buradaki önemli bir husus var, base64 kolayca decode edilebilen bir şifreleme türüdür. Bu yüzden farklı yapılarda kullanarak (HTTPS veya SSL) şifrelenmiş verinin okunmasini engelleyebilirsiniz
Peki bu aşamalar nasıl olur?

techmonger.github.io
Basic authentication ile HTTP’de olan olaylar üstteki diyagramdaki gibidir.
Kullanıcı_adı:şifre == admin
assword123
çıktı olarak: YWRtaW46cGFzc3dvcmQxMjMK
5. Kullanıcı bunu HTTP protokolü altında
6. Sunucu ise kullanıcıdan gelen
Örnek bir deneme yapalım
Kod bloğunu php.net sitesinden aldım.
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Text to send if user hits Cancel button';
exit;
} else {
echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
}
?>
Kaynak: https://www.php.net/manual/en/features.http-auth.php
İlk olarak sayfama girdiğimde yine bir pop-up açıldı ve kullanıcı adı ve şifre girdim. Ardından sağ tık > network > header kısmına gelerek

Basic_authentication-2
Base64’ü decode ettiğimizde pwnlab
wnlab değeri dönecektir çünkü ben kullanıcı adına pwnlab, şifresine de pwnlab yazdım. Evet, burada akıllara bir soru geliyor, ya bizim ağımızı dinliyorlarsa? O zaman işte büyük bir sıkıntı ortaya çıkıyor. HTTPS olmayan sitelerde basic auth. kullanmak biraz tehlikelidir. O yüzden HTTPS olmayan bir websitesinde bunu kullanmak pek akıl kârı değildir.

Basic_authentication-3 Wireshark
Örnek olarak bir saldırgan olup Wireshark gibi ağ trafiğini dinleyebileceği araçlarla, kullanıcı adını ve şifreyi clear-text olarak alabilirdi
Tabi ki kullanımı kadar güvenli hale getirilmesi de bir o kadar önemlidir, aksi halde saldırganlar tarafından bilgileriniz bulunarak giriş yapılabilir. Güvenlik için üç tane öneri de bulanacağım.
HTTP kullandığımızda, sunucu ile bizim aramızdaki veriler sadece base-64 ile şifrelenmiş bir şekilde gözükür. Saldırgan kişi, ağda bizlerin trafiğini takip ederse, bu encode edilmiş veriyi decode ederek, bilgilerimize ulaşabilir. Bu yüzden basic authentication kullanıyorsak, HTTPS önlemini de almak durumdayız.
Tabi ki her yerde olduğu gibi burada da güçlü bir parola kullanmakta fayda vardır. Birazdan anlatacağım basic authentication timing attack gibi saldırıların önüne geçebilmek için güçlü bir parola kullanmakta fayda vardır. Timing attack’ta genel olarak if-else döngüsünden kaynaklı bir açık olsa da yine de kendimize güçlü bir parola oluşturmakta fayda vardır.
Rate limit, yani sayfaya atılan istek sayısını sınırlamak. Bunun ne faydası var diye düşünecek olursanız, saldırgan kişiler brute force dediğimiz kaba kuvvet saldırıları ile deneme yanılma yolu ile bizlerin giriş bilgilerini elde edebilir. Bunun için siteye rate limit konmalıdır ki, siteye belli bir sayıda istek geldiğinde sizin yönlendirdiğiniz sayfaya gidecektir.
Basic Auth’larda karşılaşılan en popüler saldırılardan birisi Timing Attack‘lar yani zamanlama saldırılarıdır. Mantığı ise şudur: Her basic auth’da olduğu gibi pop-up şeklinde kullanıcı adı ve şifre girmeniz gerekir, girdikten sonra sunucunun arkaplanında (backend) doğru giriş bilgileri ile girmiş olduğunuz bilgiler belirli bir sürede kıyaslanır. Kıyaslaması da şu şekilde olur;
Gerçek parolanın abcdef olduğunu varsayalım. Ben bir saldırgan olarak server’a iki farklı değer gönderdiğimi düşünelim. Birincisi, abcd123 ikincisi ise abcde123 olsun. Eğer arkaplanda bu değerler “==” ile kontrol ediliyorsa ikinci değerin kontrolü birinci değere göre uzun sürer. Bunun sebebi çoğu programlama dilinde “==” ile yapılan kontrollerin karakter karakter ilerlemesidir. İlk 5 karakter server’daki gerçek parolanın aynısıdır. İlk 5’i doğru 6. yanlış olduğu için 6. da hata mesajı döndürür. Birincisinde ise ilk 4’ü doğru, 5. yanlış olduğu için daha hızlı bir hata mesajı döndürür. Timing attack’larında sunucunun geri dönüş mesajlarındaki süreyi (response time) hesaplayıp , parolanın uzunluğu ve doğruluğu bulunabilir. Tabiki bunları önleme yolları mevcuttur.
Peki bundan nasıl korunabiliriz bundan bahsedeyim, daha çok backend ile ilgili bir durum fakat varsayalım siz bir projede bunu kullanacaksınız ve korunmak isteyeceksiniz.
Genel mantığı anlamak çok önemli. Go dilinde slim.ConstantTimeCompare() fonksiyon kullanıldığı zaman kullanıcının girdiği bilgiler doğru bilgiler ile karşılaştırıldığı durumda kaçıncı karakterde farklılık olduğu fark etmeksizin aynı, belirli bir zamanda dönüş(response) yapar. Böylece dönüş zamanından (response time) kullanıcının girmiş olduğu bilgilerin doğrulu hakkında herhangi bir çıkarım yapılamaz. Ek olarak uzunluğunun tespit edilmesini önlemek amacıyıla hem kullanıcının girmiş olduğu hem de doğru olan bilgilerin SHA256 gibi bir algoritma aracılığıyla hash değerleir karşılaştırılmalılıdr. SHA256‘nın tercih edilmesinin öncül nedenlerinden birisi hızlı olmasıdır. Bahsetmiş olduğun işlem ile hem girilen bilgiler hem de doğru bilgiler 256 bit, 32 byte olacağı için doğru bilgilerin uzunluğu hakkında herhangi bir çıkarım yapılamayacaktır.
func basicAuth(next http.HandlerFunc) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
username, password, status := r.BasicAuth()
if ok {
username_converter := sha256.Sum256([]byte(username))
password_converter := sha256.Sum256([]byte(password))
expectedUsernameHash := sha256.Sum256([]byte("your expected username"))
expectedPasswordHash := sha256.Sum256([]byte("your expected password"))
username_Match := (subtle.ConstantTimeCompare(username_converter[:], expectedUsernameHash[:]) == 1)
password_Match := (subtle.ConstantTimeCompare(password_converter[:], expectedPasswordHash[:]) == 1)
if username_Match && password_Match {
next.ServeHTTP(w, r)
return
}
}
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
})
}
r.BasicAuth() toplamda 3 değer döndürüyor: username, password ve status. Basic authentication’da sorun olup olmadığını status ile kontrol ediliyor. Kullanıcıdan gelen username ve password bilgileri SHA-256 ile hashleniyor. Bu bilgiler ile sistemde bulunan bilgiler ConstantTimeCompare ile karşılaştırılıyor. Eğer bu bilgiler eşleşirse sayfamız başarılı bir şekilde açılıyor fakat eşleşmezse en altta bulunan kod bloğu devreye girerek, 401 değeri (status code) döndürüyor.
Son olarak hackerone’da ikisi ile ilgili raporların bir listesini vereceğim. Bunlara bakarak yeni bilgiler öğrenebilir ve bakış açınızı geliştirebilirsiniz.
https://hackerone.com/reports/277534
https://hackerone.com/reports/224096
https://hackerone.com/reports/348168
https://hackerone.com/reports/94568
https://hackerone.com/reports/838231
Yardımlarından dolayı wakeup‘a teşekkürler
[TR] Basic Authentication Nedir, Ne İşe Yarar?
Merhabalar herkese, bugün sizlere Basic Authentication’ın ne olduğundan, saldırılarının nasıl olduğundan ve nasıl analiz edileceğinden bahsedeceğim, keyifli okumalar.
Basic Authentication
İlk olarak basic authentication nedir bundan bahsedelim. Türkçe olarak Temel Kimlik Doğrulama olarak çevirebiliriz ve temel bir güvenlik olarak kullanılmaktadır. Yani temel olarak bir kullanıcının o sayfaya girebilmek için kendisini doğrulaması gerekir. HTTP protokolünde yer alan kimlik doğrulama sistemidir. HTTP isteklerinde
Authorization
başlığının içerisinde bir kelime Basic
ve ardından bir boşluk bırakılıp base64 ile şifrelenmiş username:password
verisi bulunur. Örnek olarak kullanıcı adı: admin ve şifre: password123 olsun. Bunun çıktısı aşağıdaki gibi olacaktır.Authorization: Basic YWRtaW46cGFzc3dvcmQxMjMK
Buradaki önemli bir husus var, base64 kolayca decode edilebilen bir şifreleme türüdür. Bu yüzden farklı yapılarda kullanarak (HTTPS veya SSL) şifrelenmiş verinin okunmasini engelleyebilirsiniz
Peki bu aşamalar nasıl olur?

Working of Basic Access Authentication - Tech Monger
In this article we will explore how basic access authentication works in http client server architecture.
Basic authentication ile HTTP’de olan olaylar üstteki diyagramdaki gibidir.
- Kullanıcı (client) sunucuya bir istek atar
- Sunucu HTTP durum kodunu 401 olarak ve HTTP Header‘ında basic değerli WWW-Authenticate değişkenini HTTP başlığında gönderir. Bunu göndermesindeki sebep, basic authentication‘ın başlaması içindir
- Kullanıcı bu isteği aldığında aşağıdaki gibi bir input alanı çıkar.
Basic_authentication-1- Kullanıcı burada kullanıcı adı ve şifre değerlerini girer. Buradaki değerler arka planda aralarında iki nokta üst üste konulup, base64 ile şifrelenerek gider.Yani,
Kullanıcı_adı:şifre == admin

çıktı olarak: YWRtaW46cGFzc3dvcmQxMjMK
5. Kullanıcı bunu HTTP protokolü altında
Authorization
header’ı altında, başında basic değeri olarak gönderir.Authorization: Basic YWRtaW46cGFzc3dvcmQxMjMK
6. Sunucu ise kullanıcıdan gelen
Authorization
header’ındaki base64 olarak şifrelenmiş olan kullanıcı adı ve şifre bilgilerini kendi bünyesinde bulunan base64 ile şifrelenmiş veri ile karşılaştırır. Eğer ki bu karşılaştırma doğru ise HTTP durum kodu olarak 200 döndürür. Fakat yanlış ise WWW-Authenticate ile 401 durum kodunu döndürür ve kodlama da bir yere yönlendirme yapılması istenmiyorsa tekrardan 3. adıma dönülür.Örnek bir deneme yapalım
Örnek Üzerinde Deneme
Kod bloğunu php.net sitesinden aldım.
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Text to send if user hits Cancel button';
exit;
} else {
echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
}
?>
Kaynak: https://www.php.net/manual/en/features.http-auth.php
İlk olarak sayfama girdiğimde yine bir pop-up açıldı ve kullanıcı adı ve şifre girdim. Ardından sağ tık > network > header kısmına gelerek
Authorization
etiketini gördük.
Basic_authentication-2
Base64’ü decode ettiğimizde pwnlab


Basic_authentication-3 Wireshark
Örnek olarak bir saldırgan olup Wireshark gibi ağ trafiğini dinleyebileceği araçlarla, kullanıcı adını ve şifreyi clear-text olarak alabilirdi
Nasıl Güvenli Hale Getirilir?
Tabi ki kullanımı kadar güvenli hale getirilmesi de bir o kadar önemlidir, aksi halde saldırganlar tarafından bilgileriniz bulunarak giriş yapılabilir. Güvenlik için üç tane öneri de bulanacağım.
1-) HTTPS Kullanımı
HTTP kullandığımızda, sunucu ile bizim aramızdaki veriler sadece base-64 ile şifrelenmiş bir şekilde gözükür. Saldırgan kişi, ağda bizlerin trafiğini takip ederse, bu encode edilmiş veriyi decode ederek, bilgilerimize ulaşabilir. Bu yüzden basic authentication kullanıyorsak, HTTPS önlemini de almak durumdayız.
2-) Güçlü Parola
Tabi ki her yerde olduğu gibi burada da güçlü bir parola kullanmakta fayda vardır. Birazdan anlatacağım basic authentication timing attack gibi saldırıların önüne geçebilmek için güçlü bir parola kullanmakta fayda vardır. Timing attack’ta genel olarak if-else döngüsünden kaynaklı bir açık olsa da yine de kendimize güçlü bir parola oluşturmakta fayda vardır.
3-) Rate Limit
Rate limit, yani sayfaya atılan istek sayısını sınırlamak. Bunun ne faydası var diye düşünecek olursanız, saldırgan kişiler brute force dediğimiz kaba kuvvet saldırıları ile deneme yanılma yolu ile bizlerin giriş bilgilerini elde edebilir. Bunun için siteye rate limit konmalıdır ki, siteye belli bir sayıda istek geldiğinde sizin yönlendirdiğiniz sayfaya gidecektir.
Basic Auth Zamanlama Saldırıları (Timing Attack)
Basic Auth’larda karşılaşılan en popüler saldırılardan birisi Timing Attack‘lar yani zamanlama saldırılarıdır. Mantığı ise şudur: Her basic auth’da olduğu gibi pop-up şeklinde kullanıcı adı ve şifre girmeniz gerekir, girdikten sonra sunucunun arkaplanında (backend) doğru giriş bilgileri ile girmiş olduğunuz bilgiler belirli bir sürede kıyaslanır. Kıyaslaması da şu şekilde olur;
Gerçek parolanın abcdef olduğunu varsayalım. Ben bir saldırgan olarak server’a iki farklı değer gönderdiğimi düşünelim. Birincisi, abcd123 ikincisi ise abcde123 olsun. Eğer arkaplanda bu değerler “==” ile kontrol ediliyorsa ikinci değerin kontrolü birinci değere göre uzun sürer. Bunun sebebi çoğu programlama dilinde “==” ile yapılan kontrollerin karakter karakter ilerlemesidir. İlk 5 karakter server’daki gerçek parolanın aynısıdır. İlk 5’i doğru 6. yanlış olduğu için 6. da hata mesajı döndürür. Birincisinde ise ilk 4’ü doğru, 5. yanlış olduğu için daha hızlı bir hata mesajı döndürür. Timing attack’larında sunucunun geri dönüş mesajlarındaki süreyi (response time) hesaplayıp , parolanın uzunluğu ve doğruluğu bulunabilir. Tabiki bunları önleme yolları mevcuttur.
Peki bundan nasıl korunabiliriz bundan bahsedeyim, daha çok backend ile ilgili bir durum fakat varsayalım siz bir projede bunu kullanacaksınız ve korunmak isteyeceksiniz.
Timing Attack(Zamanlama Saldırıları) için Önlem
Genel mantığı anlamak çok önemli. Go dilinde slim.ConstantTimeCompare() fonksiyon kullanıldığı zaman kullanıcının girdiği bilgiler doğru bilgiler ile karşılaştırıldığı durumda kaçıncı karakterde farklılık olduğu fark etmeksizin aynı, belirli bir zamanda dönüş(response) yapar. Böylece dönüş zamanından (response time) kullanıcının girmiş olduğu bilgilerin doğrulu hakkında herhangi bir çıkarım yapılamaz. Ek olarak uzunluğunun tespit edilmesini önlemek amacıyıla hem kullanıcının girmiş olduğu hem de doğru olan bilgilerin SHA256 gibi bir algoritma aracılığıyla hash değerleir karşılaştırılmalılıdr. SHA256‘nın tercih edilmesinin öncül nedenlerinden birisi hızlı olmasıdır. Bahsetmiş olduğun işlem ile hem girilen bilgiler hem de doğru bilgiler 256 bit, 32 byte olacağı için doğru bilgilerin uzunluğu hakkında herhangi bir çıkarım yapılamayacaktır.
func basicAuth(next http.HandlerFunc) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
username, password, status := r.BasicAuth()
if ok {
username_converter := sha256.Sum256([]byte(username))
password_converter := sha256.Sum256([]byte(password))
expectedUsernameHash := sha256.Sum256([]byte("your expected username"))
expectedPasswordHash := sha256.Sum256([]byte("your expected password"))
username_Match := (subtle.ConstantTimeCompare(username_converter[:], expectedUsernameHash[:]) == 1)
password_Match := (subtle.ConstantTimeCompare(password_converter[:], expectedPasswordHash[:]) == 1)
if username_Match && password_Match {
next.ServeHTTP(w, r)
return
}
}
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
})
}
r.BasicAuth() toplamda 3 değer döndürüyor: username, password ve status. Basic authentication’da sorun olup olmadığını status ile kontrol ediliyor. Kullanıcıdan gelen username ve password bilgileri SHA-256 ile hashleniyor. Bu bilgiler ile sistemde bulunan bilgiler ConstantTimeCompare ile karşılaştırılıyor. Eğer bu bilgiler eşleşirse sayfamız başarılı bir şekilde açılıyor fakat eşleşmezse en altta bulunan kod bloğu devreye girerek, 401 değeri (status code) döndürüyor.
Basic Authentication ve Timing Attack Hackerone Raporları
Son olarak hackerone’da ikisi ile ilgili raporların bir listesini vereceğim. Bunlara bakarak yeni bilgiler öğrenebilir ve bakış açınızı geliştirebilirsiniz.
https://hackerone.com/reports/277534
https://hackerone.com/reports/224096
https://hackerone.com/reports/348168
https://hackerone.com/reports/94568
https://hackerone.com/reports/838231
Yardımlarından dolayı wakeup‘a teşekkürler

Moderatör tarafında düzenlendi: