Scripting entre sites o quê. Vulnerabilidade XSS - o que é isso? Exemplos de vulnerabilidades XSS. Qual é a diferença entre XSS no modelo DOM

Scripting entre sites o quê. Vulnerabilidade XSS - o que é isso? Exemplos de vulnerabilidades XSS. Qual é a diferença entre XSS no modelo DOM

Todos nós sabemos o que é cross-site scripting, certo? Esta é uma vulnerabilidade na qual um invasor envia dados maliciosos (geralmente HTML contendo código Javascript) que posteriormente são retornados pela aplicação, fazendo com que o código Javascript seja executado. Então isso não é verdade! Existe um tipo de ataque XSS que não se enquadra nesta definição, pelo menos em seus princípios básicos. Os ataques XSS, conforme definidos acima, são divididos em instantâneos (dados maliciosos são incorporados em uma página que é retornado ao navegador imediatamente após a solicitação) e retardados (dados maliciosos são retornados após algum tempo). Mas existe um terceiro tipo de ataque XSS, que não se baseia no envio de dados maliciosos ao servidor. Embora pareça contraintuitivo, existem dois exemplos bem documentados de tal ataque. Este artigo descreve o terceiro tipo de ataques XSS - XSS através de DOM (DOM Based XSS). Nada de fundamentalmente novo sobre o ataque será escrito aqui, mas a inovação deste material está em destacar as características distintivas do ataque, que são muito importantes e interessantes.

Os desenvolvedores e usuários de aplicativos devem compreender os princípios dos ataques XSS via DOM, pois eles representam uma ameaça aos aplicativos da web e são diferentes do XSS normal. Existem muitas aplicações web na Internet que são vulneráveis ​​ao XSS através do DOM e ao mesmo tempo testadas para XSS e consideradas “invulneráveis” a este tipo de ataque. Os desenvolvedores e administradores de sites devem se familiarizar com as técnicas de detecção e proteção contra XSS por meio do DOM, pois essas técnicas diferem das técnicas usadas para lidar com vulnerabilidades XSS padrão.

Introdução

O leitor deve estar familiarizado com os princípios básicos dos ataques XSS (, , , , ). XSS geralmente se refere a scripts instantâneos () e preguiçosos entre sites. Com o XSS instantâneo, o código malicioso (Javascript) é retornado imediatamente pelo servidor atacado como resposta a uma solicitação HTTP. Lazy XSS significa que o código malicioso é armazenado no sistema atacado e pode posteriormente ser injetado na página HTML do sistema vulnerável. Conforme mencionado acima, esta classificação pressupõe que a propriedade fundamental do XSS é que o código malicioso é enviado de um navegador para um servidor e retornado ao mesmo navegador (flash XSS) ou a qualquer outro navegador (XSS atrasado). Este artigo levanta a questão de que esta é uma classificação incorreta. A capacidade de realizar um ataque XSS que não dependa da injeção de código na página retornada pelo servidor teria um grande impacto nas técnicas de segurança e detecção. Os princípios de tais ataques são discutidos neste artigo.

Exemplo e comentários

Antes de descrever o cenário de ataque mais simples, é importante enfatizar que os métodos aqui descritos já foram demonstrados publicamente diversas vezes (por exemplo, , e ). Não afirmo que os métodos abaixo sejam descritos pela primeira vez (embora alguns deles sejam diferentes de materiais publicados anteriormente).

Um sinal de site vulnerável pode ser a presença de uma página HTML que utiliza dados de document.location, document.URL ou document.referrer (ou quaisquer outros objetos que possam ser influenciados por um invasor) de forma insegura.

Nota para leitores não familiarizados com esses objetos Javascript: Quando o código Javascript é executado no navegador, ele acessa vários objetos representados no DOM (Document Object Model). O objeto document é o principal desses objetos e fornece acesso à maioria das propriedades da página. Este objeto contém muitos objetos aninhados, como localização, URL e referenciador. Eles são controlados pelo navegador de acordo com o ponto de vista do navegador (como será visto a seguir, isso é bastante significativo). Portanto, document.URL e document.location contêm a URL da página, ou mais precisamente, o que o navegador entende por URL. Observe que esses objetos não são retirados do corpo da página HTML. O objeto document contém um objeto body contendo o código HTML analisado da página.

Não é difícil encontrar uma página HTML contendo código Javascript que analisa uma string de URL (acessada via document.URL ou document.location) e, de acordo com seu valor, realiza algumas ações no lado do cliente. Abaixo está um exemplo desse código.

