[TR] Web Security Academy — 7.Access control

3 years ago 151
BOOK THIS SPACE FOR AD
ARTICLE AD

hakansonay

Herkese Merhaba,

Bu yazımda PortSwigger firmasının Web Security Academy serisinden Access control zafiyetilerinin lab çözümlerini sizlere anlatacağım.

Labımıza wiener:peter ile giriş yaptıktan sonra Proxy > HTTP historyden /my-account requestimizi Repeatera gönderiyoruz. Requestimizde /my-account sayfasındaki Admin=false parametresi dikatimizi çekiyor. Bu parametre uygulamada kullanıcının admin olup olmamasını boolean olarak değerlendirip farklı yetkiler verebilir. Bu parametre değerini değiştirirsek yetkisiz kullanıcı olarak admin fonksiyonlarına erişebiliriz.

Requestimizde carlos kullanıcısı olmamıza rağmen Admin parametresinin değerini true olarak gönderdiğimizde responsede bizi admin paneli karşılıyor.

Admin panele gitmek için URL’imizi /admin olarak değiştiriyoruz. Burada dikkat etmemiz gereken her requestte default olarak Admin=false parametresi gitmektedir. Admin panele giderken de Admin=true yapmayı unutmayalım ki 401 Unauthorized almayalım.

Admin panele ulaştıktan sonra carlos kullanıcısını silmek için gerekli path ve query kısmını responseden alıyoruz ve requestimizi tekrar düzenliyoruz.

Admin panel üzerinden carlos kullanıcısını silerek labımızı tamamlıyoruz.

Labımıza wiener:peter ile giriş yaptıktan sonra e-mail adresimizi değiştiriyoruz ve bu requesti repeatera gönderiyoruz. Repeaterda requestimizin reponsesini incelediğimizde bodyde bir json ile username,email,apikey ve roleid bize dönüyor.

E-mail adresimizi güncellerken uygulama sadece “email”: keyi json nesnesine requestimizin bodysinde ekliyordu. Responsede ise dört json key:value bize dönüyor. Bu durumda responsede dönen keylerden yola çıkarak requestimizdeki json nesnesine istediğimiz responsedeki key:value’yi eklersek e-mail güncelleme gibi bu değeride güncelleyebiliriz.

Sonraki adım olarak bizde requestimizin bodysine “roleid”:1 key:value değerini json nesnesine ekliyoruz. Normal kullanıcı olarak carlos’a “roleid”=1 tanımlanmış fakat biz 2 olarak tanımlarsak carlos kullanıcısını yetkili biri olarak tanımlanmış olabiliriz. Requestimizin bodysindeki json’a “roleid”=2 ekledikten sonra requestimizi gönderiyoruz ve /my-account’a gidiyoruz.

Admin panel gözüküyor ardından admin panelden carlos kullanıcısını silerek labımızı tamamlıyoruz.

Labımıza wiener:peter ile giriş yaptıktan sonra My account’a tıklıyoruz bu requestimizi Repeatera gönderiyoruz. Requestimizdeki id parametresinin değeri tahmin edilebilir bir kullanıcı id’si olmadığı için farklı kullanıcıların hesaplarına erişemiyoruz.

Uygulamada blog postları incelerken postu yazan kişinin id’sinin sayfa kaynağında yer aldığını görüyoruz. Ana sayfadaki bloglardan carlos kullanıcısının yazdığı bir blog postu bulup userId değerini alıyoruz.

Repeaterdaki requestimizin id parametresinin değerini wiener yerine carlos’unkiyle değiştirdikten sonra requestimizin responsesinde carlos kullanıcısının API keyini alıp submit solution ile göndererek labımızı tamamlıyoruz.

Labımıza wiener:peter ile giriş yaptıktan sonra My Account’a tıklıyoruz bu requestimizi Repeatera gönderip responseyi inceliyoruz. Response’un bodysinde parolamız clear text olarak gözükmektedir. Requestimizdeki id paremetresini farklı bir kullanıcı olarak değiştirirsek responsede o kullanıcının parolasını elde edebilir ve uygulamaya onun yetkileriyle giriş yapabiliriz.

Repeaterda requestimizin id parametresini administrator olarak değiştirelim. Reponse’un bodysinde clear text halde olan admin parolasını alalım ve administrator olarak giriş yapalım.

