Kit de iniciação para testes de segurança na Web

Olá pessoal!

Meu nome é Andrey. Por 10 anos, tenho procurado vulnerabilidades em vários serviços da web. e pronto para compartilhar meu conhecimento com você. Em maio passado, fiz um relatório sobre isso na conferência Heisenbug e agora estou pronto para compartilhar meu conhecimento aqui também nos espaços abertos da Habr. Então, vamos começar.

Uma vez encontrei uma vulnerabilidade nos servidores da notória empresa Facebook. Os caras se esqueceram de atualizar o ImageMagick (a biblioteca para processamento de imagens) e pagaram por isso :) Com este exemplo, eu queria mostrar que somos todos pessoas e que todos podemos cometer erros, não importa em que empresa e em que posição trabalhamos. O único problema é que esses erros podem levar a todos os tipos de riscos.
Quanto mais complicado seu aplicativo / site / ferramenta, maior a probabilidade de que algo dê errado.
Você precisa verificar se há vulnerabilidades. É tolice não fazer isso.

Os seguintes itens podem ser estágios de verificação de aplicativos da web:
  • Preparação:
    • Definir pontos de entrada - de fato, de onde os dados podem ser obtidos no aplicativo;
    • Identificar estoque de tecnologia;
    • Determine quais vulnerabilidades faz sentido verificar;
  • Verificação Você precisa verificar todas as vulnerabilidades que se aplicam ao escopo da tecnologia do seu aplicativo da web;
  • Análise de código. Não seja preguiçoso, não pule este item. Em alguns casos, sem acesso ao código, é difícil encontrar vulnerabilidades, e isso também permite ignorar a filtragem que pode estar incorporada ao seu aplicativo.

Eu vou falar sobre tudo isso em detalhes.

Então, preparação. Não vou me concentrar em todos os tipos de vulnerabilidades, caso contrário, a quantidade de texto no artigo excederá todos os tamanhos concebíveis e inconcebíveis. Aconselho que você comece a aprender com a lista dos dez melhores projetos da OWASP . A cada poucos anos, o consórcio OWASP faz uma lista das vulnerabilidades mais relevantes no momento. Vamos considerar alguns deles em detalhes.

Xss


XSS (script entre sites) é um ataque a um usuário que permite que um invasor execute um script arbitrário no contexto do navegador de sua vítima. Na maioria das vezes, isso implica a implementação de tags HTML e scripts JS .
Exemplo: uma vez houve um serviço como o Yahoo! Ad Exchange O formulário de recuperação de senha tinha um parâmetro " Return URL ". Pode indicar a qual página retornar após o processo de redefinição de senha. Se você inserir um ou outro vetor que leve à execução do código JS , poderá obter todos os cookies do usuário. Vamos analisar como isso acontece e por quê.


Aqui está o próprio vetor. De repente:

Para fazer uma injeção, você precisa sair do contexto da variável em que estávamos por padrão (por padrão - é isso que o programador assumiu quando escreveu o código).
Abaixo está o valor original. Este é um comportamento válido.

Vemos que returnURL = / login.jsp
Isso se enquadra no valor da tag <input> .
Se adicionarmos aspas após jsp , veremos que a sintaxe HTML foi derramada. Felizmente, a linguagem HTML não é rigorosa, o analisador irá pular e não haverá problemas:

Adicione outro caractere. Aqui estamos completamente fora do contexto da tag <input> :

Agora adicionamos a abertura da tag <svg> e obtemos duas tags válidas em termos de sintaxe:

Em seguida, adicione todo o vetor de ataque:

Nesse caso, a imagem svg é desenhada. Usando o manipulador JavaScript " onload ", executamos um alerta com os cookies do documento. Isso é tudo! O atacante recebeu seus cookies .
Se na prova mostrarmos apenas o alerta em si, não será difícil para um invasor enviar cookies para um servidor controlado por ele e, na pior das hipóteses, apreender sua conta. Vamos ver como fica novamente:


Também há mais vetores de ataque ao cliente. Vou dar alguns exemplos com uma breve descrição. Mas primeiro você precisa entender como sair do contexto:
  • Fora de contexto. Esses 6 caracteres ajudarão a sair não apenas do contexto do valor do parâmetro HTML, mas também de muitos outros:
    -> '">

