JavaScript Nesne Prototiplerini Yöneterek Node.js'ye Saldırmak

Helmholtz Bilgi Güvenliği Merkezi (CISPA) ve Kraliyet Teknoloji Enstitüsü'nden (İsveç) araştırmacılar, Node.js platformuna ve buna dayalı popüler uygulamalara saldırılar oluşturmak ve kod yürütmeye yol açmak için JavaScript prototip kirliliği tekniğinin uygulanabilirliğini analiz etti.

Prototip kirletme yöntemi, herhangi bir nesnenin kök prototipine yeni özellikler eklemenizi sağlayan JavaScript dilinin bir özelliğini kullanır. Uygulamalar, çalışması değiştirilmiş bir özellikten etkilenen kod blokları (araçlar) içerebilir; örneğin, kod, 'const cmd = options.cmd || Saldırganın kök prototipteki "cmd" özelliğini değiştirmeyi başarması durumunda mantığı değişecek olan "/bin/sh"'.

Başarılı bir saldırı, uygulamanın nesnenin kök prototipinde yeni bir özellik oluşturmak için harici verileri kullanabilmesini ve yürütmenin, değiştirilen özelliğe bağlı bir gadget ile karşılaşmasını gerektirir. Prototipin değiştirilmesi, Node.js'deki “__proto__” ve “constructor” hizmet özelliklerinin işlenmesiyle gerçekleştirilir. "__proto__" özelliği, nesnenin sınıfının prototipini döndürür ve "constructor" özelliği, nesneyi oluşturmak için kullanılan işlevi döndürür.

Uygulama kodu “obj[a][b] = değer” atamasını içeriyorsa ve değerler harici verilerden ayarlanmışsa, saldırgan “a”yı “__proto__” değerine ayarlayabilir ve kendi mülkünün kurulumunu gerçekleştirebilir Nesnenin kök prototipinde “b” adı ve “değer” değeri (obj.__proto__.b = değer;) bulunur ve prototipte ayarlanan özellik tüm nesnelerde görünür olacaktır. Benzer şekilde, eğer kod “obj[a][b][c] = değer” gibi ifadeler içeriyorsa, mevcut tüm nesnelerde “a”yı “yapıcı” değerine ve “b”yi “prototip”e ayarlayarak şunları yapabilirsiniz: "c" adında ve "değer" değerinde yeni bir özellik tanımlayın.

Prototipi değiştirme örneği: const o1 = {}; const o2 = yeni Nesne(); o1.__proto__.x = 42; // kök prototip console.log'da (o2.x) "x" özelliğini oluşturun; // “x” özelliğine başka bir nesneden erişin // kök prototip, o42 nesnesinde de kullanılan o1 nesnesi aracılığıyla değiştirildiği için çıktı 2 olacaktır

Güvenlik açığı bulunan kod örneği: function entryPoint (arg1, arg2, arg3){ const obj = {}; const p = obj[arg1]; p[arg2] = arg3; p'yi döndür; }

entryPoint işlevi argümanları giriş verilerinden oluşturulmuşsa, saldırgan "__proto__" değerini arg1'e iletebilir ve kök prototipte herhangi bir adla bir özellik oluşturabilir. arg2'ye "toString" değerini ve arg3'e 1 değerini iletirseniz, "toString" özelliğini (Object.prototype.toString=1) tanımlayabilir ve toString() çağrısı sırasında uygulamayı kilitleyebilirsiniz.

Saldırganın kod yürütmesine neden olabilecek durumlara örnek olarak "main", "shell", "exports", "contextExtensions" ve "env" özelliklerinin oluşturulması verilebilir. Örneğin, bir saldırgan bir nesnenin kök prototipinde bir "ana" özellik oluşturabilir ve bu özelliğin içine kendi komut dosyasının yolunu yazabilir (Object.prototype.main = "./../../pwned.js") ve Bu özellik, eğer dahil edilen paket package.json'daki "main" özelliğini açıkça tanımlamıyorsa (özellik tanımlanmamışsa, bu özellik, require("my-package") yapısının kodunda yürütme sırasında çağrılacaktır. kök prototipinden elde edilecektir). "Shell", "exports" ve "env" özellikleri benzer şekilde değiştirilebilir: let rootProto = Object.prototype; rootProto["dışa aktarılanlar"] = {".":"./changelog.js"}; rootProto["1"] = "/yol/giden/npm/scripts/"; // çağrıyı tetikle require("./target.js"); Object.prototype.main = "/path/to/npm/scripts/changelog.js"; Object.prototype.shell = "düğüm"; Object.prototype.env = {}; Object.prototype.env.NODE_OPTIONS = "—inspect-brk=0.0.0.0:1337"; // çağrıyı tetikleme require("bytes");

Araştırmacılar, en fazla bağımlılığa sahip 10 NPM paketini analiz etti ve bunların 1958'inin package.json'da bir ana özelliğe sahip olmadığını, 4420'sinin require ifadelerinde göreceli yollar kullandığını ve 355'inin doğrudan komut değiştirme API'sini kullandığını buldu.

Çalışan bir örnek, evalFunctions özelliğini geçersiz kılan Ayrıştırma Sunucusu arka ucuna saldırmaya yönelik bir istismardır. Bu tür güvenlik açıklarının tespitini kolaylaştırmak için statik ve dinamik analiz yöntemlerini birleştiren bir araç seti geliştirildi. Node.js testi sırasında, saldırganın kodunun yürütülmesine yol açacak saldırıları organize etmek için kullanılabilecek 11 gadget belirlendi. Ayrıştırma Sunucusunun yanı sıra, NPM CLI'de de yararlanılabilir iki güvenlik açığı belirlendi.

Kaynak: opennet.ru

Yorum ekle