Superbug

Information Security Community

Modern İnternet Tarayıcılarının Güvenliği



İçerik :

[+] Execution Context & Stack
[+] DOM
[+] Kapsam
[+] DOM Clobber

Execution Context & Stack

İlk olarak, uygulama güvenliği konusuna derinlemesine girdiğimizde oldukça işimize yarayacak olan Global, Fonksiyon ve Eval alanlarının ne işe yaradığını anlamaya çalışalım.

Global kod : Default olarak kod ile birlikte çalıştırılacak olan alan.
Fonksiyon kod : Kod akışı fonksiyon gövdesine girdiği zaman çalıştırılacak olan alan.
Eval kod : Bu alanda kod çalıştırılacaktır.

Aşağıdaki kod parçasında bir Global context ve 3 farklı Function context oluşturduk. Global context içinden herhangi bir context'e erişim sağlayabiliriz. Her fonksiyon çağırdığımızda yeni bir context oluşturmuş oluyoruz.

//global context

var sayHello = 'Hello';

function person() { // execution context

var first = 'Evren',
last = 'Yalçın';

function firstname() {
return first; // execution context
}

function lastname() {
return last; // execution context
}

alert(sayHello + firstname() + ' ' + lastname());
}


JavaScript interpreter'i tarayıcı içinde single thread olarak çalışmaktadır. Yani tek seferde tek işlem yapılmaktadır ve diğer aksiyonlar için Execution stack çağrılmaktadır. Aşağıdaki diyagramda single thread stack'in nasıl çalıştığını görebilirsiniz.



Scriptler yüklenirken Global execution context ön tanımlı bir şekilde yüklenmektedir. Global koddan bir fonksiyon çağırdığımız zaman akış şemasında fonksiyon çağıralacak, yeni bir execution context oluşturulacaktır ve yığının en tepesine yerleştirecektir. Daha sonra sonra geri dönüp sıradaki contexti aşağıdan yukarıya doğru alacaktır. Çalışma mantığını ufak bir örnekle anlamaya çalışalım.

Aşağıdaki kod kendini 3 defa çağırmaktadır. Foo fonksiyonu çağrıldığı zaman yeni bir Execution context oluşmaktadır. Context tamamlanıp, çalıştırıldığında yığında en tepeye çıkarılmaktadır. Daha sonra kontrol mekanizması geri dönerek yeni bir context oluşturmak için Global context'e ulaşmaktadır.

(function foo(i) {
if (i === 3) {
return;
}
else {
foo(++i);
}
}(0));


Kod - Recursive fonksiyonun çalışması ( Örnek için tıklayın )

Artık her fonksiyon çağırdığımızda execution context oluşturduğunu biliyoruz. Şimdi Execution context'in oluşturulma aşamalarını inceleyelim:

1- Creation Stage : Fonksiyon çağrıldığında ama herhangi bir kod çalıştırılmadığı zaman kullanılan alandır.

- Scope Chain oluşturulur.
- Özellikler, fonksiyonlar ve argümanlar bu aşamada oluşturulur.
- This'in değeri belirlenir.

2- Code Execution Stage :

- Interpreter fonksiyon kodunu context içinde çalıştırır ve değer atanmış özellikler satır satır çalıştırılır.

Aşağıdaki kod parçasında foo(22) yazarak fonksiyonu çağırıyoruz. Creation stage aşağıdaki gibi olacaktır :

function foo(i) {
var a = 'hello';
var b = function privateB() {

};
function c() {

}
}

foo(22);


Aşağıdakii kod parçasında özelliklerin isimleri belirleniyor. Argümanlar ve parametreler belirleniyor ve Creation stage sonlandırılıyor. Ardından kod akışı devam ediyor, fonksiyon ve özellikler çalıştırılıyor ve Execution stage sonlandırılıyor.


fooExecutionContext = {
scopeChain: { ... },
variableObject: {
arguments: {
0: 22,
length: 1
},
i: 22,
c: pointer to function c()
a: undefined,
b: undefined
},
this: { ... }
}


 Aşağıdaki kodda Execution Stage'in sonlandırılmış halini görebilirsiniz :

