зеркало из https://github.com/mozilla/MozDef.git
Merge pull request #323 from yashmehrotra/master
[Mozilla Winter of Security] 3D interactive Attack visualization via Landmass
This commit is contained in:
Коммит
48a650f379
|
@ -417,7 +417,8 @@ def updateMongoWithESEvents(mozdefdb, results):
|
|||
esrecord = dict(documentid=r['_id'],
|
||||
documenttype=r['_type'],
|
||||
documentindex=r['_index'],
|
||||
documentsource=r['_source'])
|
||||
documentsource=r['_source'],
|
||||
read=False)
|
||||
|
||||
logger.debug('searching for ' + str(sourceIP))
|
||||
#attacker = attackers.find_one({'events.details.sourceipaddress': str(sourceIP.ip)})
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 426 KiB |
|
@ -61,6 +61,14 @@ to quickly filter attackers by category or timeframe and get easy access to rece
|
|||
|
||||
.. image:: images/AttackerOgres.png
|
||||
|
||||
3D interactive Attack visualization via Landmass
|
||||
-------------------------------------
|
||||
MozDef has a service-oriented visualization where you will get see various animations on a landmass service wise.
|
||||
There are also options for handling attacks, and a sidebar which gives you detailed info into the attacks
|
||||
|
||||
|
||||
.. image:: images/AttacksLandmass.png
|
||||
|
||||
Demo Instance
|
||||
=============
|
||||
|
||||
|
|
|
@ -0,0 +1,583 @@
|
|||
/**
|
||||
* @author qiao / https://github.com/qiao
|
||||
* @author mrdoob / http://mrdoob.com
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
* @author WestLangley / http://github.com/WestLangley
|
||||
* @author erich666 / http://erichaines.com
|
||||
*/
|
||||
/*global THREE, console */
|
||||
|
||||
// This set of controls performs orbiting, dollying (zooming), and panning. It maintains
|
||||
// the "up" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is
|
||||
// supported.
|
||||
//
|
||||
// Orbit - left mouse / touch: one finger move
|
||||
// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
|
||||
// Pan - right mouse, or arrow keys / touch: three finter swipe
|
||||
//
|
||||
// This is a drop-in replacement for (most) TrackballControls used in examples.
|
||||
// That is, include this js file and wherever you see:
|
||||
// controls = new THREE.TrackballControls( camera );
|
||||
// controls.target.z = 150;
|
||||
// Simple substitute "OrbitControls" and the control should work as-is.
|
||||
|
||||
THREE.OrbitControls = function ( object, domElement ) {
|
||||
|
||||
this.object = object;
|
||||
this.domElement = ( domElement !== undefined ) ? domElement : document;
|
||||
|
||||
// API
|
||||
|
||||
// Set to false to disable this control
|
||||
this.enabled = true;
|
||||
|
||||
// "target" sets the location of focus, where the control orbits around
|
||||
// and where it pans with respect to.
|
||||
this.target = new THREE.Vector3();
|
||||
// center is old, deprecated; use "target" instead
|
||||
this.center = this.target;
|
||||
|
||||
// This option actually enables dollying in and out; left as "zoom" for
|
||||
// backwards compatibility
|
||||
this.noZoom = false;
|
||||
this.zoomSpeed = 1.0;
|
||||
// Limits to how far you can dolly in and out
|
||||
this.minDistance = 0;
|
||||
this.maxDistance = Infinity;
|
||||
|
||||
// Set to true to disable this control
|
||||
this.noRotate = false;
|
||||
this.rotateSpeed = 1.0;
|
||||
|
||||
// Set to true to disable this control
|
||||
this.noPan = false;
|
||||
this.keyPanSpeed = 7.0; // pixels moved per arrow key push
|
||||
|
||||
// Set to true to automatically rotate around the target
|
||||
this.autoRotate = false;
|
||||
this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
|
||||
|
||||
// How far you can orbit vertically, upper and lower limits.
|
||||
// Range is 0 to Math.PI radians.
|
||||
this.minPolarAngle = 0; // radians
|
||||
this.maxPolarAngle = Math.PI; // radians
|
||||
|
||||
// Set to true to disable use of the keys
|
||||
this.noKeys = false;
|
||||
// The four arrow keys
|
||||
this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
|
||||
|
||||
////////////
|
||||
// internals
|
||||
|
||||
var scope = this;
|
||||
|
||||
var EPS = 0.000001;
|
||||
|
||||
var rotateStart = new THREE.Vector2();
|
||||
var rotateEnd = new THREE.Vector2();
|
||||
var rotateDelta = new THREE.Vector2();
|
||||
|
||||
var panStart = new THREE.Vector2();
|
||||
var panEnd = new THREE.Vector2();
|
||||
var panDelta = new THREE.Vector2();
|
||||
|
||||
var dollyStart = new THREE.Vector2();
|
||||
var dollyEnd = new THREE.Vector2();
|
||||
var dollyDelta = new THREE.Vector2();
|
||||
|
||||
var phiDelta = 0;
|
||||
var thetaDelta = 0;
|
||||
var scale = 1;
|
||||
var pan = new THREE.Vector3();
|
||||
|
||||
var lastPosition = new THREE.Vector3();
|
||||
|
||||
var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };
|
||||
var state = STATE.NONE;
|
||||
|
||||
// events
|
||||
|
||||
var changeEvent = { type: 'change' };
|
||||
|
||||
|
||||
this.rotateLeft = function ( angle ) {
|
||||
|
||||
if ( angle === undefined ) {
|
||||
|
||||
angle = getAutoRotationAngle();
|
||||
|
||||
}
|
||||
|
||||
thetaDelta -= angle;
|
||||
|
||||
};
|
||||
|
||||
this.rotateUp = function ( angle ) {
|
||||
|
||||
if ( angle === undefined ) {
|
||||
|
||||
angle = getAutoRotationAngle();
|
||||
|
||||
}
|
||||
|
||||
phiDelta -= angle;
|
||||
|
||||
};
|
||||
|
||||
// pass in distance in world space to move left
|
||||
this.panLeft = function ( distance ) {
|
||||
|
||||
var panOffset = new THREE.Vector3();
|
||||
var te = this.object.matrix.elements;
|
||||
// get X column of matrix
|
||||
panOffset.set( te[0], te[1], te[2] );
|
||||
panOffset.multiplyScalar(-distance);
|
||||
|
||||
pan.add( panOffset );
|
||||
|
||||
};
|
||||
|
||||
// pass in distance in world space to move up
|
||||
this.panUp = function ( distance ) {
|
||||
|
||||
var panOffset = new THREE.Vector3();
|
||||
var te = this.object.matrix.elements;
|
||||
// get Y column of matrix
|
||||
panOffset.set( te[4], te[5], te[6] );
|
||||
panOffset.multiplyScalar(distance);
|
||||
|
||||
pan.add( panOffset );
|
||||
};
|
||||
|
||||
// main entry point; pass in Vector2 of change desired in pixel space,
|
||||
// right and down are positive
|
||||
this.pan = function ( delta ) {
|
||||
|
||||
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
|
||||
|
||||
if ( scope.object.fov !== undefined ) {
|
||||
|
||||
// perspective
|
||||
var position = scope.object.position;
|
||||
var offset = position.clone().sub( scope.target );
|
||||
var targetDistance = offset.length();
|
||||
|
||||
// half of the fov is center to top of screen
|
||||
targetDistance *= Math.tan( (scope.object.fov/2) * Math.PI / 180.0 );
|
||||
// we actually don't use screenWidth, since perspective camera is fixed to screen height
|
||||
scope.panLeft( 2 * delta.x * targetDistance / element.clientHeight );
|
||||
scope.panUp( 2 * delta.y * targetDistance / element.clientHeight );
|
||||
|
||||
} else if ( scope.object.top !== undefined ) {
|
||||
|
||||
// orthographic
|
||||
scope.panLeft( delta.x * (scope.object.right - scope.object.left) / element.clientWidth );
|
||||
scope.panUp( delta.y * (scope.object.top - scope.object.bottom) / element.clientHeight );
|
||||
|
||||
} else {
|
||||
|
||||
// camera neither orthographic or perspective - warn user
|
||||
console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.dollyIn = function ( dollyScale ) {
|
||||
|
||||
if ( dollyScale === undefined ) {
|
||||
|
||||
dollyScale = getZoomScale();
|
||||
|
||||
}
|
||||
|
||||
scale /= dollyScale;
|
||||
|
||||
};
|
||||
|
||||
this.dollyOut = function ( dollyScale ) {
|
||||
|
||||
if ( dollyScale === undefined ) {
|
||||
|
||||
dollyScale = getZoomScale();
|
||||
|
||||
}
|
||||
|
||||
scale *= dollyScale;
|
||||
|
||||
};
|
||||
|
||||
this.update = function () {
|
||||
|
||||
var position = this.object.position;
|
||||
var offset = position.clone().sub( this.target );
|
||||
|
||||
// angle from z-axis around y-axis
|
||||
|
||||
var theta = Math.atan2( offset.x, offset.z );
|
||||
|
||||
// angle from y-axis
|
||||
|
||||
var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
|
||||
|
||||
if ( this.autoRotate ) {
|
||||
|
||||
this.rotateLeft( getAutoRotationAngle() );
|
||||
|
||||
}
|
||||
|
||||
theta += thetaDelta;
|
||||
phi += phiDelta;
|
||||
|
||||
// restrict phi to be between desired limits
|
||||
phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
|
||||
|
||||
// restrict phi to be betwee EPS and PI-EPS
|
||||
phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
|
||||
|
||||
var radius = offset.length() * scale;
|
||||
|
||||
// restrict radius to be between desired limits
|
||||
radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
|
||||
|
||||
// move target to panned location
|
||||
this.target.add( pan );
|
||||
|
||||
offset.x = radius * Math.sin( phi ) * Math.sin( theta );
|
||||
offset.y = radius * Math.cos( phi );
|
||||
offset.z = radius * Math.sin( phi ) * Math.cos( theta );
|
||||
|
||||
position.copy( this.target ).add( offset );
|
||||
|
||||
this.object.lookAt( this.target );
|
||||
|
||||
thetaDelta = 0;
|
||||
phiDelta = 0;
|
||||
scale = 1;
|
||||
pan.set(0,0,0);
|
||||
|
||||
if ( lastPosition.distanceTo( this.object.position ) > 0 ) {
|
||||
|
||||
this.dispatchEvent( changeEvent );
|
||||
|
||||
lastPosition.copy( this.object.position );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
function getAutoRotationAngle() {
|
||||
|
||||
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
|
||||
|
||||
}
|
||||
|
||||
function getZoomScale() {
|
||||
|
||||
return Math.pow( 0.95, scope.zoomSpeed );
|
||||
|
||||
}
|
||||
|
||||
function onMouseDown( event ) {
|
||||
|
||||
if ( scope.enabled === false ) { return; }
|
||||
event.preventDefault();
|
||||
|
||||
if ( event.button === 0 ) {
|
||||
if ( scope.noRotate === true ) { return; }
|
||||
|
||||
state = STATE.ROTATE;
|
||||
|
||||
rotateStart.set( event.clientX, event.clientY );
|
||||
|
||||
} else if ( event.button === 1 ) {
|
||||
if ( scope.noZoom === true ) { return; }
|
||||
|
||||
state = STATE.DOLLY;
|
||||
|
||||
dollyStart.set( event.clientX, event.clientY );
|
||||
|
||||
} else if ( event.button === 2 ) {
|
||||
if ( scope.noPan === true ) { return; }
|
||||
|
||||
state = STATE.PAN;
|
||||
|
||||
panStart.set( event.clientX, event.clientY );
|
||||
|
||||
}
|
||||
|
||||
// Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be
|
||||
scope.domElement.addEventListener( 'mousemove', onMouseMove, false );
|
||||
scope.domElement.addEventListener( 'mouseup', onMouseUp, false );
|
||||
|
||||
}
|
||||
|
||||
function onMouseMove( event ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
|
||||
|
||||
if ( state === STATE.ROTATE ) {
|
||||
|
||||
if ( scope.noRotate === true ) return;
|
||||
|
||||
rotateEnd.set( event.clientX, event.clientY );
|
||||
rotateDelta.subVectors( rotateEnd, rotateStart );
|
||||
|
||||
// rotating across whole screen goes 360 degrees around
|
||||
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
|
||||
// rotating up and down along whole screen attempts to go 360, but limited to 180
|
||||
scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
|
||||
|
||||
rotateStart.copy( rotateEnd );
|
||||
|
||||
} else if ( state === STATE.DOLLY ) {
|
||||
|
||||
if ( scope.noZoom === true ) return;
|
||||
|
||||
dollyEnd.set( event.clientX, event.clientY );
|
||||
dollyDelta.subVectors( dollyEnd, dollyStart );
|
||||
|
||||
if ( dollyDelta.y > 0 ) {
|
||||
|
||||
scope.dollyIn();
|
||||
|
||||
} else {
|
||||
|
||||
scope.dollyOut();
|
||||
|
||||
}
|
||||
|
||||
dollyStart.copy( dollyEnd );
|
||||
|
||||
} else if ( state === STATE.PAN ) {
|
||||
|
||||
if ( scope.noPan === true ) return;
|
||||
|
||||
panEnd.set( event.clientX, event.clientY );
|
||||
panDelta.subVectors( panEnd, panStart );
|
||||
|
||||
scope.pan( panDelta );
|
||||
|
||||
panStart.copy( panEnd );
|
||||
|
||||
}
|
||||
|
||||
// Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be
|
||||
scope.update();
|
||||
|
||||
}
|
||||
|
||||
function onMouseUp( /* event */ ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
|
||||
// Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be
|
||||
scope.domElement.removeEventListener( 'mousemove', onMouseMove, false );
|
||||
scope.domElement.removeEventListener( 'mouseup', onMouseUp, false );
|
||||
|
||||
state = STATE.NONE;
|
||||
|
||||
}
|
||||
|
||||
function onMouseWheel( event ) {
|
||||
|
||||
if ( scope.enabled === false || scope.noZoom === true ) return;
|
||||
|
||||
var delta = 0;
|
||||
|
||||
if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
|
||||
|
||||
delta = event.wheelDelta;
|
||||
|
||||
} else if ( event.detail ) { // Firefox
|
||||
|
||||
delta = - event.detail;
|
||||
|
||||
}
|
||||
|
||||
if ( delta > 0 ) {
|
||||
|
||||
scope.dollyOut();
|
||||
|
||||
} else {
|
||||
|
||||
scope.dollyIn();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onKeyDown( event ) {
|
||||
|
||||
if ( scope.enabled === false ) { return; }
|
||||
if ( scope.noKeys === true ) { return; }
|
||||
if ( scope.noPan === true ) { return; }
|
||||
|
||||
// pan a pixel - I guess for precise positioning?
|
||||
// Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be
|
||||
var needUpdate = false;
|
||||
|
||||
switch ( event.keyCode ) {
|
||||
|
||||
case scope.keys.UP:
|
||||
scope.pan( new THREE.Vector2( 0, scope.keyPanSpeed ) );
|
||||
needUpdate = true;
|
||||
break;
|
||||
case scope.keys.BOTTOM:
|
||||
scope.pan( new THREE.Vector2( 0, -scope.keyPanSpeed ) );
|
||||
needUpdate = true;
|
||||
break;
|
||||
case scope.keys.LEFT:
|
||||
scope.pan( new THREE.Vector2( scope.keyPanSpeed, 0 ) );
|
||||
needUpdate = true;
|
||||
break;
|
||||
case scope.keys.RIGHT:
|
||||
scope.pan( new THREE.Vector2( -scope.keyPanSpeed, 0 ) );
|
||||
needUpdate = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be
|
||||
if ( needUpdate ) {
|
||||
|
||||
scope.update();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function touchstart( event ) {
|
||||
|
||||
if ( scope.enabled === false ) { return; }
|
||||
|
||||
switch ( event.touches.length ) {
|
||||
|
||||
case 1: // one-fingered touch: rotate
|
||||
if ( scope.noRotate === true ) { return; }
|
||||
|
||||
state = STATE.TOUCH_ROTATE;
|
||||
|
||||
rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
||||
break;
|
||||
|
||||
case 2: // two-fingered touch: dolly
|
||||
if ( scope.noZoom === true ) { return; }
|
||||
|
||||
state = STATE.TOUCH_DOLLY;
|
||||
|
||||
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
|
||||
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
|
||||
var distance = Math.sqrt( dx * dx + dy * dy );
|
||||
dollyStart.set( 0, distance );
|
||||
break;
|
||||
|
||||
case 3: // three-fingered touch: pan
|
||||
if ( scope.noPan === true ) { return; }
|
||||
|
||||
state = STATE.TOUCH_PAN;
|
||||
|
||||
panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
||||
break;
|
||||
|
||||
default:
|
||||
state = STATE.NONE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function touchmove( event ) {
|
||||
|
||||
if ( scope.enabled === false ) { return; }
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
|
||||
|
||||
switch ( event.touches.length ) {
|
||||
|
||||
case 1: // one-fingered touch: rotate
|
||||
if ( scope.noRotate === true ) { return; }
|
||||
if ( state !== STATE.TOUCH_ROTATE ) { return; }
|
||||
|
||||
rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
||||
rotateDelta.subVectors( rotateEnd, rotateStart );
|
||||
|
||||
// rotating across whole screen goes 360 degrees around
|
||||
scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
|
||||
// rotating up and down along whole screen attempts to go 360, but limited to 180
|
||||
scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
|
||||
|
||||
rotateStart.copy( rotateEnd );
|
||||
break;
|
||||
|
||||
case 2: // two-fingered touch: dolly
|
||||
if ( scope.noZoom === true ) { return; }
|
||||
if ( state !== STATE.TOUCH_DOLLY ) { return; }
|
||||
|
||||
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
|
||||
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
|
||||
var distance = Math.sqrt( dx * dx + dy * dy );
|
||||
|
||||
dollyEnd.set( 0, distance );
|
||||
dollyDelta.subVectors( dollyEnd, dollyStart );
|
||||
|
||||
if ( dollyDelta.y > 0 ) {
|
||||
|
||||
scope.dollyOut();
|
||||
|
||||
} else {
|
||||
|
||||
scope.dollyIn();
|
||||
|
||||
}
|
||||
|
||||
dollyStart.copy( dollyEnd );
|
||||
break;
|
||||
|
||||
case 3: // three-fingered touch: pan
|
||||
if ( scope.noPan === true ) { return; }
|
||||
if ( state !== STATE.TOUCH_PAN ) { return; }
|
||||
|
||||
panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
|
||||
panDelta.subVectors( panEnd, panStart );
|
||||
|
||||
scope.pan( panDelta );
|
||||
|
||||
panStart.copy( panEnd );
|
||||
break;
|
||||
|
||||
default:
|
||||
state = STATE.NONE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function touchend( /* event */ ) {
|
||||
|
||||
if ( scope.enabled === false ) { return; }
|
||||
|
||||
state = STATE.NONE;
|
||||
}
|
||||
|
||||
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
|
||||
this.domElement.addEventListener( 'mousedown', onMouseDown, false );
|
||||
this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
|
||||
this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
|
||||
|
||||
this.domElement.addEventListener( 'keydown', onKeyDown, false );
|
||||
|
||||
this.domElement.addEventListener( 'touchstart', touchstart, false );
|
||||
this.domElement.addEventListener( 'touchend', touchend, false );
|
||||
this.domElement.addEventListener( 'touchmove', touchmove, false );
|
||||
|
||||
};
|
||||
|
||||
THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,166 @@
|
|||
/* General styles for all menus */
|
||||
.cbp-spmenu {
|
||||
background: #47a3da;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.cbp-spmenu h3 {
|
||||
color: #afdefa;
|
||||
font-size: 1.9em;
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
font-weight: 300;
|
||||
background: #0d77b6;
|
||||
}
|
||||
|
||||
.cbp-spmenu a {
|
||||
display: block;
|
||||
color: #fff;
|
||||
font-size: 1.1em;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.cbp-spmenu a:hover {
|
||||
background: #258ecd;
|
||||
}
|
||||
|
||||
.cbp-spmenu a:active {
|
||||
background: #afdefa;
|
||||
color: #47a3da;
|
||||
}
|
||||
|
||||
/* Orientation-dependent styles for the content of the menu */
|
||||
|
||||
.cbp-spmenu-vertical {
|
||||
width: 240px;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.cbp-spmenu-vertical a {
|
||||
border-bottom: 1px solid #258ecd;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.cbp-spmenu-horizontal {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cbp-spmenu-horizontal h3 {
|
||||
height: 100%;
|
||||
width: 20%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.cbp-spmenu-horizontal a {
|
||||
float: left;
|
||||
width: 20%;
|
||||
padding: 0.8em;
|
||||
border-left: 1px solid #258ecd;
|
||||
}
|
||||
|
||||
/* Vertical menu that slides from the left or right */
|
||||
|
||||
.cbp-spmenu-left {
|
||||
left: -240px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-right {
|
||||
right: -240px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-left.cbp-spmenu-open {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-right.cbp-spmenu-open {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
/* Horizontal menu that slides from the top or bottom */
|
||||
|
||||
.cbp-spmenu-top {
|
||||
top: -150px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-bottom {
|
||||
bottom: -150px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-top.cbp-spmenu-open {
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-bottom.cbp-spmenu-open {
|
||||
bottom: 0px;
|
||||
}
|
||||
|
||||
/* Push classes applied to the body */
|
||||
|
||||
.cbp-spmenu-push {
|
||||
overflow-x: hidden;
|
||||
position: relative;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.cbp-spmenu-push-toright {
|
||||
left: 240px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-push-toleft {
|
||||
left: -240px;
|
||||
}
|
||||
|
||||
/* Transitions */
|
||||
|
||||
.cbp-spmenu,
|
||||
.cbp-spmenu-push {
|
||||
-webkit-transition: all 0.3s ease;
|
||||
-moz-transition: all 0.3s ease;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Example media queries */
|
||||
|
||||
@media screen and (max-width: 55.1875em){
|
||||
|
||||
.cbp-spmenu-horizontal {
|
||||
font-size: 75%;
|
||||
height: 110px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-top {
|
||||
top: -110px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-bottom {
|
||||
bottom: -110px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media screen and (max-height: 26.375em){
|
||||
|
||||
.cbp-spmenu-vertical {
|
||||
font-size: 90%;
|
||||
width: 190px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-left,
|
||||
.cbp-spmenu-push-toleft {
|
||||
left: -190px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-right {
|
||||
right: -190px;
|
||||
}
|
||||
|
||||
.cbp-spmenu-push-toright {
|
||||
left: 190px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
/* General Demo Style */
|
||||
@import url(http://fonts.googleapis.com/css?family=Lato:300,400,700);
|
||||
|
||||
@font-face {
|
||||
font-family: 'fontawesome';
|
||||
src:url('../fonts/fontawesome.eot');
|
||||
src:url('../fonts/fontawesome.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/fontawesome.svg#fontawesome') format('svg'),
|
||||
url('../fonts/fontawesome.woff') format('woff'),
|
||||
url('../fonts/fontawesome.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
body, html { font-size: 100%; padding: 0; margin: 0;}
|
||||
|
||||
/* Reset */
|
||||
*,
|
||||
*:after,
|
||||
*:before {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Clearfix hack by Nicolas Gallagher: http://nicolasgallagher.com/micro-clearfix-hack/ */
|
||||
.clearfix:before,
|
||||
.clearfix:after {
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.clearfix:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Lato', Calibri, Arial, sans-serif;
|
||||
color: #47a3da;
|
||||
|
||||
}
|
||||
|
||||
a {
|
||||
color: #f0f0f0;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.main,
|
||||
.container > header {
|
||||
width: 90%;
|
||||
max-width: 69em;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.875em 3.125em 1.875em;
|
||||
}
|
||||
|
||||
.container > header {
|
||||
padding: 2.875em 1.875em 1.875em;
|
||||
}
|
||||
|
||||
.container > header h1 {
|
||||
font-size: 2.125em;
|
||||
line-height: 1.3;
|
||||
margin: 0;
|
||||
float: left;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.container > header span {
|
||||
display: block;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5em;
|
||||
padding: 0 0 0.6em 0.1em;
|
||||
}
|
||||
|
||||
.container > header nav {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.container > header nav a {
|
||||
display: block;
|
||||
float: left;
|
||||
position: relative;
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
color: transparent;
|
||||
margin: 0 0.1em;
|
||||
border: 4px solid #47a3da;
|
||||
text-indent: -8000px;
|
||||
}
|
||||
|
||||
.container > header nav a:after {
|
||||
content: attr(data-info);
|
||||
color: #47a3da;
|
||||
position: absolute;
|
||||
width: 600%;
|
||||
top: 120%;
|
||||
text-align: right;
|
||||
right: 0;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.container > header nav a:hover:after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.container > header nav a:hover {
|
||||
background: #47a3da;
|
||||
}
|
||||
|
||||
.main > section {
|
||||
max-width: 260px;
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.main > section h2 {
|
||||
font-weight: 300;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.main > section button {
|
||||
border: none;
|
||||
background: #47a3da;
|
||||
color: #fff;
|
||||
padding: 1.5em;
|
||||
display: block;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
margin: 10px 0;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.main > section button:hover {
|
||||
background: #258ecd;
|
||||
}
|
||||
|
||||
.main > section button.active {
|
||||
background: #0d77b6;
|
||||
}
|
||||
|
||||
.main > section button.disabled {
|
||||
background: #aaa;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.icon-drop:before,
|
||||
.icon-arrow-left:before {
|
||||
font-family: 'fontawesome';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
line-height: 2;
|
||||
text-align: center;
|
||||
color: #47a3da;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-indent: 8000px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.container > header nav a:hover:before {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.icon-drop:before {
|
||||
content: "\e000";
|
||||
}
|
||||
|
||||
.icon-arrow-left:before {
|
||||
content: "\f060";
|
||||
}
|
||||
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -41,6 +41,7 @@ Anthony Verez averez@mozilla.com
|
|||
<ul>
|
||||
<li class="first"><a href="/logincounts/">logincounts</a></li>
|
||||
<li><a href="/attackers">attackers</a></li>
|
||||
<li><a href="/landmass">Landmass</a></li>
|
||||
<li class="last"><a href="/globe">globe</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<!--
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
Copyright (c) 2014 Mozilla Corporation
|
||||
|
||||
Contributors:
|
||||
Anthony Verez averez@mozilla.com
|
||||
Jeff Bryner jeffbryner@gmail.com
|
||||
Sanchit Kapoor sanchitlucknow@gmail.com
|
||||
Avijit Gupta 526avijit@gmail.com
|
||||
Yash Mehrotra yashmehrotra95@gmail.com
|
||||
-->
|
||||
|
||||
<template name="vr">
|
||||
|
||||
<style>
|
||||
body {
|
||||
background: #6495ED;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.blockip {
|
||||
cursor: pointer;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
#date {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
<div id="container"></div>
|
||||
|
||||
<nav class="vr-sidenav cbp-spmenu cbp-spmenu-vertical cbp-spmenu-right text-center" id="attack-sidenav">
|
||||
<h3>Summary</h3>
|
||||
<div id="filter-read-unread" class="filter-radios"> Filter Attacks:
|
||||
<label>
|
||||
<input type="radio" name="filter-type" class="filter-type" value="all" checked/>
|
||||
All
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="filter-type" class="filter-type" value="read"/>
|
||||
Read
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" name="filter-type" class="filter-type" value="unread"/>
|
||||
Unread
|
||||
</label>
|
||||
</div>
|
||||
<a id="attacks-host"><em>{{hostAttacks.host}}</em></a>
|
||||
<a id="attacks-rank">Priority <em># {{displayIndex hostAttacks.rank}}</em></a>
|
||||
|
||||
<span id="specific-attack-details">
|
||||
<i class="glyphicon glyphicon-chevron-left back-button"></i>
|
||||
<h5>{{displayIndex index}}. {{attackDetails.category}}</h5>
|
||||
<h5>Severity: {{attackDetails.severity}}</h5>
|
||||
<h5>IP: {{attackDetails.details.sourceipv4address}}</h5>
|
||||
<h5>Seen: <span id="date">{{displayDate attackDetails.timestamp}}</span></h5>
|
||||
<h5 class="blockip btn" data-ipaddress={{attackDetails.details.sourceipv4address}}>BLOCK IP</h5><br/>
|
||||
{{#if attackDetails.read}}
|
||||
<input type="checkbox" class="cbox" name="attack-isread" checked/> Mark as Read
|
||||
{{else}}
|
||||
<input type="checkbox" class="cbox" name="attack-isread" /> Mark as Read
|
||||
{{/if}}
|
||||
</span>
|
||||
<ul class="text-center" id="attacks-list">
|
||||
{{#each hostAttacks.attacks}}
|
||||
<li class="text-center attacks-list-item" data-index="{{index}}">{{displayIndex index}}. {{category}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
{{>blockIPModal}}
|
||||
</template>
|
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
Copyright (c) 2014 Mozilla Corporation
|
||||
|
||||
Contributors:
|
||||
Jeff Bryner jbryner@mozilla.com
|
||||
Anthony Verez averez@mozilla.com
|
||||
Sanchit Kapoor sanchitlucknow@gmail.com
|
||||
Yash Mehrotra yashmehrotra95@gmail.com
|
||||
Avijit Gupta 526avijit@gmail.com
|
||||
*/
|
||||
|
||||
if (Meteor.isClient) {
|
||||
|
||||
var MESH_PROPERTIES = {
|
||||
count: 4,
|
||||
position: [
|
||||
{x: 0, y: 0, z: 0},
|
||||
{x: -800, y: -20, z: 0},
|
||||
{x: -800, y: -20, z: -800},
|
||||
{x: 0 , y: -20, z: -800}
|
||||
],
|
||||
rotationY: [
|
||||
0,
|
||||
0,
|
||||
Math.PI/2,
|
||||
Math.PI/2
|
||||
]
|
||||
};
|
||||
|
||||
var RANK_COORDINATES = [
|
||||
{x: -286, z: -115},
|
||||
{x: -15, z: 11},
|
||||
{x: -234, z: 232},
|
||||
{x: -69, z: -142},
|
||||
{x: 124, z: 293},
|
||||
{x: 153, z: -869},
|
||||
{x: 124, z: -1122},
|
||||
{x: -261, z: -1031},
|
||||
{x: 87, z: -583},
|
||||
{x: -288, z: -625},
|
||||
{x: 265, z: -501},
|
||||
{x: -850, z: -134},
|
||||
{x: -1094, z: -74},
|
||||
{x: -576, z: -190},
|
||||
{x: -605, z: 98},
|
||||
{x: -964, z: 293},
|
||||
{x: -1084, z: -554},
|
||||
{x: -899, z: -628},
|
||||
{x: -589, z: -716},
|
||||
{x: -992, z: -962},
|
||||
{x: -754, z: -1087}
|
||||
];
|
||||
var ATTACK_ANIMATIONS = {
|
||||
'broxss': Examples.smoke,
|
||||
'brosqli': Examples.smoke,
|
||||
'brotunnel': Examples.smoke,
|
||||
};
|
||||
|
||||
var WIDTH = window.innerWidth;
|
||||
var HEIGHT = window.innerHeight;
|
||||
var SPEED = 0.01;
|
||||
var OPENNAV = 'cbp-spmenu-open';
|
||||
|
||||
var geometry = null;
|
||||
var scene = null;
|
||||
var camera = null;
|
||||
var renderer = null;
|
||||
var material = null;
|
||||
var json = null;
|
||||
var controls = null;
|
||||
var clock = null;
|
||||
var mesh = null;
|
||||
var spotlight = null;
|
||||
var loader = null;
|
||||
var projector = null;
|
||||
var sceneObjects = [];
|
||||
var attackedIds = 0;
|
||||
var cssRenderer = null;
|
||||
var intersectedObject = null;
|
||||
var engine = null;
|
||||
var enginesList = [];
|
||||
var world = {};
|
||||
var jsonData = {};
|
||||
|
||||
function init() {
|
||||
Meteor.call('getVrJson', function(err, response) {
|
||||
jsonData = JSON.parse(response);
|
||||
initMeshes();
|
||||
setCamera();
|
||||
setLights();
|
||||
setRenderers();
|
||||
setStats();
|
||||
|
||||
document.getElementById("container").appendChild(renderer.domElement);
|
||||
document.getElementById("container").appendChild(cssRenderer.domElement);
|
||||
});
|
||||
}
|
||||
|
||||
function initVariables() {
|
||||
clock = new THREE.Clock();
|
||||
scene = new THREE.Scene();
|
||||
loader = new THREE.JSONLoader();
|
||||
camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 10000);
|
||||
sceneControls = new THREE.TrackballControls(camera);
|
||||
spotLight = new THREE.SpotLight(0xffffff, 1);
|
||||
renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
projector = new THREE.Projector();
|
||||
cssRenderer = new THREE.CSS3DRenderer();
|
||||
controls = new THREE.OrbitControls(camera);
|
||||
stats = new Stats();
|
||||
Session.set('filterType', 'all');
|
||||
}
|
||||
|
||||
function restartEngine(parameters, x, z) {
|
||||
parameters.positionBase.x=x;
|
||||
parameters.positionBase.z=z;
|
||||
|
||||
engine = new ParticleEngine();
|
||||
engine.setValues(parameters);
|
||||
engine.initialize(scene);
|
||||
|
||||
enginesList.push(engine);
|
||||
}
|
||||
|
||||
function setStats() {
|
||||
stats.domElement.style.position = 'absolute';
|
||||
stats.domElement.style.bottom = '0px';
|
||||
stats.domElement.style.zIndex = 100;
|
||||
}
|
||||
|
||||
function setCamera() {
|
||||
camera.position.set(-39.52908903855581, -4.352138336979161, 40.70626794923796);
|
||||
var lookAt = { x: -30.52908903855581, y: -4.352138336979161, z: 37.70626794923796 };
|
||||
camera.lookAt(lookAt);
|
||||
}
|
||||
|
||||
function setRenderers() {
|
||||
renderer.setSize(WIDTH, HEIGHT);
|
||||
renderer.shadowMapEnabled = true; // enable shadows
|
||||
|
||||
cssRenderer.setSize(WIDTH, HEIGHT);
|
||||
cssRenderer.domElement.style.position = 'absolute';
|
||||
cssRenderer.domElement.style.top = 0;
|
||||
}
|
||||
|
||||
function setLights() {
|
||||
spotLight.position.set( 100, 10000, 100 );
|
||||
scene.add(spotLight);
|
||||
spotLight.castShadow = true;
|
||||
}
|
||||
|
||||
function initMeshes() {
|
||||
json = loader.parse(jsonData);
|
||||
geometry = json.geometry;
|
||||
material = new THREE.MeshPhongMaterial(json.materials);
|
||||
for (var i = 0; i < MESH_PROPERTIES.count; i++) {
|
||||
mesh = new THREE.Mesh(geometry, material);
|
||||
mesh.scale.x = mesh.scale.y = mesh.scale.z = 50.75;
|
||||
mesh.translation = THREE.GeometryUtils.center(geometry);
|
||||
mesh.castShadow = true;
|
||||
mesh.position.copy(MESH_PROPERTIES.position[i]);
|
||||
mesh.rotation.y = MESH_PROPERTIES.rotationY[i];
|
||||
scene.add(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
controls.update();
|
||||
stats.update();
|
||||
enginesList.forEach(function(engine) {
|
||||
engine.update(0.01*0.5);
|
||||
});
|
||||
}
|
||||
|
||||
function render() {
|
||||
requestAnimationFrame(render);
|
||||
update();
|
||||
renderer.render(scene, camera);
|
||||
cssRenderer.render(scene, camera);
|
||||
}
|
||||
|
||||
function getAttackers() {
|
||||
Meteor.subscribe("attackers-summary-landmass", onReady = function() {
|
||||
|
||||
attackers.find().forEach(function(element) {
|
||||
element.events.forEach(function(evt) {
|
||||
var evtHost = evt.documentsource.details.host;
|
||||
var doc = evt.documentsource;
|
||||
doc.id = evt.documentid;
|
||||
doc.read = evt.read || false;
|
||||
if (evtHost == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Object.keys(world).length >=26) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (world[evtHost]) {
|
||||
world[evtHost].push(doc);
|
||||
} else {
|
||||
world[evtHost] = [doc];
|
||||
world[evtHost].rank = attackedIds++;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var attacks = Object.keys(world).sort(function(prev, current) {
|
||||
return world[current].length - world[prev].length;
|
||||
});
|
||||
|
||||
attacks.forEach(function(host, index) {
|
||||
var attackRank = world[host].rank;
|
||||
// Create enclosing transparent sphere
|
||||
var sphereGeometry = new THREE.SphereGeometry(70);
|
||||
var sphereMaterial = new THREE.MeshBasicMaterial({ transparent: true, opacity: 0 });
|
||||
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
|
||||
sphere.position.x = RANK_COORDINATES[attackRank].x;
|
||||
sphere.position.z = RANK_COORDINATES[attackRank].z;
|
||||
sphere.name = "EnclosingSphere" + attackRank;
|
||||
sphere.rank = attackRank;
|
||||
sphere.host = host;
|
||||
sphere.attacks = [];
|
||||
|
||||
world[host].forEach(function(attack) {
|
||||
if (typeof attack === "object") {
|
||||
attackType = attack.category;
|
||||
sphere.attacks.push(attack);
|
||||
if (Object.keys(ATTACK_ANIMATIONS).indexOf(attackType) > -1) {
|
||||
mappedAttack = ATTACK_ANIMATIONS[attackType];
|
||||
// Display animation
|
||||
restartEngine(mappedAttack, RANK_COORDINATES[index].x, RANK_COORDINATES[index].z);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sceneObjects.push(sphere);
|
||||
scene.add(sphere);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
Template.vr.created = function () {
|
||||
initVariables();
|
||||
};
|
||||
|
||||
Template.vr.rendered = function () {
|
||||
init();
|
||||
render();
|
||||
getAttackers();
|
||||
};
|
||||
|
||||
Template.vr.helpers({
|
||||
hostAttacks: function() {
|
||||
var hostAttacks = Session.get('hostAttacks');
|
||||
var isReadOrUnread = Session.get('filterType');
|
||||
var filteredAttacks = { attacks: [] };
|
||||
if (hostAttacks) {
|
||||
filteredAttacks.rank = hostAttacks.rank;
|
||||
filteredAttacks.host = hostAttacks.host;
|
||||
hostAttacks.attacks.forEach(function(attack, index) {
|
||||
attack.index = index;
|
||||
if (isReadOrUnread === 'read' && attack.read) {
|
||||
filteredAttacks.attacks.push(attack);
|
||||
}
|
||||
else if (isReadOrUnread === 'unread' && !attack.read) {
|
||||
filteredAttacks.attacks.push(attack);
|
||||
}
|
||||
else if (isReadOrUnread === 'all') {
|
||||
filteredAttacks.attacks.push(attack);
|
||||
}
|
||||
});
|
||||
return filteredAttacks;
|
||||
}
|
||||
},
|
||||
attackDetails: function() {
|
||||
return Session.get('attackDetails');
|
||||
},
|
||||
displayIndex: function(index) {
|
||||
return index + 1
|
||||
},
|
||||
displayDate: function(date) {
|
||||
var MM = {Jan:"January", Feb:"February", Mar:"March", Apr:"April",
|
||||
May:"May", Jun:"June", Jul:"July", Aug:"August", Sep:"September",
|
||||
Oct:"October", Nov:"November", Dec:"December"};
|
||||
|
||||
var parsed_date = String(new Date(date)).replace(
|
||||
/\w{3} (\w{3}) (\d{2}) (\d{4}) (\d{2}):(\d{2}):[^(]+\(([A-Z]{3})\)/,
|
||||
function($0,$1,$2,$3,$4,$5,$6){
|
||||
return MM[$1]+" "+$2+", "+$3+" - "+$4%12+":"+$5+(+$4>12?"PM":"AM")+" "+$6
|
||||
}
|
||||
);
|
||||
|
||||
return parsed_date
|
||||
}
|
||||
});
|
||||
|
||||
Template.vr.events({
|
||||
|
||||
"click #container": function(e) {
|
||||
var mouse = {
|
||||
x: (e.clientX / WIDTH)*2 - 1,
|
||||
y: (e.clientY / HEIGHT)*2 - 1
|
||||
};
|
||||
var mouseVector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
|
||||
projector.unprojectVector(mouseVector, camera);
|
||||
var raycaster = new THREE.Raycaster(camera.position, mouseVector.sub( camera.position).normalize() );
|
||||
var intersects = raycaster.intersectObjects(sceneObjects, true);
|
||||
var sideNav = $('#attack-sidenav');
|
||||
|
||||
if (intersects.length) {
|
||||
intersects.forEach(function(intersect) {
|
||||
var attackRank = intersect.object.rank;
|
||||
var attackRegion = intersect.object.host;
|
||||
var attacks = intersect.object.attacks;
|
||||
|
||||
if (typeof attackRank !== "undefined") {
|
||||
var sessionAttackObj = {
|
||||
host: attackRegion,
|
||||
rank: attackRank,
|
||||
attacks: attacks
|
||||
};
|
||||
Session.set('hostAttacks', sessionAttackObj);
|
||||
// Open the nav if not already opened
|
||||
if (!sideNav.hasClass(OPENNAV)) {
|
||||
sideNav.addClass(OPENNAV);
|
||||
}
|
||||
if (Session.get('showDetailedAttack')) {
|
||||
$('#specific-attack-details').slideToggle();
|
||||
$('#attacks-list').slideToggle();
|
||||
Session.set('showDetailedAttack', false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(sideNav.hasClass(OPENNAV)) {
|
||||
sideNav.removeClass(OPENNAV);
|
||||
}
|
||||
},
|
||||
|
||||
"mousemove": function(e) {
|
||||
var mouse = {
|
||||
x: (e.clientX / WIDTH)*2 - 1,
|
||||
y: (e.clientY / HEIGHT)*2 - 1
|
||||
};
|
||||
var mouseVector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
|
||||
projector.unprojectVector(mouseVector, camera);
|
||||
var raycaster = new THREE.Raycaster(camera.position, mouseVector.sub( camera.position).normalize());
|
||||
var intersects = raycaster.intersectObjects(sceneObjects, true);
|
||||
|
||||
$('body').removeClass('mousepointer');
|
||||
|
||||
if (intersects.length) {
|
||||
intersects.forEach(function(intersect) {
|
||||
var attackRank = intersect.object.rank;
|
||||
if (typeof attackRank !== "undefined") {
|
||||
$('body').addClass('mousepointer');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
"change .cbox": function(event) {
|
||||
var isChecked = $('.cbox').is(':checked');
|
||||
var attackId = Session.get('attackDetails').id;
|
||||
var setModifier = { $set: {}};
|
||||
var element = attackers.findOne({"events.documentid": attackId});
|
||||
|
||||
element.events.forEach(function(evt, index) {
|
||||
if (evt.documentid === attackId) {
|
||||
setModifier.$set['events.' + index + '.read'] = isChecked;
|
||||
attackers.update({'_id': element._id}, setModifier);
|
||||
var hostAttacks = Session.get('hostAttacks');
|
||||
hostAttacks.attacks.forEach(function(attack) {
|
||||
if (attack.id === attackId) {
|
||||
attack.read = isChecked;
|
||||
}
|
||||
});
|
||||
Session.set('hostAttacks', hostAttacks);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
"change .filter-type": function (event) {
|
||||
Session.set('filterType', $('.filter-radios input[name=filter-type]:checked').val());
|
||||
// filterAttacksType();
|
||||
},
|
||||
|
||||
"click .attacks-list-item": function(event) {
|
||||
var attackIndex = event.target.getAttribute('data-index');
|
||||
var hostName = document.getElementById('attacks-host').innerText;
|
||||
var attackDetails = world[hostName][attackIndex];
|
||||
Session.set('attackDetails', attackDetails);
|
||||
Session.set('showDetailedAttack', true);
|
||||
slideToggle();
|
||||
},
|
||||
|
||||
"click .back-button": function() {
|
||||
slideToggle();
|
||||
},
|
||||
|
||||
"click .blockip": function(e,t) {
|
||||
Session.set('blockIPipaddress',($(e.target).attr('data-ipaddress')));
|
||||
//disable and hook to re-enable the scene controls so they don't grab the mouse and use it
|
||||
sceneControls.enabled = false;
|
||||
controls.enabled = false;
|
||||
$('#modalBlockIPWindow').on('hidden', function () {
|
||||
sceneControls.enabled=true;
|
||||
controls.enabled = true;
|
||||
});
|
||||
$('#modalBlockIPWindow').modal();
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
Template.vr.destroyed = function () {
|
||||
container.removeChild(renderer.domElement);
|
||||
scene = null;
|
||||
camera = null;
|
||||
renderer = null;
|
||||
WIDTH = window.innerWidth;
|
||||
HEIGHT = window.innerHeight;
|
||||
SPEED = 0.01;
|
||||
};
|
||||
|
||||
function slideToggle() {
|
||||
$('#specific-attack-details').slideToggle();
|
||||
$('#attacks-list').slideToggle();
|
||||
$('#filter-read-unread').slideToggle();
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ Copyright (c) 2014 Mozilla Corporation
|
|||
Contributors:
|
||||
Jeff Bryner jbryner@mozilla.com
|
||||
Anthony Verez averez@mozilla.com
|
||||
|
||||
Yash Mehrotra yashmehrotra95@gmail.com
|
||||
*/
|
||||
|
||||
//collections shared by client/server
|
||||
|
@ -199,6 +199,15 @@ if (Meteor.isServer) {
|
|||
limit:100});
|
||||
});
|
||||
|
||||
Meteor.publish("attackers-summary-landmass", function () {
|
||||
//limit to the last 100 records by default
|
||||
//to ease the sync transfer to dc.js/crossfilter
|
||||
var inModifier = { $in: ["broxss", "brotunnel", "brosqli"]};
|
||||
return attackers.find({"events.documentsource.category": inModifier},
|
||||
{sort: {lastseentimestamp: -1},
|
||||
limit: 100});
|
||||
});
|
||||
|
||||
Meteor.publish("investigations-summary", function () {
|
||||
return investigations.find({},
|
||||
{fields: {
|
||||
|
|
|
@ -186,4 +186,10 @@ Router.map(function () {
|
|||
template:'veristags',
|
||||
layoutTemplate: 'layout'
|
||||
});
|
||||
|
||||
this.route('vr', {
|
||||
path: '/landmass',
|
||||
template: 'vr',
|
||||
layoutTemplate: 'layout'
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ Copyright (c) 2014 Mozilla Corporation
|
|||
|
||||
Contributors:
|
||||
Jeff Bryner jbryner@mozilla.com
|
||||
Avijit Gupta 526avijit@gmail.com
|
||||
*/
|
||||
if (Meteor.isServer) {
|
||||
|
||||
|
@ -20,7 +21,8 @@ if (Meteor.isServer) {
|
|||
'ipintel': ipintel,
|
||||
'verisstats': verisstats,
|
||||
'logincounts': logincounts,
|
||||
'getplugins': getplugins
|
||||
'getplugins': getplugins,
|
||||
'getVrJson': getVrJson
|
||||
});
|
||||
|
||||
function saySomething() {
|
||||
|
@ -146,4 +148,9 @@ if (Meteor.isServer) {
|
|||
}
|
||||
return response
|
||||
}
|
||||
|
||||
function getVrJson() {
|
||||
var response = Assets.getText('vr.config.json');
|
||||
return response;
|
||||
}
|
||||
};
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -6,6 +6,7 @@ Copyright (c) 2014 Mozilla Corporation
|
|||
|
||||
Contributors:
|
||||
Jeff Bryner jbryner@mozilla.com
|
||||
Avijit Gupta 526avijit@gmail.com
|
||||
*/
|
||||
|
||||
/*base css */
|
||||
|
@ -90,6 +91,30 @@ caption, legend {
|
|||
line-height: 13px;
|
||||
}
|
||||
|
||||
|
||||
.attackshoverboard {
|
||||
/*width: 500px;*/
|
||||
/*height: 500px;*/
|
||||
/*background-color: green;*/
|
||||
-moz-transform: scaleY(-1);
|
||||
-webkit-transform: scaleY(-1);
|
||||
-o-transform: scaleY(-1);
|
||||
transform: scaleY(-1);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropdown-submenu{position:relative;}
|
||||
.dropdown-submenu>.dropdown-menu{top:0;left:100%;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;}
|
||||
.dropdown-submenu:active>.dropdown-menu, .dropdown-submenu:hover>.dropdown-menu {
|
||||
display: block;
|
||||
right:162px;
|
||||
}
|
||||
.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;}
|
||||
.dropdown-submenu:active>a:after{border-left-color:#ffffff;}
|
||||
.dropdown-submenu.pull-left{float:none;}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;}
|
||||
|
||||
|
||||
|
||||
.attackercallout {
|
||||
width: 120px;
|
||||
height: 160px;
|
||||
|
@ -140,7 +165,6 @@ caption, legend {
|
|||
background-color: rgba(245,245,245,.7)
|
||||
}
|
||||
|
||||
|
||||
/*bootstrap overrides*/
|
||||
|
||||
.btn {
|
||||
|
@ -175,16 +199,9 @@ input[type="search"] {
|
|||
}
|
||||
|
||||
td{
|
||||
color:white;
|
||||
color:white;
|
||||
}
|
||||
|
||||
.brightURL{
|
||||
color:white;
|
||||
}
|
||||
|
||||
.brightURL:hover{
|
||||
color:white;
|
||||
}
|
||||
|
||||
.welcome {
|
||||
text-align: center;
|
||||
|
@ -195,7 +212,7 @@ td{
|
|||
}
|
||||
|
||||
|
||||
/*login ui css to hide the local account/password signup options */
|
||||
/* uncomment this login ui css to hide the local account/password signup options
|
||||
.logins-wrapper .svgtextlabel {
|
||||
font-size: 20px;
|
||||
color: white;
|
||||
|
@ -213,6 +230,11 @@ td{
|
|||
.or {
|
||||
display: none;
|
||||
}
|
||||
*/
|
||||
/* don't float the 'create account' link*/
|
||||
#login-buttons #signup-link{
|
||||
float: none;
|
||||
}
|
||||
|
||||
/* d3 circle styles */
|
||||
.successcircle{
|
||||
|
@ -515,5 +537,51 @@ circle:hover{
|
|||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.vr-sidenav {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.vr-sidenav .filter-radios label:nth-child(1) {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.vr-sidenav .filter-radios label {
|
||||
display: block;
|
||||
text-align: left;
|
||||
padding-left: 33%;
|
||||
}
|
||||
|
||||
.vr-sidenav #specific-attack-details {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vr-sidenav .back-button {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
top: 5px;
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.vr-sidenav .back-button:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.vr-sidenav #attacks-list {
|
||||
list-style: none;
|
||||
color: white;
|
||||
margin-left: -40px;
|
||||
}
|
||||
|
||||
.vr-sidenav #attacks-list .attacks-list-item {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.vr-sidenav #attacks-list .attacks-list-item:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.mousepointer {
|
||||
cursor: pointer;
|
||||
}
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 80 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 667 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 15 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 380 B |
Загрузка…
Ссылка в новой задаче