Uygulamaya administrator:x ile giriş yaptıktan sonra admin panelden carlos kullanıcısını silerek labımızı tamamlıyoruz.

Labımıza wiener:peter ile giriş yaptıktan sonra My Account’a tıklıyoruz bu requestimizi Repeatera gönderiyoruz. Responseyi incelediğimizde wiener kullanıcısının API Keyini body’de görüyoruz.

Browserdan URL’i /my-account?id=carlos olarak değiştirip carlos kullanıcısına gitmeye çalışıyoruz fakat bizi hemen login sayfasına redirect ediyor ve bir bilgi alamıyoruz. Burp'e geçip Proxy > HTTP historyden login sayfasına redirect etmeden önce requestimizin responsesini incelediğimizde yine de carlosun API keyi response'un bodysinde ifşa ediliyor. Responseden carlos kullanıcısının API Keyini alıp submit solution ile göndererek labımızı tamamlıyoruz.

Labımıza wiener:peter ile giriş yaptıktan sonra My Account’a tıklıyoruz bu requestimizi Repeatera gönderiyoruz. Responseyi incelediğimizde wiener kullanıcısının API Keyini body’de görüyoruz.

Requestimizdeki id parametresinin değeri bize wiener kullanıcısını getirmektedir. Uygulama id üzerinde bir kontrol gerçekleştirmiyor ise horizontal pirivilege escalation (Yatay ayrıcalık yükseltme) ile başka bir kullanıcı hesabına erişebiliriz. Requestimizi /my-account?id=carlos olarak düzenliyoruz. Responseden carlos kullanıcısının API Keyini alıp submit solution ile göndererek labımızı tamamlıyoruz.

Labımıza açtıktan sonra admin panel’e gidiyoruz fakat 403 Forbidden “Access denied” ile karşılaşıyoruz. Admin panel ana sayfada mevcut fakat buraya erişemiyoruz.

Labımızın açıklamasında back-end uygulamasındaki framework X-Original-URL headerını da desteklediğini yazıyor. Buradan web uygulamasının front-end kısmında URL /admin için bir engelleme olduğunu çıkarabiliriz. X-Original-URL veya X-Rewrite-URL header kısaca original requestimizin URL’ini override etmemizi sağlar. Front-end kısmında original URL’de engelleme olsada back-end sisteminin URL’i X-Original-URL headerından işlediğini gösterir böylece burayı bypass edebiliriz.

Requestimize X-Original-URL: /admin headerını ekliyoruz ve gönderiyoruz. Responsede Admin panel'e erişiyoruz ardından carlos kullanıcısını silmemiz için gerekli kısmı alıyoruz. Uygulamadaki yapıda requestimize X-Original-URL ile carlos kullanıcısını silecek path ve query'i eklediğimizde responsede 400 Bad Request "Missing parameter 'username'" dönüyor. Uygulama query stringi X-Original-URL'den kabul etmiyor bizde original URL'imize query stringi ekliyoruz.

Requestimizdeki query stringimizi/?username=carlos ve X-Original-URL: /admin/delete olarak değiştirelim. Requestimizin sonucunda carlos kullanıcısını silerek labımızı tamamlıyoruz.

Labımızı açtıktan sonra uygulamanın sayfa kaynağını inceliyoruz CTRL+U. Burada <script>...</script> tagları arasında bir javascript kodu var. Kısaca bu kodda kullanıcının admin olup olmamasını kontrol edip, admin ise arayüzüne bir bağlantı ekliyor. Ama burada admin panel ifşa edildiği için kaynağı inceleyen herhangi bir kullanıcı bu pathı URL'ine ekleyip admin paneline erişebilir. Bizde bu kısmı URL'imize ekliyoruz.

Admin panel üzerinden carlos kullanıcısını silerek labımızı tamamlıyoruz.

Labımızı açtıktan sonra URL’den robots.txt dosyasına bakalım. Kısaca robots.txt, küçük bir komut setine sahip olan ve arama motorlarına yol gösteren bir dosyadır. Developerlar robots.txt dosyasında yanlış yapılandırma ile istenmeyen sayfaları ifşa edebilirler.