Por analogia com o exemplo em, considere a seguinte página HTML (assumindo que o conteúdo seja http://www.vulnerable.site/welcome.html):

Bem-vindo! Olá var pos=document.URL.indexOf("name=")+5; document.write(document.URL.substring(pos,document.URL.length));
Bem-vindo ao nosso sistema…

No entanto, uma consulta como esta -

http://www.vulnerable.site/welcome.html?name=alert(document.cookie)

causaria XSS. Vejamos o porquê: o navegador da vítima, ao receber este link, envia uma solicitação HTTP para www.vulnerable.site e recebe a página HTML (estática!) acima mencionada. O navegador da vítima começa a analisar esse código HTML. O DOM contém um objeto de documento que possui um campo URL, e este campo é preenchido com o valor do URL da página atual durante a criação do DOM. Quando o analisador atinge o código Javascript, ele o executa, o que provoca a modificação do código HTML da página exibida. Neste caso, o código faz referência a document.URL e como parte desta string é incorporada no HTML durante a análise, que é imediatamente analisada, o código detectado (alert(...)) é executado no contexto da mesma página.

Notas:

1. O código malicioso não está incorporado na página HTML (ao contrário de outros tipos de XSS).
2. Esta exploração funcionará desde que o navegador não modifique os caracteres da URL. O Mozilla codifica automaticamente '' caracteres (em %3C e %3E respectivamente) em objetos de documento aninhados. Se a URL foi digitada diretamente na barra de endereço, este navegador não estará vulnerável ao ataque descrito neste exemplo. No entanto, se o ataque não exigir os caracteres '' (em sua forma original não codificada), o ataque poderá ser executado. O Microsoft Internet Explorer 6.0 não codifica '' e é, portanto, vulnerável ao ataque descrito sem quaisquer restrições. No entanto, existem muitos cenários de ataque diferentes que não requerem '' e, portanto, mesmo a Mozilla não está imune a este ataque.

Métodos para detectar e prevenir vulnerabilidades deste tipo

No exemplo acima, o código malicioso ainda é enviado ao servidor (como parte da solicitação HTTP), portanto o ataque pode ser detectado como qualquer outro ataque XSS. Mas este é um problema solucionável.

Considere o seguinte exemplo:

http://www.vulnerable.site/welcome.html#name=alert(document.cookie)

Observe o símbolo '#' à direita do nome do arquivo. Diz ao navegador que tudo depois desse caractere não faz parte da solicitação. Microsoft Internet Explorer (6.0) e Mozilla não enviam o fragmento após o caractere '#' para o servidor, portanto, para o servidor esta solicitação será equivalente a http://www.vulnerable.site/welcome.html, ou seja, o código malicioso nem será notado pelo servidor. Assim, graças a esta técnica, o navegador não envia uma carga maliciosa ao servidor.

No entanto, em alguns casos, é impossível ocultar a carga útil: uma carga maliciosa faz parte do nome de usuário em uma URL como http://nomedeusuário@host/. Nesse caso, o navegador envia uma solicitação com um cabeçalho de autorização contendo o nome de usuário (carga maliciosa), resultando em código malicioso chegando ao servidor (codificado em Base64 - portanto, o IDS/IPS deve primeiro decodificar esses dados para detectar o ataque). No entanto, o servidor não é obrigado a injetar essa carga útil em uma das páginas HTML disponíveis, embora esta seja uma condição necessária para executar um ataque XSS.

Obviamente, em situações em que a carga útil pode ser completamente ocultada, as ferramentas de detecção (IPS) e prevenção (IPS, firewalls de aplicativos da web) não podem proteger completamente contra esse ataque. Mesmo que a carga precise ser enviada ao servidor, em muitos casos ela pode ser transformada de uma determinada maneira para evitar a detecção. Por exemplo, se algum parâmetro estiver protegido (por exemplo, o parâmetro name no exemplo acima), uma pequena alteração no script de ataque pode produzir o seguinte resultado:

(documento.cookie)

Uma política de segurança mais rigorosa exigiria que o parâmetro name fosse enviado. Neste caso, você pode fazer a seguinte solicitação:

http://www.vulnerable.site/welcome.html?notname=alert(document.cookie)&name=Joe

Se a sua política de segurança restringir nomes de parâmetros adicionais (por exemplo: foobar), você poderá usar a seguinte opção:

http://www.vulnerable.site/welcome.html?foobar=name=alert(document.cookie)&name=Joe

Observe que o parâmetro ignorado (foobar) deve vir primeiro e conter uma carga útil em seu valor.

O cenário de ataque descrito em é ainda mais preferível para o invasor, pois o valor completo de document.location é escrito na página HTML (o código Javascript não procura um nome de parâmetro específico). Assim, um invasor pode ocultar completamente a carga enviando o seguinte:

/attachment.cgi?id=&action=foobar#alert(document.cookie)

Mesmo que a carga útil seja analisada pelo servidor, a proteção só poderá ser garantida se a solicitação for rejeitada ou a resposta for substituída por algum texto de erro. Referindo-nos novamente a e: se o cabeçalho Authorization for simplesmente removido pelo sistema de segurança intermediário, não terá efeito se a página original for retornada. Da mesma forma, qualquer tentativa de manipular dados no servidor removendo ou codificando caracteres ilegais será ineficaz contra este ataque.

No caso de document.referrer, a carga útil é enviada ao servidor por meio do cabeçalho Referer. Porém, se o navegador do usuário ou a proteção intermediária remover esse cabeçalho, não haverá nenhum vestígio do ataque, que pode passar completamente despercebido.

Resumindo, concluímos que os métodos tradicionais, nomeadamente

1. Codificação de dados HTML do lado do servidor
2. A remoção/codificação de entradas proibidas no lado do servidor não funciona no DOM XSS.

A busca automática por vulnerabilidades “bombardeando” dados maliciosos (às vezes chamado de fuzzing) não funcionará, uma vez que os programas que usam essa técnica normalmente fazem inferências com base se os dados incorporados estão presentes ou não na página retornada (em vez de executar o código no contexto do navegador no lado do cliente e monitorando os resultados). Porém, se o programa conseguir analisar estaticamente o código Javascript encontrado na página, ele poderá apontar sinais suspeitos (veja abaixo). E, claro, se as ferramentas de segurança puderem executar código Javascript (e inicializar objetos DOM corretamente) ou emular tal execução, elas serão capazes de detectar esse ataque.

A pesquisa manual de uma vulnerabilidade usando um navegador também funcionará, pois o navegador pode executar código Javascript do lado do cliente. As ferramentas de vulnerabilidade podem adotar esse método e executar código do lado do cliente para monitorar os resultados de sua execução.
Proteção eficaz

Evite reescritas, redirecionamentos ou outras ações semelhantes de documentos do lado do cliente que usam dados do lado do cliente. A maioria dessas ações pode ser realizada usando páginas dinâmicas (lado do servidor).
2.

Análise e melhoria da segurança do código (Javascript) do lado do cliente. As referências a objetos DOM que podem ser influenciados pelo usuário (o invasor) devem ser verificadas cuidadosamente. Atenção especial deve ser dada aos seguintes objetos (mas não limitados a eles):
* documento.URL
* document.URLUnencoded
* document.location (e suas propriedades)
* documento.referenciador
* window.location (e suas propriedades)

Observe que as propriedades dos objetos documento e janela podem ser referenciadas de diversas maneiras: explicitamente (exemplo: window.location), implicitamente (exemplo: location) ou obtendo um identificador e usando-o (exemplo: handle_to_some_window.location).

Deve ser dada especial atenção ao código onde o DOM é modificado, explícita ou potencialmente, através do acesso direto ao HTML ou através do acesso direto ao DOM. Exemplos (esta não é de forma alguma uma lista exaustiva):
*Inserção no código HTML da página:
o documento.write(…)
o documento.writeln(…)
o document.body.innerHtml=…
* Alterando o DOM diretamente (incluindo eventos DHTML):
o document.forms.action=… (e outras variações)
o document.attachEvent(…)
o document.create…(…)
o document.execCommand(…)
o documento.corpo. ... (acessando o DOM através do objeto body)
o window.attachEvent(…)
* Alteração do URL do documento:
o document.location=… (além de atribuir valores href, host e hostname ao objeto location)
o document.location.hostname=…
o document.location.replace(…)
o document.location.assign(…)
o documento.URL=…
o window.navigate(…)
* Abrindo/modificando o objeto janela:
o documento.open(…)
o janela.open(…)
o window.location.href=… (além de atribuir os valores de host e nome de host ao objeto de localização)
*Executando o script diretamente:
o avaliação(…)
o window.execScript(…)
o window.setInterval(…)
o window.setTimeout(…)

Continuando com o exemplo acima, para uma proteção eficaz, o script original pode ser substituído pelo código a seguir, que verifica se a string escrita na página HTML contém apenas caracteres alfanuméricos.

O uso de cabeçalhos de segurança é uma parte importante na proteção de um site e de seus visitantes contra ataques de hackers. No último artigo sobre a seção de proteção e segurança, prometi publicar regularmente posts sobre este tema. Hoje falarei sobre proteção contra ataques XSS.

O que é um ataque XSS

Cross Site Scripting é uma vulnerabilidade que permite que um invasor injete código malicioso (geralmente HTML ou JavaScript) no conteúdo de um site. O código malicioso é executado no navegador do usuário que visualiza a página do site infectado.

Os invasores podem explorar várias vulnerabilidades. Os tipos de ataques mais comuns são:

  • O XSS refletido é o tipo de ataque não persistente mais comum, exigindo uma ação específica do usuário.
  • XSS persistente é um tipo de ataque permanente que injeta código malicioso no servidor e não requer intervenção do usuário.
Ataque XSS refletido

Acionado quando um usuário segue um link especialmente preparado que envia uma solicitação a um site com vulnerabilidade. Esta vulnerabilidade é normalmente o resultado de uma filtragem insuficiente das solicitações recebidas, o que permite a manipulação de funções e a ativação de scripts maliciosos.

  • O invasor incorpora um script malicioso no hiperlink que permite visualizar cookies de sessão do usuário e os envia à vítima por e-mail ou outro meio de comunicação.
  • Ao clicar no link, o usuário é capturado.
  • O script é executado no navegador do usuário.
  • O navegador envia cookies ao invasor, proporcionando acesso aos dados pessoais do usuário.
  • Ataque XSS armazenado

    Para realizar um ataque armazenado com sucesso, o invasor só precisa encontrar uma vulnerabilidade no site e colocar um script malicioso em seu servidor. Em seguida, o site coloca uma tag que carrega o script de um site externo, por exemplo, nos comentários. Quando uma página infectada é carregada, um script malicioso é sempre transmitido ao navegador do usuário.

  • Um invasor descobre um site com vulnerabilidade XSS e injeta um script malicioso que rouba os cookies do usuário.
  • Cada vez que você visita um site, o script malicioso é ativado sem realizar nenhuma ação.
  • Os cookies de sessão do navegador do visitante são enviados ao invasor.
  • Habilitando o cabeçalho X-XSS-Protection

    O cabeçalho X-XSS-Protection destina-se a ativar o filtro de script entre sites integrado em todos os navegadores modernos. Permitirá, por exemplo, impedir a execução de uma tag na URL da página.

    A diretiva report para envio de relatórios atua de forma semelhante à diretiva report-uri (ou report-to) da Política de Segurança de Conteúdo (CSP), instruindo o navegador do usuário a relatar tentativas de violação da política de segurança de conteúdo. Falarei sobre isso em um artigo separado.

    O relatório de violação é gerado no formato JSON e enviado por meio de solicitações POST para o URL especificado.

    Voltando ao tópico principal, recomendo configurar o servidor de forma que o cabeçalho HTTP inclua filtragem e, em caso de ataque XSS, bloqueie o carregamento de uma página com conteúdo inseguro. No arquivo de configuração adicional.htaccess (ou httpd.conf se você tiver acesso total ao servidor) do servidor web Apache, você precisa adicionar a seguinte entrada:

    Conjunto de cabeçalho X-XSS-Protection "1; mode=block"

    Para o servidor Nginx, adicione a seguinte entrada ao arquivo nginx.conf na seção HTTP:

    Add_header X-XSS-Protection "1; modo = bloco";

    Caso não haja acesso aos arquivos de configuração do servidor, mas haja suporte PHP, utilize a função:

    Cross Site Scripting, também conhecido como XSS, é um método de injeção de código malicioso executado no lado do cliente. O usuário pode perceber algo errado, por exemplo, um comportamento incomum da página, às vezes o ataque ocorre de forma totalmente imperceptível em segundo plano.

    Esperamos que agora você entenda um pouco mais sobre os cabeçalhos do servidor HTTP e o X-XSS pode ajudar a evitar scripts entre sites. Eu uso cabeçalhos de segurança em todos os meus sites e recomendo fortemente que você faça o mesmo. Juntos podemos tornar a Internet mais segura! 😉

    Sobre a possibilidade de obter diversas informações de sites de terceiros por meio de um ataque simples - Cross Site Scripting Inclusion (XSSI).

    Se você lê Easy Hack sistematicamente, provavelmente já está familiarizado com a Política de Mesma Origem (SOP), e frequentemente voltamos a ela. Devido ao SOP, a capacidade de interação entre os dois “sites” é muito limitada. Mas como a tarefa de receber e enviar informações de um site para outro surge frequentemente, vários métodos foram introduzidos para “suavizar” a política e organizar a interação. Por exemplo, como CORS ou crossdomain.xml. Um dos métodos mais antigos é carregar JavaScript de outro domínio através do arquivo . O SOP não nos limita de forma alguma: você pode especificar um local quase arbitrário.

    Por exemplo, existe o host do invasor evil.ru e o site da vítima - vítima.com. Em evil.ru podemos colocar um arquivo HTML e vincular a qualquer script da vítima:

    Quando um usuário entra no site do invasor, o navegador carrega e executa o JS de vítima.com, mas no contexto do SOP evil.ru. Isso significa que a partir do JS do invasor poderemos acessar (não todos) os dados JS do servidor da vítima.

    Por exemplo, conteúdo JS do site da vítima (http://victim.com/any_script_.js):

    Var a = "12345";

    Então, no site do invasor podemos obter o valor da variável:

    console.log(a);

    A ideia do trabalho é tão simples quanto uma chaleira de alumínio.

    Na verdade, a capacidade de carregar JS estático de outros sites não representa mais problemas para o site vítima do que carregar uma imagem.

    Podem surgir problemas quando o JS é gerado dinamicamente, ou seja, quando o conteúdo do script JS muda com base nos dados do cookie dependendo de qual usuário o acessa. Por exemplo, JS armazena algumas informações “críticas”: informações pessoais (e-mail, nome de usuário no site da vítima) ou informações técnicas (tokens anti-CSRF).

    Mas, como sabemos, ao carregar um script através de uma tag, o navegador do usuário envia automaticamente um cookie para o usuário. Ao somar esses fatos, conseguimos obter informações sobre qualquer usuário que tenha visitado o site do invasor e esteja logado no site da vítima.

    O que podemos descobrir? Variáveis ​​globais e resultados de funções globais. Infelizmente, não seremos capazes de acessar variáveis/funções internas (embora talvez alguém encontre uma maneira de fazer isso também).

    Função test())( return "dados privados da função frm"; )

    Este ataque parece possível, mas parece simples demais e não deveria ser comum. É isso que torna interessante a apresentação na Black Hat. Os pesquisadores analisaram 150 sites populares e descobriram que um terço deles era vulnerável até certo ponto. Estas estatísticas obrigam-nos a olhar o problema um pouco mais de perto.

    Outro padrão também foi revelado. A Política de Segurança de Conteúdo está se tornando mais comum. Como você sabe, com ele podemos indicar de quais domínios este ou aquele recurso pode ser carregado. Por exemplo, você pode executar JS apenas a partir do mesmo recurso. Além disso, as práticas recomendadas para configurar um CSP incluem proibir a execução de JS embutido (ou seja, código localizado diretamente no HTML e não carregado de um arquivo JS).

    Porém, a transferência inline para arquivos pode ser feita com muletas e com pressa – ou seja, por meio de scripts gerados dinamicamente. Como o CSP não tem efeito no XSSI, podemos realizar nossos ataques novamente. Esta é uma prática tão ruim.

    Todo mundo sabe há muito tempo que, na maioria das vezes, usando XSS, um invasor tenta enviar um cookie para a vítima, ler tokens CSRF, realizar um ataque de phishing (criando um formulário de login falso), realizar alguma ação em nome do usuário e alguns outros ataques semelhantes (talvez essas não sejam todas as possibilidades, mas essas são todas as mais populares que conheço no momento).

    O objetivo deste método é monitorar as páginas em nome do usuário que ele navega no site atacado, bem como monitorar suas teclas digitadas (você também pode usar movimentos e cliques do mouse, mas para mim isso será desnecessário, não particularmente útil informações, na maioria dos casos com certeza).
    Agora com relação ao benefício máximo - acredito que o algoritmo será assim:

    • ler e enviar Cookies;
    • leia e envie o restante das informações (endereço IP, plug-ins instalados, versão e tipo de navegador, suporte a flash, suporte a silverlight, etc.) [opcional]
    • obter informações sobre a rede interna, penetrar no roteador [opcional]
    • ler e enviar tokens diferentes [opcional];
    • implementar phishing [opcional];
    • fazemos algo “com as mãos do usuário” [opcional];
    • continuamos a espioná-lo e obter informações até que ele feche a aba ou saia do site;

    Todos os itens opcionais da lista IMHO devem ser executados dependendo da situação e prioridades específicas para os objetivos que precisam ser alcançados usando XSS, eles às vezes podem interferir uns nos outros (se você tentar combiná-los, ou melhor, executar um após o outro) e aumentar a probabilidade de falha da operação XSS.
    Mas o primeiro e o último ponto devem ser sempre cumpridos, em qualquer caso, na verdade, a parte principal do artigo será sobre o último ponto desta lista.

    Estamos nos aproximando da meta.

    Vou começar de longe: através do JavaScript é possível alterar o caminho na barra de endereço sem recarregar a página. Por exemplo, se um usuário carregou uma página em

    http://site.com/some/path/to/page/


    Então o conteúdo da barra de endereço será o seguinte (sem recarregar a página):

    http://site.com/new-url/

    http://site.com/new-url/


    Esse recurso, aliás, às vezes é bastante útil quando é necessário se esconder dos usuários (ou de uma categoria mais atenta de usuários - administradores) limpando rapidamente a URL após eles clicarem em um link que continha XSS refletido, para que posteriormente, depois de carregar a página, olhando na barra de endereço, não encontrei nada.

    document.body.innerHTML += "Hackeado";

    http: //site.com/search.php?q=123 documento. corpo. innerHTML += "Hackeado" ;

    http://site.com/search.php?q=123window.history.pushState("", "", "/"); document.body.innerHTML += "Hackeado";

    http: //site.com/search.php?q=123 janela. história. pushState ("" , "" , "/" ); documento. corpo. innerHTML += "Hackeado" ;


    vamos privá-lo desta oportunidade.

    Mas esta técnica tem aplicações ainda mais interessantes e poderosas. Simularemos a permanência do usuário no site após clicar no link, na verdade ele permanecerá na mesma página o tempo todo, e neste momento um script de terceiros funcionará, extraindo e enviando informações ao invasor. Por isso, O XSS funcionará desde que o usuário clique em um link neste domínio .

    Designamos a ideia.

    O princípio geral de funcionamento é este: quando um usuário entra em uma página com XSS, o script cria um iframe com o mesmo endereço da página e o “anexa” ao primeiro plano, o usuário fica com a impressão de que a página carregou normalmente, pois o iframe só pode ser visto nas páginas de código.

    E o script auxiliar controla a lógica do bot espião, ou seja, monitora quando o endereço do frame muda para alterá-lo na barra de endereços, mas se o endereço do frame recém-alterado tiver um domínio diferente, então você pode abrir em uma nova aba, ou você terá que recarregar a página para não se queimar.
    Assim, para que o XSS pare de ser executado neste momento, o usuário deve atualizar a página manualmente (se o XSS foi refletido e foi transmitido pelo método POST, em outros casos a atualização não ajudará, e por falar nisso, alguns os navegadores agora podem enviar uma solicitação POST novamente ao atualizar a página) ou fechar a guia ou mudar para outro domínio (embora neste caso você ainda possa evitar perder o controle).

    Se for para um subdomínio do domínio atacado, então a escolha é do invasor, ou seja, o XSS funcionará, mas há uma pequena chance de o usuário detectar uma discrepância entre o endereço. Acho que dependendo da situação, por exemplo, se o domínio google.ru foi atacado, o usuário mudou para o serviço de arquivos em nuvem do Google, que geralmente fica no subdomínio drive.google.ru, então a probabilidade de ele perceber o problema ao olhar para a barra de endereço é bastante alto, se ele costumava usar este serviço. Caso contrário, você também pode correr um risco. Mas devemos levar em consideração que não poderemos mais ler seus dados a partir de um frame com subdomínio, pois a Cross Origin Policy não o permitirá. Mas podemos navegar com segurança no domínio principal em seu nome no modo oculto (mais sobre isso abaixo).

    Somente este método tem limitações, ou seja, não funcionará se as respostas do servidor web do site contiverem um cabeçalho X-Frame-Options com o valor DENY . Mas, pessoalmente, encontrei esses sites literalmente algumas vezes, agora até metade deles não tem SAMEORIGIN definido, sem mencionar a restrição completa; NEGAR.

    Vamos analisar a ideia.

    Agora, muitos provavelmente se lembram de uma coisa tão maravilhosa como o BeEF, que também tem muitas coisas interessantes. Aliás, também existe a opção de forçar o usuário a redirecionar no frame, mas o endereço na barra de endereço não muda, o que pode incendiar rapidamente a mesa e essa opção tem finalidades um pouco diferentes.
    Em geral, o BeEF tem quase tudo que você precisa e até muitas funções adicionais, mas pessoalmente eu queria funcionalidades adicionais, a saber:

    • a capacidade de monitorar o código das páginas acessíveis ao usuário atacado em tempo real;
    • a possibilidade de ver tudo o que ele digita naquele site (desde login e senha, até teclas de atalho e mensagens), ou seja, um keylogger em JS;
    • a possibilidade de dar comandos JS ao seu bot em tempo real, após visualizar o código das páginas recebidas;
    • a possibilidade de deixar comandos para o bot localmente, para que posteriormente ele possa “pegá-los” e executá-los sem nossa participação direta;
    • uma menor probabilidade de o bot ser queimado ou a capacidade do bot de “se esconder” de olhares indiscretos;

    Como mencionado acima, decidi pegar emprestada a ideia legal de uma fila de execução de comandos do BeEF. Por exemplo, analisamos as páginas que o bot derrubou quando um usuário privilegiado estava acessando seu painel de controle com XSS armazenado, deixamos comandos para o bot - código JS, como na próxima vez que o usuário fizer login, clique neste botão, escreva isto valor aqui, etc., na próxima vez que esse usuário visitar a página, o bot lê os comandos e os executa, e não precisamos estar no comando para tudo - é muito conveniente.

    Basicamente, esse bot é, obviamente, projetado para usuários de alto status de alguns sites que possuem “alavancas” adicionais para gerenciar conteúdo, outros usuários, etc. Pelas solicitações de funcionalidade fica claro que não podemos prescindir da parte do servidor.

    Vamos implementar a ideia.

    A princípio, você pode pular esta parte do artigo, pois ela simplesmente descreve o processo de implementação do bot desejado e alguns de seus detalhes, caso alguém queira refazê-lo ou customizá-lo para si. Embora o bot tenha variáveis ​​​​no início do código através das quais você pode definir algumas configurações.
    Primeiro, o algoritmo das ações do bot desde o momento do carregamento:

    1) Verificando a presença do cabeçalho Opções de quadro X: NEGAR(se houver, enrolamos as varas de pescar);
    2) Incorporar um frame e configurar todos os componentes do bot;
    3) Removendo o script e todos os rastros do código HTML;
    4) Estabelecer contato com a parte servidora e passar a enviar dados, respondendo às respostas (recebendo comandos do servidor);

    O primeiro ponto não foi feito completamente, ou seja, o bot verifica apenas a primeira página e o cabeçalho raiz. O fato é que normalmente esses cabeçalhos são incorporados pelo servidor web para todas as páginas de uma vez e é muito raro que para uma única página tudo seja feito “manualmente”. E este título em si é bastante raro. Bom, não há muito o que falar sobre o segundo e o terceiro, tudo estará abaixo.

    Há um ponto relativamente importante que antes de adicionar código de script de bot em seu código, você precisa se livrar dos sinais XSS na barra de endereço imediatamente (do código JS), pois isso reduz as chances de detecção e, o mais importante, evita recursão isso ocorre ao adicionar um endereço ao quadro com o mesmo código XSS, que por sua vez cria outro quadro consigo mesmo e assim por diante.

    Mas, por precaução, o código do bot implementa a capacidade de detectar tal recursão de quadro e evitá-la na primeira tentativa de adicionar um quadro a um já criado, mas é melhor não confiar apenas nele, mas remover adicionalmente o código antes de carregar o código do bot. Embora ainda não tenha encontrado nenhum problema.

    Função de verificação de atualização de quadro. Tentei várias maneiras de resolver esse problema economicamente, pendurando manipuladores de eventos em janela de conteúdo ou documento de conteúdo, mas nada funcionou, então tive que escrever uma função que verificasse o endereço do quadro e comparasse com o salvo anteriormente, e com base nisso, decidisse se o quadro estava sendo atualizado (se o endereço havia mudado) e então chama a si mesmo recursivamente.

    A frequência dessas verificações por segundo é controlada pela variável atraso, que está listado no início do arquivo de código do bot. Mas depois, já tendo escrito, encontrei uma solução mais eficaz - use uma solução simples e desligue carregando para o quadro, então deixei essa função, mas comentei, caso mais tarde seja mais procurada.

    Envio do código HTML da página.

    O esquema aqui é bastante simples - após cada recarga de frame (incluindo o primeiro carregamento), o bot envia para o servidor todo o código HTML da página junto com seu endereço atual, para que posteriormente você possa distinguir se o código pertence ao desejado Páginas.

    O servidor implementa a lógica de armazenamento de páginas - o servidor cria uma pasta para cada domínio com o nome deste domínio e salva todos os dados lá. Os códigos das páginas são salvos e atualizados constantemente para as versões mais recentes, mas a cada novo dia uma nova cópia da página é criada para que você possa controlar o histórico de versões, se necessário. Isso é para /notícias.php No dia 1º de setembro o estado será atualizado, e no dia 2 de setembro será criada uma cópia dele, relevante apenas para aquele dia, e assim sucessivamente todos os dias novamente (se o usuário visitar esta página todos os dias). O nome da página consiste na data e no caminho para esta página em relação à raiz do site (ou seja, sem o domínio).

    Keylogger em JavaScript.

    A ideia já havia sido implementada por alguns entusiastas, mas o trabalho deles não me agradou, até porque a maioria deles eram bastante simples, ou seja, detectaram o código da tecla pressionada e através String.fromCharCode traduzido em símbolos. Mas este método tem uma série de desvantagens - teclas de controle como shift, control, espaço, etc., não são traduzidas em nenhum formato (muitas vezes simplesmente em um caractere vazio), a interação das teclas alfanuméricas com shift é registrada incorretamente, uma vez que este deve ser implementado programaticamente, e Além disso, todas as teclas pressionadas são exibidas em letras maiúsculas, o que também pode ser corrigido programaticamente.

    O resultado foi um keylogger que detectou corretamente todas as teclas de números, letras e caracteres básicos, funcionando em ambos os layouts, reagindo ao shift e registrando todas as principais teclas especiais. É verdade que alguns caracteres (no topo da linha numérica, que são impressos quando o shift e o número são pressionados) podem ser diferentes em algumas máquinas, pois foram implementados de acordo com o padrão básico, que algumas empresas alteram.
    Cada parte dos caracteres pressionada é retida pelo cliente até que o elemento de texto perca o foco. Em seguida, essa parte é enviada para o servidor, onde é salva em um arquivo de texto, que também será criado todos os dias com uma nova cópia, para que não cresça em tamanhos grandes e você possa encontrar rapidamente o que o usuário estava digitando naquela hora.
    Além das próprias chaves, a cada trecho são enviadas ao servidor informações sobre o elemento em que o texto foi digitado (ou seja, se foi , [ ou alguns quando o usuário utilizou teclas de atalho), além do nome do elemento, são enviados seus dados básicos (id, nome, classe - se houver) para que possam ser facilmente encontrados no código. E claro, ficam registrados o endereço da página onde foi feito o recrutamento e o horário aproximado desse recrutamento. Em geral, informações suficientes sobre as batidas do teclado do usuário são enviadas para análise posterior.

    Comande seu bot.

    Este processo pode ser realizado pelo invasor ou no lado onde o bot irá rodar, no lado do servidor ou até mesmo remotamente. Depois de executar o script do servidor, um servidor web em miniatura auto-escrito é iniciado, que atende solicitações do bot e de seu controlador, que funciona por meio da interface web. Ou seja, após iniciar, o servidor web emite um link, através do qual você pode começar a dar comandos ao bot.

    Sobre este painel de controle. Em primeiro lugar, foi necessário restringi-lo com uma senha (o caminho e poucas pessoas saberão sobre o serviço em execução em tal ou tal porta ou sobre o endereço que precisam ir para utilizar este serviço), para que no primeiro login o servidor solicitará uma senha, que é fornecida na barra de endereço (será fornecido um exemplo), a senha original é armazenada em senha.txt, que pode ser alterado. Após o primeiro login, o servidor web instruirá o navegador a salvar a senha em um cookie, para que você não precise mais se preocupar com isso.

    Na própria página de envio de comandos ao bot também há informações sobre o estado do bot - se está online ou offline no momento, e algumas configurações, a primeira delas é o host, ou seja, o IP endereço ou domínio do site para o qual os comandos serão enviados ao bot. Isso foi projetado caso vários sites contenham esse bot, para que possam ser identificados. No servidor, também neste caso, todos os dados são divididos em pastas com nomes de domínio.
    A seguir está uma janela onde você pode escrever comandos para o bot em JS, e uma opção que define onde esse código JS será executado, na janela principal onde o bot está ou em um quadro - isso é feito por conveniência, apenas por precaução .

    Se o bot não estiver online, o servidor simplesmente salva os comandos e posteriormente, quando o bot ficar online, ou seja, o usuário visitar novamente a página com ele ou seguir o link do invasor, esses comandos serão executados.
    Isto é muito conveniente se, durante o primeiro reconhecimento, o bot descartou todas as páginas visitadas pelo usuário (por exemplo, uma conta pessoal), após estudar o código do qual escrevemos comandos em JS, para que o bot então clicasse em os links que precisamos, insira os dados necessários, exiba as fotos necessárias, etc., o que o ajudará a atingir seu objetivo.

    Ou você pode diretamente em tempo real, olhar rapidamente o conteúdo das páginas através do código e dar comandos ao bot para que ele envie o código de outras páginas, vá para outro endereço, etc. tela” do usuário, que navegará tranquilamente no site através de um frame.

    Para sua conveniência, você pode transformar as instruções usadas com mais frequência em funções inteiras em JS, que são então inseridas no arquivo de origem do bot ( xsb.js, mais sobre a estrutura do arquivo abaixo) e use. Ou use aquelas funções que estão incluídas no bot, embora exista apenas o básico e não haja nada de novo, mas por exemplo, você pode usar a função de enviar o código da página a qualquer momento, e não quando o frame for recarregado. Você pode escrever uma função que abrirá os links passados ​​​​a ela em novos frames em segundo plano para visualizar o conteúdo de várias páginas ao mesmo tempo em nome do usuário (e operar esse conteúdo com suas mãos virtuais).

    Removendo seu próprio código.

    Pois bem, o último recurso é implementado de forma bastante simples (pode ser desabilitado definindo a variável desejada no arquivo, estão comentados). O script, após configurar e suspender todos os manipuladores de eventos, criando todas as variáveis ​​e funções, se exclui

    Afinal todos os dados já foram carregados na RAM através do navegador, então não há com o que se preocupar, mas isso é em teoria, talvez mais tarde haja alguns problemas que não levei em consideração, então criei uma variável que pode ser usado para desativar esse recurso conforme necessário.

    Depois de excluir todos os scripts, será extremamente difícil perceber o XSS, pois a presença de um quadro não indica isso indiretamente, e o código em si só pode ser encontrado nos logs de histórico de tráfego de rede do navegador (que não são mantidos por padrão em muitos navegadores se o painel do desenvolvedor não estiver aberto).

    Parte do servidor.

    Para uma forma mais simples e conveniente de iniciar o bot, decidiu-se escrever nosso próprio pequeno servidor web em soquetes, que serviria o bot, forneceria todas as operações de recebimento e postagem dos dados enviados, transmitiria mensagens entre o invasor e o bot, e crie uma interface web para o invasor para o comando.
    O servidor foi escrito em Python, tentei usar apenas bibliotecas padrão para não precisar instalar nada antes de lançar. Além disso, o próprio servidor edita alguns dados nos scripts, ou seja, no script JS do bot não há necessidade de definir o endereço do servidor comandante, o próprio servidor web irá definir o necessário lá na inicialização. Existe apenas um parâmetro na configuração do servidor - a porta na qual ele será iniciado (padrão 8000).
    Após a inicialização, o servidor fornecerá todos os dados necessários - um link para o script JS, que precisará ser inserido, um link para o painel de comando, ou melhor, links para endereços externos e locais, por conveniência.

    Esquema de trabalho com o bot.

    Lançamos o servidor em alguma porta não reivindicada e você pode enviar um link com um script de bot, então todos que clicarem nele enviarão dados que o servidor salvará a qualquer hora do dia. Então você pode simplesmente visualizá-los se houver necessidade de sair do bot da equipe e continuar fazendo seu próprio trabalho.

    Estrutura de arquivos.

    A pasta contém os seguintes arquivos:

    • xsb.py - arquivo principal que implementa a parte do servidor para o bot funcionar, execute-o e basta usar o link que ele oferece;
    • xsb.js - aqui é armazenado o código JS do bot, cujo link é fornecido pelo servidor, são declaradas variáveis ​​​​de configuração no início do mesmo, que podem ser alteradas a seu critério (algumas, nomeadamente o host e a porta, o servidor será configurado mais tarde, você não precisa se preocupar);
    • panel.html - daqui o servidor pega o código do painel de controle do bot, você pode personalizar a interface a seu critério;
    • password.txt - aqui fica armazenada a senha do painel de controle, que pode ser alterada;
    • saveData é o diretório onde serão criadas as pastas com domínios de sites, onde serão salvas todas as informações.

    Deixe-me observar novamente que no arquivo xsb.js você pode adicionar suas próprias funções, que podem ser chamadas através do painel sem escrever grandes porções de código;

    Uma breve análise dos resultados.

    Depois de escrever minha própria maneira inventada de manter um usuário em uma página com XSS por meio de frames (bem, como inventado - eu pessoalmente descobri por mim mesmo, é bem possível que alguém “inventou” essa mesma técnica para si ou já esteja em algum lugar em o público brilhou, porque agora é muito difícil desenvolver algo verdadeiramente novo e, via de regra, depois de algum tempo você descobre que “isso já estava nos Simpsons”) comecei a me aprofundar no BeEF com mais detalhes e a ler seu wiki. Então descobri que outra técnica foi implementada ali para atingir o mesmo objetivo - estender o tempo do usuário em uma página com XSS executável (que eles chamaram de homem no navegador). E foi implementado assim: todos os links da página original foram alterados de tal forma que ao clicar em algum deles o script não recarregava a página, mas através do Ajax enviava uma solicitação ao servidor e inseria os dados recebido na resposta, ou seja, pode-se dizer que o atualizou artificialmente, o que também era quase indistinguível do refresco comum.

    Portanto, não fui o primeiro a concretizar esta ideia (mesmo que os métodos tenham sido diferentes). Mas ambos os métodos têm suas desvantagens:

    O método de carregamento via não funciona se houver um cabeçalho na resposta Opções de quadro X: NEGAR, mas por outro lado funciona como uma janela normal do navegador;

    O método ajax sempre funciona se o navegador o suportar (todos os principais navegadores o suportam agora), mas com o novo padrão Web 2.0, mais e mais transições são acionadas por eventos personalizados de qualquer elemento via JS. Um dia fui ao Google AdWords e resolvi ver como o HTML e JS deles interagiam ali, pois todos os meus spiders eram péssimos na criação do back map desse serviço. E eu fiquei surtando silenciosamente a noite toda sobre como tudo era incomum ali, quando os elementos de texto eram botões, seletores e controles deslizantes e eram representados com todo o resto, e cada um tinha cerca de 30 manipuladores para eventos diferentes.

    Ou seja, em um site sofisticado, o botão de transição (subjetivamente um link) será implementado por meio de uma tag normal , que é carregado com estilos e nos quais os manipuladores de eventos estão anexados, um dos quais, por exemplo, onclick redireciona o usuário para outra página. Existem também elementos padrão como [i] ou ele mesmo etc., que também são links para outras páginas, mas às quais o BeEF não responderá e a página simplesmente não será atualizada quando você clicar na maioria dos botões e outros elementos. O que pode solicitar que o usuário atualize a página ou entre novamente pelo outro lado, o que mata nossa sessão XSS ativa.

    Para abreviar a nomenclatura dos arquivos, chamei-o de Xss Spy Bot.

    P.S.
    Tudo isso demorou pouco mais de um mês para ser escrito devido à falta periódica de tempo e distrações constantes. Também por isso, a qualidade do código e a probabilidade de encontrar algum bug são bastante altas. Por isso peço que não xingue muito, mas que anote o que há de errado com alguém para que possa ser corrigido.
    Eu mesmo testei o bot em apenas 4 máquinas, todas rodando Debian.

    Planos de longo prazo para este bot, se houver motivação:
    - implementar a renderização do código das páginas que o bot envia ao servidor, para que ele abra imediatamente no navegador e possa ser “tocado” e testado na hora;
    - eles tentarão aproveitar algumas vantagens da tecnologia WebRTC, ou seja, encontrar maneiras de obter novas informações que o JS puro não consegue extrair;
    - implementar a comunicação entre o bot e o servidor usando o protocolo WebSocket sobre HTTP;
    - adicione algumas comodidades ao painel de controle;

    Usando XSS, invasores experientes integram scripts executados neles nas páginas dos sites das vítimas, executados ao visitar recursos infectados. Existem vários tipos de vulnerabilidades XSS que apresentam vários graus de gravidade.

    Características de vulnerabilidade passiva e ativa

    Você deve ter mais cuidado ao lidar com vulnerabilidades ativas. Quando um invasor injeta seu código SQL em um banco de dados ou arquivo acessível em um servidor, cada visitante do recurso infectado pode se tornar uma vítima. Tais locais são muitas vezes integrados, por isso mesmo os dados armazenados na base de dados, processados ​​pela sua proteção, ainda podem representar algum perigo.

    Criar uma vulnerabilidade XSS passiva requer alguma engenhosidade por parte do invasor. Ou eles estão atraindo você para um recurso falso com todos os tipos de links ou estão tentando redirecioná-lo para o site desejado por qualquer meio. Isso geralmente acontece por meio de cartas da administração fictícia da página que você está visitando, solicitando que você verifique as configurações da sua conta. Várias correspondências de spam ou postagens em fóruns amplamente visitados também são usadas ativamente.

    Vulnerabilidades passivas de XSS podem vir de parâmetros POST e GET. Os primeiros são caracterizados por uma série de truques diferentes, enquanto os últimos são caracterizados pela codificação da string do URL ou pela inserção de valores adicionais.

    Roubando biscoitos

    Na maioria das vezes, são os seus Cookies que se tornam alvo de um ataque XSS. Às vezes, eles contêm informações valiosas, incluindo logins e senhas de usuários ou seu hash. Mas roubar sessões ativas de sites que são importantes para você também é bastante perigoso, por isso não se esqueça de clicar no botão “sair” mesmo ao visitar sites do seu computador doméstico. Embora a maioria dos recursos use limites automáticos de duração de sessão para evitar tais ações. As restrições de domínio em XMLHttpRequest não protegem contra tais ataques.

    Dados de formulários preenchidos

    A leitura de informações em formulários preenchíveis também é popular. Para isso, o rastreamento de eventos (onsubmit) é realizado nas páginas de interesse, e todos os dados fornecidos também são enviados aos servidores dos invasores. Esses ataques são em muitos aspectos semelhantes aos ataques de phishing, mas o roubo não ocorre em um site falso, mas em um site real com boa reputação.

    Ataques DDoS distribuídos

    Recursos multivisitados também são usados ​​para ataques XSS. Graças à vulnerabilidade XSS, as solicitações que chegam a eles são redirecionadas para o servidor hackeado, resultando em falha em sua proteção.

    Falsificação de solicitação entre sites (CSRF/XSRF)

    Eles também têm pouco em comum com o XSS. Este é um tipo separado de vulnerabilidade usado em combinação com XSS. Seu objetivo é atrair um usuário autorizado de um site invulnerável para uma página vulnerável falsa para realizar transações fraudulentas. Por exemplo, um cliente que utiliza um sistema de pagamento eletrônico é atraído para um site vulnerável que transfere dinheiro para contas de invasores. Portanto, a maioria dos sistemas de pagamento oferece proteção inserindo adicionalmente uma senha ou código de confirmação da operação.

    Injeção de worms XSS

    Esse ataque XSS a um site apareceu com o desenvolvimento de redes sociais conhecidas (VKontakte, Twitter e outras). Através deles, grupos inteiros de usuários recebem links XSS vulneráveis ​​com scripts integrados que enviam spam pelas redes em seu nome. Também é amplamente praticado copiar simultaneamente informações pessoais e fotografias para os recursos dos invasores.

    Exemplos de XSS inofensivos

    Observe que muitos tipos de contadores também atuam como XSS ativo. Eles transmitem dados sobre os visitantes registrados (seus endereços IP, dados sobre os equipamentos utilizados).

    Somente este código é integrado ao seu computador de acordo com sua vontade. Outros XSS semelhantes podem facilmente incluir uma série de solicitações AJAX entre domínios.

    Visualizações