Bem, de fato, os dois vetores mais simples de ataque:
  • Inserir links em particular. Mas, no caso geral - mudando a aparência da página. Por exemplo, eles podem incorporar código html à sua página e exibir uma janela falsa solicitando dados:

    A sequência " aaaa " aponta para google.com . Você pode ver que o link é renderizado na página, mas você pode não vê-lo, mas isso não cancela sua presença no código. Nos dois casos, o caso pode ser considerado concluído;
  • Execução de script, por exemplo, interceptando cookies do usuário:



Onde e como procurar o XSS?


Primeiro, encontre as funções de saída de informações / dados na página. Analisar quais dados chegam lá? Aí vem o conceito de uma fonte não confiável . E assim, primeiro de tudo, é seu usuário . Os vetores de ataque podem estar contidos em outras fontes: feeds RSS, outros serviços, externos e internos.
Aqui está um exemplo da vida real: trabalho para o SEMrush IT. Estamos desenvolvendo uma plataforma online, que é uma ferramenta universal para profissionais de marketing online. Portanto, um serviço salvou os dados e o outro deduziu, cada uma das equipes confiou uma na outra, resultou que no segundo serviço o XSS surgiu devido à falta de processamento adequado dos dados de saída, e o primeiro comando não considerou necessário filtrar os dados recebidos de qualquer maneira e os manteve " como estão ". Conclusão: se você não souber como esses dados são armazenados, eles devem ser considerados não confiáveis. Ou concorde com antecedência sobre quem armazena e como, filtra, exibe dados.

Se você já possui dados de fontes não confiáveis, recomendo:
  • Estudar a filtragem de dados recebidos;
  • Examine o contexto da saída. Nem sempre o XSS pode ser executado, mesmo na ausência de filtragem. Por exemplo, se o tipo de conteúdo da resposta for: texto / sem formatação;
  • Não confie na filtragem de estruturas de sistemas de segurança incorporadas.


Injeção de SQL




Implementação do código SQL (injeção SQL em inglês) - a introdução na consulta do banco de dados de instruções que não estavam implícitas lá.

Exemplo (não da vida, mas também bom):
Vemos um script que exibe uma tabela de usuário. Nesse caso, ele pode pesquisar por nome de usuário.
À direita é mostrada a aparência da consulta ao banco de dados e à esquerda é o resultado do script no navegador.

Além disso, para testar e obter pelo menos algum resultado primário, inserimos duas aspas no valor do parâmetro name. Simples e duplo:

Vemos que, do ponto de vista da produção, tudo desmoronou, a mesa desapareceu completamente. A solicitação também recebe as 2 aspas extras. A sintaxe inteira da consulta SQL é violada.
Se pegarmos e adicionarmos essa construção ao valor do parâmetro ( ed .: procure na caixa amarela ), receberemos uma solicitação absolutamente válida. A saída da página é completamente idêntica à primeira solicitação, que não incluiu uma injeção:

Para verificar completamente se há uma vulnerabilidade, adicionamos um empate em vez de unidade:

Acontece que a solicitação se torna falsa, do ponto de vista da lógica booleana e, como resultado, não contém dados. No entanto, ao contrário do momento em que ocorreu um erro, temos a saída da própria tabela.

Para não listar tudo o que pode estar em diferentes mecanismos de banco de dados e consultas de diferentes tipos, reduzi tudo a uma linha:

Isso é algo que você pode tentar inserir no parâmetro e, de acordo com as diferenças nas respostas, tentar entender o que está acontecendo, há uma vulnerabilidade ou não. Cerca de 80% dos casos você pode cobrir com esta manipulação.
Restam 20% de situações difíceis nas quais ela não fornece nenhuma informação, por exemplo: consultas / filtros aninhados e assim por diante. Na minha prática, encontrei um similar apenas uma vez. Então eu tive que ignorar a filtragem no lado do serviço.

Qual é o perigo no SQL?
  • Do óbvio - vazamento de informações . Se um invasor foi capaz de gerar consultas em seus bancos de dados, ele pode, de uma forma ou de outra, obter valores que não deveriam ser gerados (hashes de senha, endereços de clientes etc.);
  • Alteração de dados . Agora, muitos desenvolvedores usam bancos de dados através de sistemas ORM . Esses sistemas, por padrão, permitem fazer várias consultas por vez; a sintaxe SQL também permite fazer isso. Se houver uma vulnerabilidade, tudo pode se concentrar não apenas na seleção dos dados, mas também na alteração (até a exclusão de tabelas, alteração da estrutura do banco de dados etc.).
    Na mesma situação, é possível um aumento nos privilégios do usuário. Altere os campos em determinadas tabelas (por exemplo, coloque is_admins = true no banco de dados de usuários ) e, assim, aumente seus direitos ao administrador;
  • DoS . Em alguns casos, uma injeção pode levar a uma negação de serviço. Várias consultas pesadas no banco de dados são geradas, iniciadas em vários threads, e seu serviço pode parar de funcionar por algum tempo;
  • A leitura dos arquivos do sistema é outro desastre que a injeção SQL pode trazer. A ocorrência desse risco depende de qual sistema de banco de dados você usa, bem como de qual usuário trabalha com ele (privilegiado ou não);
  • RCE (Execução Remota de Código) é a execução de código. Depende diretamente do tipo de banco de dados usado (anteriormente isso era possível por padrão, com configurações padrão do banco de dados, no MSSQL).