Disallow: /administrator-panel komutu ile sitedeki belirli sayfalara arama motorlarının erişimine sınırlama koyulmuş. Kullanıcılar Disallow komutu verdiğiniz sayfaya erişmeye devam edebileceklerdir. URL'den /administrator-panel gidiyoruz. Admin panel üzerinden carlos kullanıcısını silerek labımızı tamamlıyoruz.

Labımıza birbirini etkilemeyecek iki ayrı pencereden administrator:admin ve wiener:peter ile giriş yaptıktan sonra önce admin kullanıcısı üzerinden işlemlerimizi gerçekleştirelim. Burp üzerinden Proxy > HTTP history’den işlemlerimizi inceleyelim. Admin panel üzerinden carlos kullanıcısının yetkisini yükselttiğimiz requestimizi Repeatera gönderelim. Web uygulaması yetki yükseltme işlemini Referer headerından kontrol etmesi aslında admin panele sadece yetkisi olan kullanıcların erişebileceğini ve upgrade/downgrade yetki işlemlerinin referer header kontrolu ile gerçekleştirildiğini anlıyoruz. Referer başlığı, genellikle bir requestin başlatıldığı sayfayı belirtmek için tarayıcılar tarafından requestlere eklenir.

Örneğin, bu uygulamanın /admin sayfası üzerinde sıkı bir erişim kontrolü uyguladığını, ancak /admin/deleteUser gibi alt sayfalar için kullanıcı’nın yalnızca Referer headerını kontrol ettiğini varsayalım. Referer headerı /admin URL’ini içeriyorsa, requeste izin verilir. Böyle bir durumda saldırgan tarafından Referer header kontrol edilebileceğinden, hassas alt sayfalara doğrudan request oluşturabilir, gerekli referer headerı sağlayabilir ve böylece yetkisiz erişim elde edebilir.

Requestimizde administrator kullanıcısı olarak Referer headerımızdan /admin sildiğimizde reponsede bize 401 Unauthorized dönüyor. Aslında işleme yetkimiz olsa dahi işlemin referer üzerinden kontrol edilmesi bizi yetkisiz kullanıcı olarak uygulamaya gösteriyor.

Wiener kullanıcısının session değerini administrator kullanıcısınınki ile değiştirelim. Yetkisini yükselttiğimiz carlos kullanıcısını yetkisini normal hale getirmek için requestimizin action parametresini downgrade olarak değiştirelim. Repsonsede 302 Found ile işlemimiz gerçekleşti. Admin panelden baktığımızda carlos kullanıcısı (NORMAL) olarak gözüküyor, yetki düşürme işlemimiz başarılı sonuçlandı.

Wiener (kendi) hesabımızı yükseltmek için username ve action parametrelerinin değerlerini değiştirelim. Wiener hesabının yetkisini ADMIN’e yükselterek labımızı tamamlıyoruz.

Labımıza birbirini etkilemeyecek iki ayrı pencereden administrator:admin ve wiener:peter ile giriş yaptıktan sonra önce admin kullanıcısı üzerinden işlemlerimizi gerçekleştirelim. Burp üzerinden Proxy > HTTP history’den işlemlerimizi inceleyelim. Admin panel üzerinden carlos kullanıcısının yetkisini yükseltelim ve requesti repeatera gönderelim. Yetki yükseltmek veya düşürmek istediğimizde iki aşamalı bir kontrolden geçiyoruz. İlk aşamada username=carlos&action=upgrade ile yetkisi yükseltilecek hesap için POST requesti gidiyor. İkinci aşamada ise action=upgrade&confirmed=true&username=wiener onaylama işleminden sonra POST requestimiz gidiyor ve kullanıcının yetkisi yükseliyor. Bu iki aşamayı Repeaterda yetki düşürmek için kullanalım fakat ikinci aşamadan başlayalım action=upgrade&confirmed=true&username=wiener. İkinci aşamadaki requestimizdeki action kısmını downgrade yapalım ve reponseyi inceleyelim. Responsede carlos kullanıcısının yetkisi düşürüldü ve ilk aşamadaki kontrole gerek kalmadı, burada bir erişim kontrolü sağlanmıyor olabilir. Buraya kadar yapılan iki aşamayı Repeaterdan sağ tıklayıp Send request(s) to AuthMatrix 'e gönderelim AuthMatrix üzerinden iki adet role ve user ekleyelim. New Role ile user ve administrator New User ile wiener ve admin kullanıcılarını oluşturalım. Cookies kısmından admin ve wiener'ın session değerlerini kayıt edelim. Wiener kullanıcısının rolünü user, admin kullanıcısının rolünü administrator olarak check boxtan ayarlayalım. Ayarlamamız bittikten sonra Run'a tıklayalım ve bizim için olası IDOR'ları bulsun. İkinci aşamada tahmin ettiğimiz gibi yetkisiz bir kullanıcı başka bir kullanıcının yetkisini yükseltebiliyor.

