JavaScript obyekti prototiplarini manipulyatsiya qilish orqali Node.js ga hujum

Helmholtz Axborot xavfsizligi markazi (CISPA) va Qirollik texnologiya instituti (Shvetsiya) tadqiqotchilari Node.js platformasi va uning asosidagi mashhur ilovalarga hujumlar yaratish uchun JavaScript prototipining ifloslanish texnikasini qo‘llash imkoniyatlarini tahlil qilib, kodning bajarilishiga olib keldi.

Prototipni ifloslantirish usuli har qanday ob'ektning ildiz prototipiga yangi xususiyatlarni qo'shish imkonini beruvchi JavaScript tilining xususiyatidan foydalanadi. Ilovalar ishiga almashtirilgan xususiyat ta'sir qiladigan kod bloklarini (gadjetlar) o'z ichiga olishi mumkin; masalan, kodda "const cmd = options.cmd ||" kabi konstruktsiya bo'lishi mumkin. "/bin/sh"', agar tajovuzkor ildiz prototipidagi "cmd" xususiyatini almashtirishga muvaffaq bo'lsa, uning mantig'i o'zgaradi.

Muvaffaqiyatli hujum uchun ilova ob'ektning ildiz prototipida yangi xususiyat yaratish uchun tashqi ma'lumotlardan foydalanishi va bajarilish o'zgartirilgan xususiyatga bog'liq bo'lgan gadjetga duch kelishini talab qiladi. Prototipni o'zgartirish Node.js da "__proto__" va "konstruktor" xizmat xususiyatlarini qayta ishlash orqali amalga oshiriladi. "__proto__" xossasi ob'ekt sinfining prototipini, "konstruktor" xususiyati esa ob'ektni yaratishda foydalanilgan funksiyani qaytaradi.

Agar dastur kodi "obj[a][b] = qiymat" topshirig'ini o'z ichiga olgan bo'lsa va qiymatlar tashqi ma'lumotlardan o'rnatilgan bo'lsa, tajovuzkor "a" ni "__proto__" qiymatiga o'rnatishi va o'z mulkini o'rnatishga erishishi mumkin. ob'ektning ildiz prototipidagi "b" nomi va qiymati "qiymat" bilan (obj.__proto__.b = qiymat;) va prototipda o'rnatilgan xususiyat barcha ob'ektlarda ko'rinadi. Xuddi shunday, agar kodda "obj[a][b][c] = qiymat" kabi iboralar mavjud bo'lsa, barcha mavjud ob'ektlarda "a" ni "konstruktor" qiymatiga va "b" ni "prototip" ga o'rnatish orqali siz buni amalga oshirishingiz mumkin. "c" nomi va "qiymat" qiymati bilan yangi xususiyatni belgilang.

Prototipni o'zgartirishga misol: const o1 = {}; const o2 = new Object(); o1.__proto__.x = 42; // console.log (o2.x) ildiz prototipida “x” xossasini yaratish; // boshqa ob'ektdan "x" xususiyatiga kirish // chiqish 42 bo'ladi, chunki ildiz prototipi o1 ob'ektida ham qo'llaniladigan o2 ob'ekti orqali o'zgartirildi.

Zaif kodga misol: funktsiya entryPoint (arg1, arg2, arg3){ const obj = {}; const p = obj[arg1]; p[arg2] = arg3; qaytish p; }

Agar entryPoint funksiyasi argumentlari kiritilgan ma'lumotlardan tuzilgan bo'lsa, tajovuzkor "__proto__" qiymatini arg1 ga o'tkazishi va ildiz prototipida istalgan nom bilan xususiyat yaratishi mumkin. Agar siz arg2 ga "toString" qiymatini va arg3 qiymati 1 ni o'tkazsangiz, "toString" xususiyatini belgilashingiz mumkin (Object.prototype.toString=1) va toString() ga qo'ng'iroq paytida dasturni buzishingiz mumkin.

Tajovuzkor kodining bajarilishiga olib kelishi mumkin bo'lgan holatlarga misol sifatida "asosiy", "qobiq", "eksportlar", "kontekst kengaytmalari" va "env" xususiyatlarini yaratish kiradi. Misol uchun, tajovuzkor ob'ektning ildiz prototipida "asosiy" xususiyatni yaratishi mumkin, unga o'z skriptiga yo'lni yozadi (Object.prototype.main = "./../../pwned.js") va Agar kiritilgan paket package.json faylidagi "asosiy" xususiyatni aniq belgilamasa (agar xususiyat aniqlanmagan bo'lsa), bu xususiyat talab ("mening-paketim") konstruktsiyasi kodida bajarilish vaqtida chaqiriladi. u ildiz prototipidan olinadi). “Shell”, “exports” va “env” xossalari xuddi shunday almashtirilishi mumkin: let rootProto = Object.prototype; rootProto["eksport"] = {".":"./changelog.js"}; rootProto["1"] = "/path/to/npm/scripts/"; // chaqiruvni ishga tushirish talab qilinadi("./target.js"); Object.prototype.main = "/path/to/npm/scripts/changelog.js"; Object.prototype.shell = "tugun"; Object.prototype.env = {}; Object.prototype.env.NODE_OPTIONS = "—inspect-brk=0.0.0.0:1337"; // chaqiruvni ishga tushirish talab qilinadi("baytlar");

Tadqiqotchilar eng ko‘p bog‘liqliklarga ega bo‘lgan 10 1958 ta NPM paketlarini tahlil qilishdi va ulardan 4420 355 tasi package.json da asosiy xususiyatga ega emasligini, XNUMX XNUMX tasi talab bayonotlarida nisbiy yo‘llardan foydalanishini va XNUMX tasi to‘g‘ridan-to‘g‘ri buyruqni almashtirish API dan foydalanishini aniqladi.

Ishchi misol - evalFunctions xususiyatini bekor qiluvchi Parse Server serveriga hujum qilish uchun ekspluatatsiya. Bunday zaifliklarni aniqlashni soddalashtirish uchun statik va dinamik tahlil usullarini birlashtirgan asboblar to'plami ishlab chiqilgan. Node.js testi davomida tajovuzkor kodining bajarilishiga olib keladigan hujumlarni tashkil qilish uchun ishlatilishi mumkin bo‘lgan 11 ta gadjet aniqlandi. Parse Server bilan bir qatorda, NPM CLI da ikkita ekspluatatsiya qilinadigan zaifliklar aniqlandi.

Manba: opennet.ru

a Izoh qo'shish