JavaScript объектинин прототиптерин манипуляциялоо аркылуу Node.jsге кол салуу

Helmholtz Маалыматтык Коопсуздук Борборунун (CISPA) жана Королдук Технология Институтунун (Швеция) изилдөөчүлөрү Node.js платформасына жана анын негизиндеги популярдуу тиркемелерге кол салууларды түзүү үчүн JavaScript прототипинин булганышы техникасынын колдонулушун талдоого алып, коддун аткарылышына алып келди.

Прототипти булгоо ыкмасы JavaScript тилинин өзгөчөлүгүн колдонот, ал кандайдыр бир объекттин түпкү прототипине жаңы касиеттерди кошууга мүмкүндүк берет. Тиркемелерде иштөөсүнө алмаштырылган касиет таасир эткен код блоктору (гаджеттер) болушу мүмкүн; мисалы, код 'const cmd = options.cmd || "/bin/sh"', эгерде чабуулчу түпкү прототипте "cmd" касиетин алмаштыра алса, анын логикасы өзгөрөт.

Ийгиликтүү кол салуу үчүн тиркеме объекттин түпкү прототипинде жаңы касиетти түзүү үчүн тышкы маалыматтарды колдоно алышы керек жана ал аткарылганда өзгөртүлгөн касиетке көз каранды болгон гаджет пайда болот. Прототибин өзгөртүү Node.js ичинде "__proto__" жана "конструктор" кызмат касиеттерин иштетүү аркылуу ишке ашат. "__proto__" касиети объекттин классынын прототибин кайтарат, ал эми "конструктор" касиети объектти түзүү үчүн колдонулган функцияны кайтарат.

Колдонмонун коду "obj[a][b] = value" тапшырмасын камтыса жана баалуулуктар тышкы маалыматтардан коюлса, чабуулчу "a" маанисин "__proto__" маанисине коюп, өз менчигинин орнотулушуна жетише алат. объекттин түпкү прототипиндеги "b" аталышы жана "маани" мааниси (obj.__proto__.b = маани;) менен жана прототипте белгиленген касиет бардык объекттерде көрүнөт. Ошо сыяктуу эле, эгер код "obj[a][b][c] = маани" сыяктуу туюнтмаларды камтыса, бардык учурдагы объекттерде "a" маанисин "конструктор" маанисине жана "b" "прототипке" коюу менен, сиз "c" аталышы жана "маани" мааниси менен жаңы касиетти аныктаңыз.

Прототипти өзгөртүүгө мисал: const o1 = {}; const o2 = new Object(); o1.__proto__.x = 42; // console.log (o2.x) түпкү прототипинде “x” касиетин түзүү; // башка объекттен "x" касиетине кирүү // чыгаруу 42 болот, анткени тамыр прототипи o1 объекти аркылуу өзгөртүлгөн, ал o2 объектисинде да колдонулат

Аялуу коддун мисалы: function entryPoint (arg1, arg2, arg3){ const obj = {}; const p = obj[arg1]; p[arg2] = arg3; кайтуу б; }

Эгерде entryPoint функциясынын аргументтери киргизилген маалыматтардан түзүлсө, анда чабуулчу “__proto__” маанисин arg1ге өткөрүп, тамыр прототипинде каалаган ат менен касиетти түзө алат. Эгер сиз arg2ге "toString" маанисин жана arg3 маанисин 1 өткөрсөңүз, "toString" касиетин (Object.prototype.toString=1) аныктап, toString() чалуу учурунда колдонмону бузуп салсаңыз болот.

Кол салуучунун кодун ишке ашырууга алып келиши мүмкүн болгон кырдаалдардын мисалдарына "негизги", "кабык", "экспорттор", "контексткеңешмелер" жана "env" касиеттерин түзүү кирет. Мисалы, чабуулчу объекттин түпкү прототипинде “негизги” касиетти түзүп, ага өзүнүн скриптинин жолун жаза алат (Object.prototype.main = “./../../pwned.js”) жана бул касиет аткарылып жаткан учурда талап кылуу ("менин-пакет") конструкциясынын кодунда чакырылат, эгерде камтылган пакет package.json ичиндеги "негизги" касиетти так аныктабаса (эгерде касиет аныкталбаса, ал тамыр прототипинен алынат). "Shell", "exports" жана "env" касиеттери окшош эле алмаштырылышы мүмкүн: let rootProto = Object.prototype; rootProto["exports"] = {".":"./changelog.js"}; rootProto["1"] = "/path/to/npm/scripts/"; // триггер чакыруу талап кылынат("./target.js"); Object.prototype.main = "/path/to/npm/scripts/changelog.js"; Object.prototype.shell = "түйүн"; Object.prototype.env = {}; Object.prototype.env.NODE_OPTIONS = "—inspect-brk=0.0.0.0:1337"; // триггер чакыруу талап кылынат("байт");

Окумуштуулар эң көп көз карандылыгы бар 10 1958 NPM пакетин талдап чыгышты жана алардын 4420инин package.json ичинде негизги касиети жок экенин, 355сы талап билдирүүлөрүндө салыштырмалуу жолдорду, XNUMXи буйрук алмаштыруу API'син түздөн-түз колдонушат.

Жумушчу мисал - evalFunctions касиетин жокко чыгарган Parse Server серверине кол салуу үчүн эксплойт. Мындай алсыздыктарды аныктоону жөнөкөйлөтүү үчүн статикалык жана динамикалык талдоо ыкмаларын айкалыштырган инструменттер топтому иштелип чыккан. Node.js тестирлөө учурунда чабуулчунун кодунун аткарылышына алып келген чабуулдарды уюштуруу үчүн колдонула турган 11 гаджет аныкталган. Талдоо серверинен тышкары, NPM CLIде эки эксплуатациялануучу алсыздыктар аныкталган.

Source: opennet.ru

Комментарий кошуу