---
# System prepended metadata

title: Web App Pentest - 0x09 Logical bugs/ PHP LC&TJ / Prototype Pollution
tags: [CSR - Web App Pentest]

---

---
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

---

![](https://i.imgur.com/8nE9LtA.png)

---

## 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`). 

![](https://hackmd.io/_uploads/HkeVablWa.jpg)
---

## 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
