---
# System prepended metadata

title: Web App Pentest - 0x06 Broken Authentication
tags: [CSR - Web App Pentest]

---

---
title: Web App Pentest - 0x06 Broken Authentication
tags: CSR - Web App Pentest
slideOptions:
  transition: 'fade'
  parallaxBackgroundImage: 'https://i.imgur.com/YClZ1aY.jpg'
---

<style>
.reveal {
  font-size: 36px;
}
</style>

# Web App Pentest 

##  Broken Authentication

---

Вопросы по заданиям?

---

## Темы занятия

- сессии
- пароли
- user enumeration/bruteforce
- защита от брутфорса
- OAuth/OpenID

---

## A07:2021-Identification and Authentication Failures 

Модули программных средств, связанные с аутентификацией и управлением сессиями, часто реализуются неправильно, что позволяет злоумышленникам взломать пароли, ключи или токены сессий или использовать другие недостатки реализации, чтобы получить идентификационные данные других пользователей.

---

## Определения

Идентификация — процесс определения, что за человек перед нами. 

Аутентификация — процесс подтверждения, что этот человек именно тот, за кого себя выдает. 

Авторизация — процесс принятия решения о том, что именно этой аутентифицированной персоне разрешается делать.

---

## Факторы аутентификации

* знание (пароль)
* обладание (смарт карты, криптографические токены, телефон (SIM-карта)*)
* биометрия

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

---

## О сессиях

* Типы сессионной информации
* Время жизни
* Передача на серверную сторону

---

## Результат аутентификации

В результате аутентификации веб-приложение может выдавать пользователю:

* Случайные сессионные идентификаторы;
* Подписанные сессионные данные (например, JWT).

<демонстрация сессий PHP>
<демонстрация jwt.io>

---

## Проблемы JWT

При некорректной реализации может возникать различные проблемы с JWT.

Подробнее https://portswigger.net/web-security/jwt. 

---

## Плагины Burp для JWT

- 

---

## Сравнение

|                           | **Преимущества**               | **Недоостатки**                                |
| ------------------------- | -------------------------- | ------------------------------------------ |
| **Сессионные идентификаторы** | Можно отзывать             | Сессионную информацию нужно где то хранить |
| **Подписанные сессионные данные**                       | На один запрос в БД меньше<br/>Встроенное "протухание"     | Не могут быть отозваны<br/>Утечка секрета приводит к компрометации **всех** учетных записей |

---

## Сессионные идентификатооры

Обычно реализуются фреймворком или средой (например, в PHP встроена поддержка 'PHPSESSID').

При самостоятельной реализации:
* нужна достаточная энтропия (желательно > 256 бит);
* использовать надежный генератор псевдослучайных чисел (в описании генераторов обычно что-то написано про возможность их использования для криптографии, если такое упоминание есть, значит годится).

---

## JWT

При работе с JWT нужно:

- использовать надежный секрет.

Список ненадежных:
https://github.com/wallarm/jwt-secrets/blob/master/jwt.secrets.list

---

## Время жизни сессий

Зависит от приложения:

* от 5 минут для критичных систем (например, ДБО);
* до бесконечных (Google, yandex, интернет-магазины).

Если вы используете длинные сессии (больше 1 суток), то рекомендуется периодически обновлять сессионный идентификатор пользователю.

---

## Передача сессий на серверную сторону

Используются следующие подходы:

* Cookie;
* HTTP-заголовок Authorization:
    * Bearer
    * Basic (\*) (пример: tomcat)

---

## Сравнение

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

---

## LocalStorage

Возможный способ хранения токена аутентификации. Доступен из javascript. Сохраняется в браузере.

---

## О паролях

* Хранение пароля
* Восстановление пароля
* Брутфорс
* Защита от онлайн подбора (bruteforce)

---

## Хранение пароля

Пароли нельзя хранить в открытом виде.

Когда говорим о том как лучше хранить пароль, считаем, что атакующий может получить доступ к базе данных с паролями, например, через SQL-инъекцию.

---

## Хранение пароля

Пароли хранят в хешированном виде.

Для хеширования паролей необходимо использовать "долгие" хеш функции:
* bcrypt;
* PBKDF2.

