В 2196 году люди все еще пользуются JavaScript’ом. Но правильно ли ? Посмотри на этот корпоративный портал...
static-mistakes-4a27e2504ec596fe.ctfcup-2023.ru
cd deploy
docker compose -p mistakes up --build -d
Provide zip file: public/task.zip.
Prototype pollution via window name, bypass regex
-
Сайт взаимодействует с API через POST запросы без проверки origin. Это позволяет отправлять запросы с любого сайта через
postMessage
. -
Заметим, что используется переменная
name
без предварительной инициализации:if(!name) name = 'mainStorage'
Поэтому будет использовано значение
window.name
, которое можно установить черезwindow.open
:window.open(task, name_variable)
-
При установке
name
в__proto__
, данные будут сохранены вObject.prototype
:storage = storage[name]
-
Затем, используя переданный JSON файл, можно провести атаку Prototype Pollution:
let instructionsJson = await fetch(debugUrl); instructionsJson = await instructionsJson.json(); console.log(instructionsJson) for(let inst in instructionsJson){ console.log(inst) storage[inst] = instructionsJson[inst].toLowerCase(); }
-
После этого находим chain для XSS в функции вставки элемента:
for(var param in params){ if(param.startsWith("on")) node.setAttribute(param,"logEvent('debug',event)"); else node.setAttribute(param, params[param]) }
Можно вставить любой атрибут, но не аттрибуты, начинающиеся с "on". Решение проблемы - переписать
srcdoc
, так как он имеет больший приоритет чемsrc
, и при вставкеiframe
будет выполнен наш скрипт.
-
The website communicates with the API via POST messages without checking the origin. This allows sending requests from any website using
postMessage
. -
It is noticed that the variable
name
is used without prior initialization:if (!name) name = 'mainStorage'
Therefore, the value of
window.name
will be used, which can be set throughwindow.open
:window.open(task, name_variable)
-
When
name
is set to__proto__
, the data will be stored instorage[Object.prototype]
:storage = storage[name]
-
Next, by using the provided JSON file, it is possible to perform a Prototype Pollution attack:
let instructionsJson = await fetch(debugUrl); instructionsJson = await instructionsJson.json(); console.log(instructionsJson) for (let inst in instructionsJson) { console.log(inst) storage[inst] = instructionsJson[inst].toLowerCase(); }
-
Then, find a chain for XSS in the element insertion function:
for (var param in params) { if (param.startsWith("on")) node.setAttribute(param, "logEvent('debug',event)"); else node.setAttribute(param, params[param]) }
It is possible to insert any attribute, but attributes starting with "on" cannot be inserted. The way to overcome this is to rewrite
srcdoc
, as it takes precedence oversrc
, so when aniframe
is inserted, our script will be executed.
static-mistakes-4a27e2504ec596fe.ctfcup-2023.ru api-mistakes-4a27e2504ec596fe.ctfcup-2023.ru
Yes
ctfcup{380f99f77826f5fc0af980915f9c375d}