A tabela abaixo mostra as vulnerabilidades na consulta SQL . Claro, você não precisa memorizá-lo. Além disso, essas não são todas as opções possíveis, mas apenas exemplos. Apenas preste atenção ao fato de que os locais onde a injeção na consulta SQL pode ocorrer se os dados brutos chegarem estão destacados em vermelho. Um invasor experiente pode encontrar uma maneira de explorar isso. Tenha cuidado e atenção.


SSRF (falsificação de solicitação do lado do servidor)


Tradução literal - solicitações falsas no lado do servidor. Ou seja, um ataque que permite manipular os dados que você envia para o aplicativo, forçando você a fazer a solicitação para não onde a lógica de negócios planejou originalmente.
A operação do SSRF é mostrada na imagem abaixo:

Há um invasor, o servidor, que é fechado pelo Firewall , mas ao mesmo tempo há uma funcionalidade que permite fazer solicitações em nome do servidor.
Se essa funcionalidade não estiver adequadamente protegida e / ou incorretamente, como geralmente acontece :), processa os dados recebidos, o invasor pode recorrer ao Memcached , Redis ou obter acesso a quaisquer recursos internos da vítima.

Para um exemplo mais ilustrativo, considere a posição que o SEMrush usa para treinamento interno de funcionários.
É importante prestar atenção ao significado do " URL do avatar ":

Aqui prestamos atenção a 2 pontos:
  • URL do avatar em si
  • e a capacidade de fazer o download usando um arquivo.

Observe que o campo " URL do avatar " é um campo de texto para entrada, o que significa que podemos manipular esse valor. Vamos tentar colocar no avatar, talvez, a imagem mais famosa da Internet - Googlebot na página de erro 404 .
Faça uma vez:

Faça dois - clique em " Salvar ". Temos um robô em vez da minha foto:

Aqui vale a pena prestar atenção ao fato de que o valor da " URL do avatar " mudou para algum caminho local - aparentemente, o aplicativo solicitou uma imagem, salvou-a no servidor e substituiu um novo valor.

Nós seguimos em frente. No campo " URL avatar ", insira o arquivo de valor : /// etc / passwd . Esse design permite acessar a estrutura do arquivo. Em algumas bibliotecas que costumam trabalhar com HTTP , por padrão, o trabalho com a estrutura de arquivos é ativado e recebe dados dos servidores nos quais foram iniciados:

O que acontece depois de clicar no botão " Salvar "? ..
Em primeiro lugar, a imagem se tornou " bat " e, em segundo lugar, o caminho para o arquivo mudou.

Se tentarmos solicitar esta imagem no navegador, eles não nos mostrarão nada (o arquivo está " quebrado "). Mas não somos o primeiro dia em segurança da informação, sabemos o que fazer :) Com simples manipulações, obtemos o conteúdo do arquivo em nosso computador:

Assim, com a ajuda dessa vulnerabilidade, eu, como invasor, posso obter todos os códigos-fonte do seu serviço e outros dados disponíveis para leitura para o usuário que está executando o serviço da web.
Vejamos os perigos do SSRF:
  • Verificação de porta. Para uma rede externa, seu serviço é um ponto de entrada e 2 portas (http e https). Ao verificar as portas de dentro da sua infraestrutura, um invasor pode detectar portas abertas;
  • Ignore a autenticação baseada em host. Qual é o objetivo? É possível que, dentro da sua estrutura, haja serviços disponíveis apenas para determinados recursos (leia-se: lista de permissões de IP). Portanto, se seu servidor vulnerável estiver na lista branca, você terá acesso aos serviços que estão disponíveis para ele e, como resultado, poderá manipulá-los;
  • Continuando o desenvolvimento do ataque mencionado acima, você pode continuar a explorar programas vulneráveis ​​em execução na intranet ou no servidor local. Muitas vezes, há situações em que a infraestrutura interna, inacessível do lado de fora, é mal monitorada (versões / patches de segurança, etc. nem sempre são atualizados). Isso também pode levar a ataques e roubo de dados;
  • Lendo dados locais. Eu mostrei acima com um exemplo. Suas configurações podem ser lidas e acessadas, tokens e senhas.