Криптографические хеш функции (например, из семейства SHA) не подходят, так как они позволят атакующему выполнить быстрый оффлайн брутфорс.

Для оффлайн брутфорса используется hashcat.

---

## Хранение пароля

### Соль

Набор случайных символов, который добавляется к паролю перед его хешированием. Соль сохраняется в БД рядом с паролем.

Использование соли не исключает возможности оффлайн брутфорса, но значительно увеличивает его время.

---

## Хранение пароля

### Перец

Набор случайных символов, который добавляется к  паролю и соли перед его хешированием. Перец может храниться в конфигурационных файлах приложения или может быть зашит в код.

Использование перца исключает возможности оффлайн брутфорса, в том случае, если атакующий получил доступ только к БД (в БД нет перца).

---

## Хранение пароля

```php=
$pepper = "fOifew8Hufehwifhea78feg29HUIFEhfewjfe*FHehaoefahwojfw";

function registerUser($username,$password) {

    $salt = openssl_random_pseudo_bytes(40);
    $hash = hash_pbkdf2 ( 'sha256' , $password.$pepper ,  $salt , 10000 );
    $sql = "INSERT INTO users VALUES ('".$username,."','".$salt."','".$hash."')";
    
    $conn->execute($sql);
}
```

---

## Brute Force

---

## User Enumeration

---

## User Enumeration

Распространенная проблема, позволяющая атакующему проверить наличие учетной записи в системе.

Возникает тогда, когда приложение по разному отвечает в случае ввода некорректного и корректного логина.

Как правило встречается на страницах регистрации, входа и восстановления пароля.

Позволяет атакующему сначала обнаружить учетные записи, а потом уже пытаться подбирать к ним пароли.

---

## User Enumeration

Сам по себе уязвимостью не является.

Тем не менее часто может помочь атакующему, поэтому рекомендуется все же отвечать одинаково для существующих и не существующих логинов.

Если в приложении есть регистрация и бизнес не дает ставить CAPTCHA, то увы, user enumeration будет. Но так и на yandex и на google и еще много где.

---

## User Enumeration

Допустим мы нашли `User Enumeration` в приложении, в котором логином является email.

Чтобы провести атаку нам нужны листы email сотрудников.

---

## User Enumeration

Специальные сервисы - вбиваем домен (example.com), получаем почты:
*  https://hunter.io 
*  https://maildb.io 
 
ПО для поиска в Интернетах: 
https://github.com/laramies/theHarvester 

google: "@hackeru.com"

---

## User Enumeration - ищем людей

Если мы знаем формат почты, то нам могут сгодиться и имена/фамилии сотрудников.

google: `<hackeru> site:linkedin.com`
google: `<hackeru> site:vk.com`
...

---

## User Enumeration - угадываем почты

Если мы знаем формат почты, то мы можем сгенерировать множество возможных почт из имен, фамилий, отчеств.

Словари:
* https://github.com/Raven-SL/ru-pnames-list
* https://github.com/sorokinpf/russian_names 

---

## User Enumeration - если не почты

https://github.com/danielmiessler/SecLists/tree/master/Usernames 

---

## Password Bruteforce

Листы паролей:

* https://github.com/danielmiessler/SecLists/tree/master/Passwords
* https://github.com/FlameOfIgnis/Pwdb-Public
* https://github.com/sharsi1/russkiwlst - для русско говорящих
* https://weakpass.com/


---

## SMS OTP Bruteforce

Бывает что разработчики позволяют выполнить сколько угодно попыток ввести OTP.

Также уязвимостью является если атакующий может запросить генерацию OTP сколько угодно раз - рано или поздно пароль будет угадан.

Словарь тут - просто цифры.

---

## Bruteforce - утилиты

### Intruder

### patator

---

## Patator

Установка

```
apt install patator
```

На MacOS:

```
pip install patator
pip uninstall pycurl
PYCURL_SSL_LIBRARY=openssl LDFLAGS="-L/usr/local/opt/openssl/lib" CPPFLAGS="-I/usr/local/opt/openssl/include" pip install --no-cache-dir pycurl
```

check:
`python patator.py http_fuzz`

---

## Patator


