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