Onde procurar por SSRF?


Esta não é uma vulnerabilidade padrão. Pode ser encontrado em locais diferentes, geralmente nos lugares mais inesperados. Nessa situação, a técnica “olhe aqui, mas você nem pode olhar aqui” não funciona.
Sinais de um possível SSRF :
  • Webhook . Se eles estiverem mal configurados, se o Firewall estiver configurado incorretamente nos servidores dos quais os Webhooks fazem solicitações, é possível obter uma vulnerabilidade;
  • Conversão HTML . Tente incorporar uma construção de URL <iframe> , <img> , <base> , <script> ou CSS que aponte para um serviço interno;
  • Baixe arquivos excluídos . Lembra do exemplo de avatar? Quando um usuário tem a oportunidade de fazer upload de dados por URL para o servidor, isso envolve grandes problemas. Tente enviar o URL com a porta e veja o conteúdo carregado.


Como procurar por SSRF?


  • Levante o servidor e execute o ouvinte :
    user$ nc -1 -n -vv -p 8080 -k 

    Dessa forma, você verá todas as solicitações que chegam ao seu servidor na porta 8080 . Por um lado, é uma porta desocupada pelos servidores da Web e, por outro lado, é uma porta que geralmente não é filtrada pelo Firewall . Acredita-se que seja usado para o protocolo http e a proibição parece opcional;
  • No aplicativo em estudo, encontre o parâmetro para o qual você pode passar o caminho para solicitar dados do nosso host (ao nosso ouvinte );
  • Examine a saída do ouvinte ou a resposta retornada.


XXE (entidade externa XML)


Vou começar a história, como sempre com um exemplo, para que fique mais claro:
No serviço SEMrush mencionado anteriormente, existe uma ferramenta que lida com a análise de conteúdo. O usuário dirige na URL do site ou de um site concorrente e, antes de analisá-lo, o serviço baixa esse mesmo conteúdo. Veja como isso acontece no vídeo:



Para baixar, o serviço acessa o site especificado e o rastreador baixa o arquivo sitemap.xml . E este é o próprio XML sobre o qual estamos falando neste bloco.
No vídeo, podemos observar como o site atacante adicionou uma definição da entidade externa XXE ao sitemap.xml , que aponta para " file: /// etc / hosts ". Nos sistemas Linux, este é um arquivo que descreve qual IP corresponde aos hosts, se não houver registros DNS para eles.
Em seguida, o invasor indica na tag <loc> a expansão dessa variável. Após analisar o XML, depois de processar todo o XML no compartimento, ele inserirá o valor que estava em " file: /// etc / hosts " na variável location (destacada em vermelho no vídeo).
O atacante inicia o lançamento do nosso analisador, vai para os logs e aqui aparece uma linha, destacada em branco no vídeo. Este é o conteúdo do arquivo " file: /// etc / hosts " obtido na solicitação GET nos logs de um servidor controlado por ele.
O que vem a seguir? O atacante verificará se ele estava certo. Ele mudará o nome do arquivo para " file: /// etc / fstab ", execute o analisador novamente e obtenha estatísticas sobre os processos em execução.

E finalmente: " file: /// etc / hostname ", inicie o analisador, acesse os logs e obtenha o nome do host da máquina em que estamos.
Este é um bug real descoberto por uma pessoa real que não está relacionada à nossa empresa. Eu tive que espalhar cinzas na minha cabeça e pagar dinheiro :)

Outro exemplo de XXE :

Suponha que tenhamos um determinado ponto de extremidade , chamado - exemplo.com/xxe .
Nós enviamos a estrutura XML para ela → em XML, declaramos a entidade → a entidade refere-se ao arquivo do sistema / etc / passwd e abre mais no corpo da resposta → obtemos o conteúdo desse arquivo em resposta.
Vale a pena notar que isso não ocorre com a frequência que desejamos.

Por que isso funciona?


