Machine Name: Appointment
Address: https://app.hackthebox.com/starting-point
Introdução
O aplicativo Appointment é predominantemente baseado na web, e vamos focar em realizar um ataque de SQL Injection contra um site que interage com um banco de dados SQL. Este aplicativo web permite que os usuários pesquisem itens de um banco de dados back-end que é vulnerável a SQL Injection. Nem todos os itens do banco de dados são acessíveis a qualquer usuário, então diferentes níveis de privilégios resultarão em resultados de pesquisa variados.
Por exemplo, um administrador pode ser capaz de pesquisar dados sensíveis como detalhes de usuários, e-mails, informações de cobrança, endereços de envio e outros. Por outro lado, um usuário comum ou um visitante não autenticado pode apenas pesquisar os produtos em venda. Esses conjuntos de dados são armazenados em tabelas separadas. No entanto, para um atacante que conhece as vulnerabilidades de aplicativos web—especificamente SQL Injection—essa separação entre as tabelas se torna irrelevante, pois ele pode explorar a aplicação para consultar qualquer tabela no banco de dados SQL do servidor web.
Um excelente exemplo de como um serviço SQL funciona tipicamente é através do processo de login. Sempre que um usuário tenta fazer login, o aplicativo web envia o nome de usuário e a senha para o serviço SQL, onde eles são comparados com as entradas armazenadas no banco de dados. Se a combinação de nome de usuário e senha corresponder a uma entrada no banco de dados, o serviço SQL responde confirmando as credenciais, e o aplicativo web faz o login do usuário, concedendo acesso às seções restritas do site.
Uma vez logado, o aplicativo web fornece permissões especiais ao usuário, geralmente na forma de um cookie ou token de autenticação. Este token vincula a presença online do usuário ao seu status autenticado no site. O cookie é armazenado localmente no armazenamento do navegador do usuário e no servidor web.
Posteriormente, se o usuário quiser procurar um item específico, ele digita o nome do item na barra de pesquisa. Essa ação aciona o serviço SQL para executar uma consulta com base na entrada do usuário. Se o item pesquisado existir no banco de dados (tipicamente em uma tabela diferente), as informações associadas—como imagens, texto, links, comentários e avaliações—são recuperadas e enviadas para o aplicativo web, que as apresenta ao usuário.
Os sites dependem de bancos de dados como MySQL, MariaDB ou outros porque os dados que coletam ou servem precisam ser armazenados em algum lugar. Esses dados podem incluir nomes de usuário, senhas, postagens, mensagens ou até informações mais sensíveis, como PII (Informações Pessoais Identificáveis), que são protegidas por leis internacionais de privacidade de dados. Organizações que não protegem adequadamente as PII de seus usuários enfrentam pesadas multas de reguladores internacionais e agências de privacidade de dados.
SQL Injection é um método comum de ataque contra sites que dependem de instruções SQL para recuperar e armazenar dados de entrada do usuário. Se essas instruções SQL estiverem mal configuradas, um atacante pode explorar a vulnerabilidade do SQL Injection, o que pode ser extremamente perigoso. Existem várias técnicas para defender contra o SQL Injection, como validação de entrada, consultas parametrizadas, procedimentos armazenados e a implementação de um WAF (Firewall de Aplicação Web) no perímetro da rede. No entanto, existem casos em que essas proteções estão ausentes, o que torna o SQL Injection prevalente e listado como uma das principais vulnerabilidades web no OWASP Top 10.
Vamos examinar nosso alvo para verificar se ele corresponde às características deste cenário.
Enumeração
Primeiro, realizamos uma varredura utilizando a ferramenta Nmap para identificar as portas abertas e os serviços que estão sendo executados nelas. Por padrão, se nenhuma flag alternativa for especificada no comando, o Nmap examina as 1000 portas TCP mais comuns para serviços ativos, o que é suficiente para nossos propósitos.
Além disso, precisaremos de privilégios de superusuário para executar o comando com as flags -sC
ou -sV
, pois essas opções ativam a varredura de scripts (-sC
) e a detecção de versão (-sV
). Esses métodos são mais intrusivos e aumentam a probabilidade de serem detectados por sistemas de segurança no perímetro da rede do alvo.
A partir da varredura, descobrimos que apenas a porta 80 TCP está aberta, e ela está executando o Apache HTTP Server versão 2.4.38. O Apache é um software gratuito e de código aberto usado para servir páginas da web em servidores físicos ou virtuais. Ele é um dos servidores HTTP mais usados, geralmente rodando em portas HTTP padrão, como 80 TCP, 443 TCP, e também em portas não padrão como 8080 TCP ou 8000 TCP. HTTP (Hypertext Transfer Protocol) é um protocolo de camada de aplicação usado para transmitir documentos hipermídia, como HTML.
-sC
: Realiza uma varredura de scripts usando o conjunto padrão de scripts. Isso é equivalente a--script=default
. Alguns scripts dessa categoria são considerados intrusivos e devem ser executados contra uma rede alvo apenas com permissão explícita.-sV
: Ativa a detecção de versão para identificar quais versões estão sendo executadas em cada porta aberta.
A única porta aberta detectada é a porta 80 TCP, que está executando o Apache HTTP Server versão 2.4.38. O Apache HTTP Server é um software gratuito e de código aberto que hospeda páginas da web em servidores físicos ou virtuais. Ele é um dos servidores HTTP mais utilizados e geralmente roda nas portas HTTP padrão como 80 TCP, 443 TCP, e ocasionalmente em portas HTTP não padrão, como 8080 TCP ou 8000 TCP. HTTP (Hypertext Transfer Protocol) é um protocolo de camada de aplicação usado para transmitir documentos hipermídia, como HTML (Hypertext Markup Language).
A varredura do Nmap revelou a versão exata do Apache HTTP Server como sendo 2.4.38. Normalmente, uma boa prática seria procurar em bancos de dados de vulnerabilidades para ver se há alguma vulnerabilidade associada a essa versão. No entanto, neste caso, não há vulnerabilidades conhecidas que possam ser exploradas.
Para explorar mais o serviço rodando na porta 80, podemos acessar diretamente o endereço IP do alvo através de um navegador na nossa instância Pwnbox ou máquina virtual.
Ao digitar o endereço IP do alvo no campo de URL do navegador, encontramos um site com um formulário de login. Os formulários de login são usados para autenticar usuários e conceder acesso às áreas restritas do site, dependendo dos privilégios associados ao nome de usuário inserido. Como não temos credenciais específicas para fazer o login, vamos explorar se existem outros diretórios ou páginas que possam ajudar no nosso processo de enumeração. Sempre é uma boa prática realizar uma enumeração completa do alvo antes de focar em uma vulnerabilidade específica, como a vulnerabilidade de SQL Injection neste caso. Ter a visão completa ajuda a garantir que não estamos deixando passar nada importante e a evitar cair em um beco sem saída frustrante.
Diretórios da web podem ser considerados como “pastas web”, onde diversos recursos e arquivos relevantes são armazenados e organizados. Esses recursos podem incluir páginas, formulários de login, formulários de login administrativos, imagens, arquivos de configuração (como CSS, JavaScript, PHP) e mais. Alguns desses recursos estão diretamente vinculados à página de entrada do site. Páginas comuns, como Home, About, Contact, Register e Login, são consideradas diretórios web separados. À medida que navegamos por essas páginas, o URL na barra de endereços do navegador será alterado de acordo. Por exemplo, ao mover da página inicial para a página de contato, o URL mudaria da seguinte forma:
Home page:
https://www.example.com/home
Contact page:
https://www.example.com/contact
Algumas páginas podem estar aninhadas dentro de outras, o que significa que o diretório de uma página pode estar localizado dentro de um diretório maior que contém a página anterior. Por exemplo, considere uma página de “Esqueci a senha”. Essas páginas geralmente ficam localizadas no diretório de Login, já que os usuários são frequentemente redirecionados para elas a partir do formulário de login caso esqueçam sua senha.
Log-in page:
https://www.example.com/login
Forgot password page:
https://www.example.com/login/forgot
No entanto, se não houver botões ou links para os diretórios desejados, e assumindo que esses diretórios contenham materiais sensíveis ou recursos para o funcionamento do site (como imagens e vídeos), podemos inserir manualmente os nomes desses diretórios ou páginas no campo de URL do navegador para verificar se algo é carregado. O navegador não bloqueará o acesso a esses diretórios apenas porque não há links ou botões diretos na página da web para eles. Cabe aos administradores do site garantir que os diretórios contendo informações sensíveis estejam devidamente protegidos, evitando que os usuários naveguem manualmente até eles.
Ao navegar por diretórios da web, o cliente HTTP (seu navegador) se comunica com o servidor HTTP (neste caso, Apache 2.4.38) através do protocolo HTTP, enviando uma solicitação HTTP (GET ou POST). O servidor então processa a solicitação e retorna uma resposta HTTP. As respostas HTTP contêm códigos de status, que indicam o resultado da interação entre a solicitação do cliente e como o servidor a processou. Alguns dos códigos de status mais comuns para o protocolo HTTP são:
- HTTP/1.1 200 OK: A página ou recurso existe, e o servidor prossegue enviando os dados solicitados.
- HTTP/1.1 404 Not Found: A página ou recurso não existe.
HTTP/1.1 302 Found: A página ou recurso foi encontrado, mas é redirecionado para outro diretório (movido temporariamente). Esse código de status instrui o agente do usuário (o navegador web) a fazer uma segunda solicitação idêntica para o novo URL especificado no campo de localização. O usuário perceberá todo o processo como um redirecionamento contínuo para o novo URL do recurso solicitado.
Vamos examinar o processo completo de busca e acesso a um diretório oculto. Ao inserir o endereço IP do alvo (que executa um servidor HTTP) na barra de URL do navegador, seguido de uma barra (/) e o nome do diretório ou arquivo, os seguintes eventos ocorrerão:
- O agente do usuário (o navegador / cliente HTTP) envia uma solicitação GET para o servidor HTTP, especificando o URL do recurso solicitado.
- O servidor HTTP procura o recurso no URL fornecido.
- Se o recurso ou diretório existir, o servidor HTTP responderá com os dados solicitados (seja uma página da web, imagem, arquivo de áudio, script, etc.) e um código de status 200 OK, indicando que o recurso foi encontrado e a solicitação foi processada com sucesso.
- HTTP/1.1 200 OK: A página/recurso existe e o servidor prossegue com o envio dos dados.
- HTTP/1.1 404 Not Found: A página/recurso não existe.
- HTTP/1.1 302 Found: A página/recurso foi encontrada, mas foi redirecionada para outro diretório (movido temporariamente). Isso instrui o agente do usuário (o navegador web) a fazer outra solicitação idêntica para o novo URL especificado no campo de localização. O usuário perceberá o processo como um redirecionamento contínuo para o novo URL do recurso solicitado.
- Se o recurso ou diretório não puder ser encontrado no URL especificado e não houver redirecionamento configurado pelo servidor, o servidor retornará uma Página 404 com o código de resposta 404 Not Found.
Esses dois casos são o foco da nossa busca ao tentar descobrir diretórios ou recursos ocultos. Em vez de procurar manualmente pela barra de URL, podemos usar ferramentas automatizadas para facilitar esse processo. Ferramentas como Gobuster, Dirbuster, Dirb, entre outras, são comumente usadas para esse propósito.
Essas ferramentas são conhecidas como ferramentas de brute-forcing. O brute-forcing envolve o envio de dados de uma lista personalizada de variáveis, chamada de wordlist, na tentativa de adivinhar a entrada correta e obter acesso. Ao aplicar esse método a diretórios e recursos da web com uma ferramenta desse tipo, ela enviará cada variável da wordlist como solicitações separadas ao servidor HTTP. Em seguida, verificará o código de resposta do servidor para determinar se o recurso existe. Para o nosso caso, as wordlists que usaremos incluem nomes comuns de diretórios e arquivos (como images, scripts, login.php, admin.php), além de alguns nomes mais raros.
A mesma técnica é usada no brute-forcing de senhas, onde senhas de uma wordlist são testadas até encontrar a correta para um determinado nome de usuário. Esse método é frequentemente utilizado por atacantes de baixo nível devido à sua simplicidade, mas pode ser “barulhento”, ou seja, envia um grande número de solicitações em um curto espaço de tempo, tornando-o fácil de detectar por dispositivos de segurança que monitoram comportamentos incomuns ou automatizados em formulários de login. No nosso caso, usaremos uma ferramenta chamada Gobuster, que realizará o brute-forcing nos diretórios e arquivos presentes na wordlist escolhida. O Gobuster já vem pré-instalado no Parrot OS, mas se você estiver usando um sistema operacional diferente, pode instalá-lo seguindo os passos abaixo.
Gobuster
Como o Gobuster é escrito na linguagem Go, é necessário ter o Go instalado, o que inclui o compilador e as ferramentas necessárias. Para instruções detalhadas de instalação, consulte o site oficial da linguagem Go. Para compilar o Gobuster, você precisará de pelo menos a versão 1.19 do Go. Após a instalação do Go, você pode seguir os seguintes métodos para instalar o Gobuster:
1. Usando o gerenciador de pacotes apt
Se você estiver usando uma distribuição Linux baseada em Debian/Ubuntu, pode instalar o Gobuster através do gerenciador de pacotes apt, executando o seguinte comando.
sudo apt install gobuster
2. Usando o comando go install
Se você já tem um ambiente Go configurado (pelo menos a versão 1.19), o processo de instalação é simples. Basta executar o seguinte comando:
go install github.com/OJ/gobuster/v3@latest
Após a conclusão da instalação, vá diretamente para a seção “Usando o Gobuster”.
3. Construindo a partir do código-fonte e compilando
Primeiro, será necessário clonar o repositório do GitHub:
git clone https://github.com/OJ/gobuster.git
Após a conclusão do clone, uma pasta chamada “gobuster” aparecerá no diretório onde você está. Navegue até essa pasta onde os arquivos estão armazenados. Como o Gobuster possui dependências externas, é necessário baixá-las primeiro:
go get && go build
Isso irá gerar um binário do Gobuster para você. Se desejar instalá-lo na pasta $GOPATH/bin
, pode usar o seguinte comando:
go install
Se todas as dependências já estiverem no lugar, você pode usar os scripts de compilação da seguinte forma:
make
– Compila com base na configuração atual do Go (ou seja, executago build
).make windows
– Compila os binários de 32 e 64 bits para Windows e os salva na pasta de compilação.make linux
– Compila os binários de 32 e 64 bits para Linux e os salva na pasta de compilação.make darwin
– Compila os binários de 32 e 64 bits para Darwin e os salva na pasta de compilação.make all
– Compila para todas as plataformas e arquiteturas, salvando os binários resultantes na pasta de compilação.make clean
– Limpa a pasta de compilação.make test
– Executa os testes.
Para entender como usar o Gobuster, podemos aplicar a seguinte sintaxe:
gobuster –help
Após verificar a opção de ajuda, agora podemos usar o programa para procurar páginas e diretórios interessantes. No entanto, ainda precisamos de uma wordlist. O Parrot OS vem com uma pasta pré-instalada contendo várias wordlists, dicionários e tabelas de rainbow, localizada no caminho /usr/share/wordlists
. Como alternativa, você pode baixar a coleção SecLists, que é uma das coleções de wordlists mais amplamente usadas atualmente. Para baixar o SecLists, use o seguinte comando:
git clone https://github.com/danielmiessler/SecLists.git
Agora, estamos prontos para usar o Gobuster em todo o seu potencial. As flags que aplicaremos com este comando são as seguintes:
- dir: Indica que queremos realizar a enumeração de diretórios da web.
- –url: Define o endereço da web da máquina alvo que está executando o servidor HTTP.
- –wordlist: Especifica a lista de palavras que pretendemos usar.
- -t: Aumenta o número de execuções simultâneas
gobuster dir –url http://10.129.227.107 –wordlist /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -t 10
Após examinar os diretórios da web, não encontramos nenhuma informação útil. Os resultados exibidos em nossa saída correspondem a diretórios padrão encontrados na maioria dos sites e, geralmente, não contêm arquivos que possam ser explorados ou úteis para um atacante. No entanto, ainda vale a pena verificá-los, pois, ocasionalmente, eles podem conter arquivos não padrão colocados lá por engano.
Foothold
Como o Gobuster não encontrou nada útil, agora precisamos verificar possíveis credenciais padrão ou encontrar uma maneira de contornar a página de login. Para verificar as credenciais padrão, podemos tentar algumas das combinações mais comuns nos campos de nome de usuário e senha, como:
admin:admin
guest:guest
user:user
root:root
administrator:password
Após tentar todas essas combinações, ainda não conseguimos fazer o login. Hipoteticamente, poderíamos usar uma ferramenta para tentar um ataque de força bruta na página de login, mas isso levaria muito tempo e poderia acionar uma medida de segurança.
O próximo passo lógico seria testar o formulário de login em busca de uma possível vulnerabilidade de Injeção de SQL. Esse vetor de ataque foi explicado detalhadamente na seção de Introdução do relatório:
A Injeção de SQL é um método comum de exploração de páginas web que utilizam instruções SQL para recuperar e armazenar dados de entrada do usuário. Quando configurada incorretamente, essa vulnerabilidade pode ser explorada por meio de ataques de Injeção de SQL, que são altamente perigosos. Existem várias técnicas de proteção contra injeções de SQL, como validação de entrada, consultas parametrizadas, procedimentos armazenados e a implementação de um WAF (Firewall de Aplicações Web) na periferia da rede do servidor. No entanto, ainda existem casos onde essas proteções não estão em vigor, o que torna esse vetor de ataque prevalente, conforme destacado na lista de vulnerabilidades web do OWASP Top 10.
Perceba como, após o símbolo #
, tudo se torna um comentário em PHP? É assim que a linguagem lida com os comentários, e isso é importante lembrar para mais tarde.
O código acima é vulnerável a ataques de Injeção de SQL, pois a consulta (variável $sql
) pode ser alterada através do formulário de login na página web, permitindo que contornemos o login completamente! Podemos especificar o nome de usuário e a senha através do formulário, mas esses valores são incorporados diretamente na variável $sql
, que executa a consulta SQL sem validação de entrada. Não há funções ou expressões regulares para impedir a inserção de caracteres especiais, como uma aspa simples ou o símbolo de hashtag. Essa falta de validação é arriscada, pois esses caracteres podem ser usados para manipular a consulta. As aspas simples são usadas para indicar os dados específicos a serem recuperados do banco de dados SQL, enquanto o símbolo de hashtag é utilizado para iniciar comentários. Isso significa que podemos explorar a consulta inserindo o seguinte:
Username: admin’#
Ao fechar a consulta com uma aspa simples, conseguimos manipular o script para procurar apenas o nome de usuário admin. Adicionando o símbolo de hashtag (#
), comentamos o restante da consulta, tornando a busca pela senha irrelevante. Se olharmos mais abaixo no código PHP, veremos que o login é aprovado apenas quando há exatamente um resultado correspondente ao nome de usuário e senha. No entanto, ao pular a verificação da senha, o script procurará apenas por uma entrada com o nome de usuário admin
. Nesse caso, temos sorte—existe uma conta chamada admin
, o que valida nossa injeção SQL. A variável $count
retornará 1
, permitindo que passemos pela condição if
e façamos o login sem precisar da senha. Se não existisse a conta admin
, poderíamos tentar outros nomes de usuário comuns como administrator
, root
ou john_doe
. Qualquer nome de usuário válido faria nossa injeção SQL funcionar. Como a parte da consulta que verifica a senha foi ignorada, podemos colocar qualquer coisa no campo da senha, e isso não fará diferença.
Password: abc123
Para esclarecer melhor, é assim que nossa entrada afeta a parte da consulta do código PHP.
SELECT * FROM users WHERE usrename = ‘admin’# AND password=’a1’
Observe como, após nossa entrada, comentamos a parte de verificação da senha da consulta? Isso fará com que o script PHP retorne o valor 1 (1 linha encontrada) para o nome de usuário ‘admin’ sem validar a senha. Isso ocorre devido à falta de validação de entrada no código PHP mostrado acima.
Question 01: What does the acronym SQL stand for?
Structured Query Language
Question 02: What is one of the most common type of SQL vulnerabilities?
Sql Injection
Question 03: What is the 2021 OWASP Top 10 classification for this vulnerability?
A03:2021-Injection
Question 04: What does Nmap report as the service and version that are running on port 80 of the target?
Apache httpd 2.4.38 ((Debian))
Question 05: What is the standard port used for the HTTPS protocol?
443
Question 06: What is a folder called in web-application terminology?
directory
Question 07: What is the HTTP response code is given for ‘Not Found’ errors?
404
Question 08: Gobuster is one tool used to brute force directories on a webserver. What switch do we use with Gobuster to specify we’re looking to discover directories, and not subdomains?
dir
Question 09: What single character can be used to comment out the rest of a line in MySQL?
#
Question 10: If user input is not handled carefully, it could be interpreted as a comment. Use a comment to login as admin without knowing the password. What is the first word on the webpage returned?
Vamos abrir a página de login
Então vamos tentar alguns payloads sqli
- ‘ OR 1=1 #
- admin’ #
- ‘ OR id = 1 #
Congratulations
Question 11: Submit the root flag
e3d0796d002a446c0e622226f42e9672