```./patator.py http_fuzz url="https://example.com/sign_in?email=FILE0.FILE1@example.com&password=fefe" 0=~/tools/russian_names/russian_trans_surnames.txt 1=~/tools/russian_names/russian_firstmiddlename_2letter.txt method=POST body="{}" -x ignore:code=404,fgrep=Invalid -t 50```


`patator http_fuzz url=http://ttesting.ru:8088/login.php body="login=bee&password=FILE0&security_level=0&form=submit" 0=$(pwd)/pass_list resolve=ttesting.ru:94.176.238.81 -x ignore:code=200`
<демонстрация>

---

## Защита от брутфорса

---

## Защита от брутфорса

Есть следующие возможности:

* временно блокировать перебираемую учетную запись; 
* требовать ввода CAPTCHA;
* временно блокировать IP-адрес перебирающего (неэффективно).

---

## Временная блокировка

Подход с временной блокировкой учетной записи может привести к недоступности ресурса для легального пользователя.

<!--
Немного улучшают ситуацию [Device Cookies](https://owasp.org/www-community/Slow_Down_Online_Guessing_Attacks_with_Device_Cookies)
-->
---

## Защита от брутфорса

CAPTCHA - подходы:

* для каждого ввода пароля (хорошо защищает, но возможно бизнес не одобрит);
* после нескольких неудачных попыток входа в учетную запись, для неё требовать CAPTCHA.

---

## Защита от брутфорса

CAPTCHA не должен распознаваться с помощью систем распознавания текста (например, tesseract).

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

Google reCaptcha - рекомендуется (хотя иногда бесит пользователей)

---

## Обход CAPTCHA с помощью tesseract

```python=
import pytesseract 
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files (x86)\Tesseract-OCR\tesseract.exe"
from PIL import Image 
print(pytesseract.image_to_string(Image.open('captcha.jpeg')))
```

Перед использовавнием:
1. Установить pytesseract (через pip)
2. Установить tesseract OCR - для Windows вот тут: https://github.com/tesseract-ocr/tesseract/wiki

---

## Обход CAPTCHA bwapp

---

## Обход CAPTCHA bwapp

CAPTCHA может обновляться только при посещении специальной страницы, например captcha.php. Тогда атакующий может либо вообще не разгадывать капчу, либо разгадать её только один раз и дальше проводить brute force

---

## Восстановление пароля

Рекомендуемый путь:

* Используем вторичный канал связи с пользователем - лучше всего email
* Генерируем случайный токен, отправляем на email
* Если пользователь пришел с этим токеном, то позволяем ему установить новый пароль

---

## Восстановление пароля

Плохо:

* Отправлять новый пароль на почту
* Делать токен с долгим сроком жизни или многоразовым
* Использовать для генерации токена не случайную информацию

---

## Делегирование аутентификации

Для делегирования аутентификации используются:

- OpenID
- OAuth

Преимущества:
* вы не храните пароли, а значит они не утекут;
* пользователю не нужно придумывать новый пароль, запоминать или сохранять его.
* пользователю не нужно проходить процедуру регистрации (это никто не любит).

---

## Проблемы OpenID/OAuth

Это сложные протоколы, в реализации которых можно допустить множество ошибок.

Рассмотрим одну проблему:
- отсутствие проверки `redirect_uri`;

Подробнее: https://portswigger.net/web-security/oauth
И тут: https://livebook.manning.com/book/oauth-2-in-action/chapter-7/

---

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

---

## Отстутствие проверки `redirect_uri`

В используется для возврата code приложению клиента.

Сервер OAuth/OpenID должен проверять что переданный `redirect_uri` соответствует `redirect_uri`, использованному при регистрации клиента.

Отсутствие такой проверки позволяет перехватить аутентификационные коды и захватить аккаунты пользователя.

Пример - Portswigger Academy: https://portswigger.net/web-security/oauth/lab-oauth-account-hijacking-via-redirect-uri

---

![](https://i.imgur.com/3adop6S.png)

---
<!--
## Отсутствие проверки `state`

Приводит к Login/Logout CSRF.

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

[RFC OAuth](https://datatracker.ietf.org/doc/html/rfc6749#section-10.12)

---

-->

## Задания

- на CTFd (http://ttesting.ru:8080)
- тест для самопроверки в LMS

---


---