İkinci aşamadaki requestimizi Repeaterda düzenleyelim.

Requestimizdeki admin session değerini wiener’ın session değeri ile değiştirelim. Yetki yükseltilecek kullanıcı username=wiener olarak değiştirelim. Requestimizin sonucunda yetkisiz wiener kullanıcısı kendi yetkisini ADMIN haline getiriyor ve labımızı tamamlıyoruz.

Labımıza birbirini etkilemeyecek iki ayrı pencereden administrator:admin ve wiener:peter ile giriş yaptıktan sonra önce admin kullanıcısı üzerinden işlemlerimizi gerçekleştirelim. Burp üzerinden Proxy > HTTP history’den işlemlerimizi inceleyelim. Labımıza admin olarak login olduktan sonra admin panale gidiyoruz ve bizi bir yetki yükseltme arayüzü karşılıyor. Buradan herhangi bir kullanıcının yetkisini yükseltelim. Carlos kullanıcısının yetkisini yükselttikten sonra bu requesti Proxy > HTTP historyden bulup Repeatera gönderelim.

Requestimizin methodunu GET olarak değiştirdiğimizde response bize 400 Bad Request “Missing parameter ‘username’” dönüyor. Burada GET requestinde username parametresinin eksik olduğunu anlıyoruz ve requestimizi tekrar POST haline getiriyoruz.

Bu requesti wiener kullanıcısı üzerinden de gerçekleştiriyoruz ve aynı responseyi alıyoruz.

Requestin üzerinde sağ tıklayıp Change request method ile requestimizi GET methoduna query string haline çeviriyoruz. Requestimizde GET method halinde de yetki yükseltebiliyoruz.

Özel pencereden veya uygulamadan çıkış yaparak wiener:peter olarak uygulamamıza giriş yapıyoruz. Wiener kullanıcısı olarak herhangi bir GET requestini Repeatera gönderiyoruz.

Wiener kullacısının GET requestini admin olarak gönderdiğimiz /admin-roles?username=wiener&action=upgrade GET query stringi ile değiştiriyoruz. Wiener kullanıcısı olarak admin panele erişmeden veya yetki yükseltmeden sadece HTTP Method değişikliği ile carlos kullanıcısını silerek labımızı tamamlıyoruz.

Labımızı açtıktan sonra Live chat’e tıklıyoruz. Live chat kısmında chat sırasında yazılanları görüntüleyebileceğimiz bir nüsha bulunmakta view transcript’e tıkladığımızda bir .txt dosyası indirebiliyoruz.

Transcripti indirmek istediğimiz requesti Proxy > HTTP historyden bulup Repeatera gönderiyoruz.

Uygulamadaki server file system’de bizim chat transcriptimiz 2.txt olarak kaydediliyor. Uygulama ise bize bu transcripti static URL olarak göstermektedir. Bir konuşma daha gerçekleştirdiğimizde sayı değeri ritmik olarak artmaktadır. Biz 1.txt deki transcripti okumak için requestimizi /download-transcript/1.txt olarak değiştiriyoruz. Responsedaki konuşmayı incelediğimizde carlos kullanıcısının passwordunu buluyoruz. Uygulamaya carlos kullanıcı olarak giriş yaparak labımızı tamamlıyoruz.

Umarım sizin için faydalı bir yazı olmuştur. Daha çok kişinin faydalanması/öğrenmesi için yazıyı paylaşabilirsiniz. Her türlü görüş ve önerilerinizi bekliyorum. Keyifli öğrenmeler :)

Read Entire Article