Os documentos XML são um formato de dados estruturado que, entre outras coisas, permite descrever os tipos de dados que eles podem conter usando uma tag especial DOCTYPE .
Data Type Definition (DTD) - A definição de tipos de dados dentro deste documento XML . Existem três opções para como isso pode ser feito:
  • Se o documento suportar DTD . O exemplo abaixo mostra um XML no qual existe uma estrutura de pedido, existe um elemento de produto e um elemento de contagem (presumivelmente: o número de estoque do produto e o número de itens no pedido). Order é o pai desses dois elementos:
  • DTDs externos no servidor local.
    Fazemos o mesmo que na primeira modalidade, mas fazemos todas as definições em um arquivo separado, localizado no servidor local:

  • DTDs externas em um servidor de terceiros:

Se você é um leitor atento, provavelmente correlacionou o fato de que a capacidade de fazer essas solicitações em seu serviço e solicitar esquemas DTD externos é uma vulnerabilidade em si mesma, sobre a qual falamos acima, a vulnerabilidade do SSRF .
Uma ocorrência comum: os desenvolvedores corrigem a vulnerabilidade XXE , mas esquecem de proibir o processamento de DTDs externas e obter SSRF . Consequências fatais não se seguirão disso, mas você não deve esquecer.

O que são entidades em XML?


Entidades em XML . O que é isso Esta é uma oportunidade para definir certos valores e direcioná-los para variáveis. As entidades têm três tipos diferentes:

Predefinido - predefinido. Semelhante ao código HTML , possibilita o uso dos caracteres que fazem parte da sintaxe da linguagem, como uma estrutura de texto. Aqui eles são dados como exemplo, para que você entenda o que é. Sim, na maioria dos ataques, eles não são usados, mas podem ser necessários em alguns casos excepcionais.
Geral e Parâmetro . É a mesma coisa, apenas a sintaxe da declaração muda e como elas podem ser chamadas após a declaração

Onde procurar por XXE ?


Várias opções:
  • Processamento XML em qualquer manifestação:
    • SVG;
    • mapa do site;
  • Converta HTML para outros formatos;
  • Manipulando docx , xlsx e formatos similares.


Como procurá-los?



A imagem mostra apenas um exemplo para começar. Não é uma chave universal. Ele precisa ser otimizado para os formatos que você usa no serviço em estudo.

A primeira coisa que fazemos: declarar uma determinada entidade Z , que acessa o host controlado pelo host atacante, a expande dentro do corpo do documento XML .
Aqui a segunda opção é possível - apenas a essência do parâmetro . Difere do primeiro anúncio (sinal de % ). E, para voltar a essa essência, o corpo do documento não é mais necessário. Podemos acessá-lo diretamente na estrutura DOCTYPE e expor esta entidade:

O terceiro cenário é verificar se a capacidade de solicitar DOCTYPE de serviços externos está ativada ou desativada:

A seguir, analisamos a saída de um servidor controlado por nós. Se virmos uma chamada para URL / verificação de vários endereços IP , isso significa que, com um alto grau de probabilidade, a vulnerabilidade passou e, então, precisamos descobrir como obter dados mais interessantes para nós.

Qual é o perigo do XXE ? Escreverei brevemente e ponto por ponto:
  • Lendo arquivos locais;
  • Acesso a recursos locais;
  • Verificação de porta / host
  • Wrappers de texto sem formatação . Esta é uma oportunidade para acessar seus serviços que operam no protocolo de texto sem formatação;
  • Execução remota de código (não frequentemente). Está desativado por padrão;
  • DoS . Devido ao fato de que as entidades podem ser concatenadas, é possível obter facilmente um aumento exponencial na quantidade de memória ocupada por esses parâmetros. O resultado é um ataque de bilhões de risos . Em outras palavras, você está simplesmente sobrecarregando a memória do servidor atacado.

Concluindo, direi que tudo isso (o artigo e qualquer conhecimento adquirido) não faz sentido sem aplicação prática. Portanto, perguntarei a você um pouco: pense no aplicativo que você escreveu / testou ontem e tente verificar se há vulnerabilidades. Existem formulários de entrada ou processamento XML ? Este aplicativo está protegido? A filtragem foi adicionada e o DTD desativado?
Abra o manual do SQLmap e descubra como verificar seu aplicativo com ele. Se ele não encontrar nada, pegue outra ferramenta, examine-a e teste seu aplicativo em busca de outras vulnerabilidades. Como eu disse no começo, o artigo examina apenas algumas vulnerabilidades, mas milhares delas .
Não acredito que você possa escrever um código absolutamente seguro. Sempre existem vulnerabilidades, você ainda não as encontrou .

Source: https://habr.com/ru/post/pt441966/


All Articles