fooExecutionContext = {
scopeChain: { ... },
variableObject: {
arguments: {
0: 22,
length: 1
},
i: 22,
c: pointer to function c()
a: 'hello',
b: pointer to function privateB()
},
this: { ... }
}


DOM

Elimizde bulunması gereken en önemli silahlardan biri de DOM(Document Object Model) dir. DOM altındaki her şey düğüm olarak belirlenmiştir. En tepedeki düğüm "document' düğümü olarak belirlenmiştir ve document düğümü ile diğer düğümlere erişim sağlayabilmekteyiz.

İşimize yarayacak düğüm listesi aşağıdaki gibidir:


  • cookies
  • window
  • history
  • location


Kapsam(Scope)

JavaScript değişkenlerine kod içinden erişim Global ve Lokal kapsamlar ile belirlenmektedir. Aşağıdaki JavaScript kod parçasında Global kapsam olarak belirlenen "g" değişkenine kodun herhangi bir yerinden erişim sağlanabilmektedir.

Resim - Global ve Lokal kapsamlar.

“var” etiketiyle tanımlanmayan değişkenler Global ortamda bulunurlar ve Global ortamlara “window” nesnesiyle erişebilıyoruz. Dis ve ic fonksiyonlarda bulunan değişkenlere x=3 veya y=3 gibi bir değer atarsak window nesnesiyle erişebiliyoruz.

Buradaki özel durumlardan birisi de erişimin iç fonksiyondan dış fonksiyona doğru olmasıdır. Fakat “ic” fonksiyonu x değişkenine erişebildiği halde, “dis” fonksiyonu y değişkenine erişim sağlayamağını unutmamak gerekiyor.

Dom Clobber

Bir önceki konuda JavaScript dilinde Global ve Lokal değişkenlerin nasıl tanımladığı konusunda biraz bilgi sahibi olduk. Şimdi de bu bilgileri kullanarak az bilinen zafiyetler kategorisinde bulunan Dom Clobber'ı inceleyelim.

Dom Clobber, Html etiketlerini kullanarak DOM elementlerini ezebildiğimiz bir saldırı türüdür. Konuyu anlamak adına basit bir örnekle başlayalım.

İlk olarak aşağıdaki kod parçasından form html etiketine name attribute değeri olarak evren'i atadık.

<form name="evren">

Konsola gidip “evren” yazdığımızda karşımıza form elementine ait methodları etkileyebileceğimiz HtmlFormElement arayüzü gelecektir.

Resim - HtmlFormElement arayüzü 

Peki form etiketine action özelliği atasaydık ne olurdu?

<form name="evren" action="www.google.com">

Konsolu açıp evren.submit(); yazdığımızda, submit methodu sayesinde google.com'a veri göndererebiliyoruz.

Görüldüğü gibi evren değerini kullanarak form'a ait özelliklere rahatlıkla erişim sağlayabiliyoruz. Diğer bir örneğe bakalım:

<form name =evren>içerik </form>

diye basit bir form açıp/kapatalım ve form'un içeriğine ulaşalım. document.evren.innerHTML veya evren.innerHTML şeklinde form içerisinde yer alan HTML içeriğe erişebiliyoruz.

Peki bu durumu nasıl bir zafiyete çevirebiliriz?

Mathias Karlsson adlı güvenlik araştırmacısının Github'da bulmuş olduğu DOM Clobber zafiyetini inceleyelim. Aşağıdaki kod parçasında yorum alanına bir img html etiketi açıyoruz ve name özelliğine body değerini ekliyoruz.

<img src="http://web" name="body" />

Kaynak : https://gist.github.com/avlidienbrunn/46f3cc26d1ea462627f5

Daha sonra yorumu düzenlemek için yorum içeriğine ulaştığınızda görsel yerine name özelliğinde bulunan body değeri JavaScript olarak yorumlanıyor; kısacası DOM elementlerine müdahale etmiş oluyoruz ve bu şekilde bir tür uygulama bazlı hizmet dışı bırakma saldırısı yapabilmekteyiz.

Son olarak hatırlatmakta fayda var; Bu şekilde bir zafiyet bulduğunuzda Bugcrowd VRT dökümanına göre seviyesi P2 olan bir zafiyet bulmuş oluyorsunuz.

...devam edecek
Evren