2015-09-29 22:01:09 +08:00
const jsonFile = "/api/monkey" ;
2016-06-14 19:40:14 +08:00
const jsonFileTelemetry = "/api/telemetry" ;
2015-09-29 22:01:09 +08:00
var monkeys = null ;
2016-06-14 19:40:14 +08:00
var scannedMachines = [ ] ;
2015-09-29 22:01:09 +08:00
var generationDate = null ;
2016-06-14 19:40:14 +08:00
var temelGenerationDate = null ;
2015-09-29 22:01:09 +08:00
// The JSON must be fully loaded before onload() happens for calling draw() on 'monkeys'
$ . ajaxSetup ( {
async : false
} ) ;
// Reading the JSON file containing the monkeys' informations
$ . getJSON ( jsonFile , function ( json ) {
monkeys = json . objects ;
generationDate = json . timestamp ;
} ) ;
2016-06-14 19:40:14 +08:00
2015-09-29 22:01:09 +08:00
// The objects used by vis
var network = null ;
var nodes = [ ] ;
var edges = [ ] ;
2016-07-18 22:09:48 +08:00
var numOfParentLinks = 0 ;
var numOfTunnelLinks = 0 ;
var numOfScanLinks = 0 ;
var showScannedHosts = true ;
2015-09-29 22:01:09 +08:00
// Images/icons constants
const ICONS _DIR = "./css/img/objects/" ;
const ICONS _EXT = ".png" ;
2016-07-18 22:09:48 +08:00
const HOST _TYPE _MONKEY = "monkey" ;
const HOST _TYPE _SCAN = "scanned" ;
2016-05-27 13:47:22 +08:00
const EDGE _TYPE _PARENT = "parent" ;
const EDGE _TYPE _TUNNEL = "tunnel" ;
2016-06-14 19:40:14 +08:00
const EDGE _TYPE _SCAN = "scan" ;
2016-05-27 13:47:22 +08:00
2016-07-16 17:21:26 +08:00
const EDGE _COLOR _PARENT = "red" ;
const EDGE _COLOR _TUNNEL = "blue" ;
const EDGE _COLOR _SCAN = "gray" ;
2016-08-14 00:37:49 +08:00
const NODE _MANUAL _RUN _COLOR = "red" ;
const NODE _ALIVE _STROKECOLOR = "#aeeaae" ;
2015-09-29 22:01:09 +08:00
// General options
// If variable from local storage != null, assign it, otherwise set it's default value.
var focusedOnNode = false ;
var monkeyCfg = undefined ;
2015-10-14 22:20:01 +08:00
var newCfg = undefined ;
2015-09-29 22:01:09 +08:00
var telemTable = undefined ;
JSONEditor . defaults . theme = 'bootstrap3' ;
function initAdmin ( ) {
if ( monkeys == null ) {
errorMessage = "<font color='red'>Could not find '" + jsonFile + "'.</font>" ;
$ ( "#networkmap" ) . html ( errorMessage ) ;
}
nodes = [ ] ;
edges = [ ] ;
2016-07-24 06:04:42 +08:00
createNodes ( ) ;
2016-05-27 06:06:56 +08:00
createEdges ( ) ;
createTunnels ( ) ;
2016-06-14 19:40:14 +08:00
createScanned ( ) ;
2015-09-29 22:01:09 +08:00
var data = {
2016-07-24 06:04:42 +08:00
nodes : nodes ,
2016-05-27 06:06:56 +08:00
edges : edges
2015-09-29 22:01:09 +08:00
} ;
2016-07-18 22:09:48 +08:00
updateCounters ( ) ;
2016-07-18 00:12:30 +08:00
2015-09-29 22:01:09 +08:00
var options = {
2016-07-21 16:21:40 +08:00
layout : {
improvedLayout : false
2016-07-24 21:27:56 +08:00
}
2015-09-29 22:01:09 +08:00
} ;
// Using jQuery to get the element does not work with vis.js library
var container = document . getElementById ( "monkeysmap" ) ;
network = new vis . Network ( container , data , options ) ;
2016-07-18 22:09:48 +08:00
$ ( "[name='chboxShowScanned']" ) . bootstrapSwitch ( 'onSwitchChange' , toggleScannedHosts ) ;
$ ( "[name='chboxMonkeyEnabled']" ) . bootstrapSwitch ( 'onSwitchChange' , toggleMonkeyEnabled ) ;
2015-09-29 22:01:09 +08:00
prepareSearchEngine ( ) ;
monkeyCfg = new JSONEditor ( document . getElementById ( 'monkey-config' ) , {
schema : {
type : "object" ,
title : "Monkey" ,
properties : {
alive : {
title : "Alive" ,
type : "boolean" ,
} ,
} ,
options : {
"collapsed" : true
} ,
} ,
disable _edit _json : false ,
} ) ;
2015-10-14 22:20:01 +08:00
newCfg = new JSONEditor ( document . getElementById ( 'new-config' ) , {
2015-09-29 22:01:09 +08:00
schema : {
type : "object" ,
title : "New Monkeys" ,
properties : {
alive : {
title : "Alive" ,
type : "boolean" ,
} ,
} ,
options : {
"collapsed" : true
} ,
} ,
disable _edit _json : false ,
} ) ;
2015-10-14 22:20:01 +08:00
newCfg . setValue ( { alive : true } ) ;
2015-09-29 22:01:09 +08:00
telemTable = $ ( "#telemetris-table" ) . DataTable ( {
"ordering" : false ,
} ) ;
2016-07-04 15:44:57 +08:00
loadNewMonkeysConfig ( ) ;
2016-07-21 16:21:40 +08:00
setInterval ( updateMonkeys , 10000 ) ;
2015-09-29 22:01:09 +08:00
addEventsListeners ( ) ;
}
2016-07-18 22:09:48 +08:00
function toggleScannedHosts ( event , state ) {
if ( event . type != "switchChange" ) {
return ;
}
if ( state ) {
showScannedHosts = true ;
}
else {
showScannedHosts = false ;
}
refreshDrawing ( ) ;
}
function refreshDrawing ( ) {
// function called before first init
if ( network == null ) {
return ;
}
// keep old selection
var selNode = network . getSelectedNodes ( ) ;
if ( showScannedHosts ) {
network . setData ( { nodes : nodes , edges : edges } ) ;
}
else {
var selectiveNodes = [ ] ;
var selectiveEdges = [ ] ;
for ( var i = 0 ; i < nodes . length ; i ++ ) {
if ( nodes [ i ] . type != HOST _TYPE _SCAN ) {
selectiveNodes . push ( nodes [ i ] )
}
}
for ( var i = 0 ; i < edges . length ; i ++ ) {
if ( edges [ i ] . type != EDGE _TYPE _SCAN ) {
selectiveEdges . push ( edges [ i ] )
}
}
network . setData ( { nodes : selectiveNodes , edges : selectiveEdges } ) ;
}
if ( selNode . length ) {
var monkey = getMonkey ( selNode [ 0 ] ) ;
if ( monkey ) { // The selection might be no longer valid if the monkey was deleted
selectNode ( monkey . hostname , false ) ;
}
}
}
2015-09-29 22:01:09 +08:00
function updateMonkeys ( ) {
$ . getJSON ( jsonFile + '?timestamp=' + generationDate , function ( json ) {
generationDate = json . timestamp ;
var new _monkeys = json . objects ;
for ( var i = 0 ; i < new _monkeys . length ; i ++ ) {
index = getMonkeyIndex ( new _monkeys [ i ] . guid ) ;
if ( index != - 1 ) {
monkeys [ index ] = new _monkeys [ i ] ;
2016-08-14 00:37:49 +08:00
monNode = getNode ( monkeys [ index ] . id ) ;
if ( ! monkeys [ index ] . dead ) {
monNode . font . strokeWidth = 1 ;
monNode . font . strokeColor = NODE _ALIVE _STROKECOLOR ;
}
else {
monNode . font . strokeWidth = 0 ;
}
2015-09-29 22:01:09 +08:00
}
else
{
monkeys . push ( new _monkeys [ i ] ) ;
2016-07-24 06:04:42 +08:00
var exiting _scan = undefined ;
for ( var j = 0 ; j < new _monkeys [ i ] . ip _addresses . length ; j ++ ) {
exiting _scan = getScannedByIP ( new _monkeys [ i ] . ip _addresses [ j ] ) ;
if ( exiting _scan != undefined ) {
break ;
}
}
if ( exiting _scan == undefined ) {
nodes . push ( createMonkeyNode ( new _monkeys [ i ] ) ) ;
}
else {
convertScanNodeToMonkey ( exiting _scan , new _monkeys [ i ] ) ;
}
2015-09-29 22:01:09 +08:00
}
}
if ( new _monkeys . length > 0 )
{
2016-05-27 06:06:56 +08:00
createEdges ( ) ;
createTunnels ( ) ;
2016-07-18 22:09:48 +08:00
refreshDrawing ( ) ;
2015-09-29 22:01:09 +08:00
}
2016-06-14 19:40:14 +08:00
createScanned ( ) ;
2016-07-24 21:27:56 +08:00
updateCounters ( ) ;
2015-09-29 22:01:09 +08:00
} ) ;
}
/ * *
* Create the nodes used by vis . js
* /
function createNodes ( ) {
for ( var i = 0 ; i < monkeys . length ; i ++ ) {
var monkey = monkeys [ i ] ;
2016-06-14 19:40:14 +08:00
nodes . push ( createMonkeyNode ( monkey ) ) ;
2015-09-29 22:01:09 +08:00
}
return nodes ;
}
2016-06-14 19:40:14 +08:00
function createMonkeyNode ( monkey ) {
2015-09-29 22:01:09 +08:00
var title = undefined ;
2016-08-14 00:37:49 +08:00
var font = { } ;
2015-09-29 22:01:09 +08:00
var img = "monkey" ;
if ( monkey . description ) {
if ( monkey . description . indexOf ( "Linux" ) != - 1 ) {
img = img + "-linux"
}
else if ( monkey . description . indexOf ( "Windows" ) != - 1 ) {
img = img + "-windows"
}
}
img = ICONS _DIR + img + ICONS _EXT ;
2016-07-24 06:04:42 +08:00
if ( monkey . parent == null ) {
2016-08-14 00:37:49 +08:00
font [ 'color' ] = NODE _MANUAL _RUN _COLOR ;
2016-07-21 16:21:40 +08:00
}
2016-07-24 06:04:42 +08:00
else {
for ( var i = 0 ; i < monkey . parent . length ; i ++ ) {
if ( monkey . parent [ i ] [ 1 ] == null ) {
2016-08-14 00:37:49 +08:00
font [ 'color' ] = NODE _MANUAL _RUN _COLOR ;
2016-07-24 06:04:42 +08:00
}
}
}
2016-08-14 00:37:49 +08:00
if ( ! monkey . dead ) {
font [ 'strokeColor' ] = NODE _ALIVE _STROKECOLOR ;
font [ 'strokeWidth' ] = 1 ;
}
2016-07-21 16:21:40 +08:00
2015-09-29 22:01:09 +08:00
return {
'id' : monkey . id ,
'label' : monkey . hostname + "\n" + monkey . ip _addresses [ 0 ] ,
2016-07-21 16:21:40 +08:00
'font' : font ,
2015-09-29 22:01:09 +08:00
'shape' : 'image' ,
'color' : undefined ,
'image' : img ,
'title' : title ,
'value' : undefined ,
2016-07-18 22:09:48 +08:00
'type' : HOST _TYPE _MONKEY ,
2016-07-06 16:44:33 +08:00
'mass' : 1 ,
2015-09-29 22:01:09 +08:00
} ;
}
2016-06-14 19:40:14 +08:00
function createMachineNode ( machine ) {
2016-07-18 00:12:30 +08:00
img = "computer" ;
if ( undefined != machine . os . type ) {
if ( machine . os . type == "linux" ) {
img += "-linux" ;
}
else if ( machine . os . type == "windows" ) {
img += "-windows" ;
}
}
img = ICONS _DIR + img + ICONS _EXT ;
2016-06-14 19:40:14 +08:00
return {
'id' : machine . ip _addr ,
'label' : machine . os . version + "\n" + machine . ip _addr ,
'shape' : 'image' ,
'color' : undefined ,
'image' : img ,
'title' : undefined ,
'value' : undefined ,
2016-07-18 22:09:48 +08:00
'type' : HOST _TYPE _SCAN ,
2016-07-06 16:44:33 +08:00
'mass' : 1 ,
2016-06-14 19:40:14 +08:00
} ;
}
2016-07-24 06:04:42 +08:00
function convertScanNodeToMonkey ( scanned , monkey ) {
var monNode = createMonkeyNode ( monkey ) ;
nodes . push ( monNode ) ;
// move edges to new node
for ( var i = 0 ; i < edges . length ; i ++ ) {
if ( edges [ i ] . to == scanned . id ) {
edges [ i ] . to = monNode . id ;
}
if ( edges [ i ] . from == scanned . id ) {
edges [ i ] . from = monNode . id ;
}
}
for ( var i = 0 ; i < scannedMachines . length ; i ++ ) {
if ( scannedMachines [ i ] . id == scanned . id ) {
scannedMachines . splice ( i , 1 ) ;
break ;
}
}
for ( var i = 0 ; i < nodes . length ; i ++ ) {
if ( nodes [ i ] . id == scanned . id ) {
nodes . splice ( i , 1 ) ;
break ;
}
}
}
2015-09-29 22:01:09 +08:00
function createEdges ( ) {
for ( var i = 0 ; i < monkeys . length ; i ++ ) {
var monkey = monkeys [ i ] ;
2016-07-24 06:04:42 +08:00
if ( monkey . parent == null ) { continue ; } ;
for ( var j = 0 ; j < monkey . parent . length ; j ++ ) {
if ( monkey . parent [ j ] [ 0 ] != monkey . guid ) {
var parent = getMonkeyByGuid ( monkey . parent [ j ] [ 0 ] ) ;
var exploit = monkey . parent [ j ] [ 1 ] ;
if ( parent && ! edgeExists ( [ parent . id , monkey . id , EDGE _TYPE _PARENT ] ) ) {
var title = "<center><b>" + exploit + "</b></center>From: " + parent . hostname + "<br/>To: " + monkey . hostname ;
edges . push ( { from : parent . id , to : monkey . id , arrows : 'middle' , type : EDGE _TYPE _PARENT , title : title , /*label: exploit, font: {color: 'red', size: 10, align: 'top'},*/ color : EDGE _COLOR _PARENT } ) ;
if ( removeEdge ( [ parent . id , monkey . id , EDGE _TYPE _SCAN ] ) ) {
numOfScanLinks -- ;
}
numOfParentLinks ++ ;
}
2015-09-29 22:01:09 +08:00
}
}
}
return edges ;
}
2016-05-27 06:06:56 +08:00
function createTunnels ( ) {
for ( var i = 0 ; i < monkeys . length ; i ++ ) {
var monkey = monkeys [ i ] ;
if ( monkey . tunnel _guid ) {
2016-05-27 13:47:22 +08:00
var tunnel = getMonkeyByGuid ( monkey . tunnel _guid ) ;
2016-05-27 06:06:56 +08:00
2016-05-27 13:47:22 +08:00
if ( tunnel && ! edgeExists ( [ monkey . id , tunnel . id , EDGE _TYPE _TUNNEL ] ) ) {
2016-07-16 17:21:26 +08:00
edges . push ( { from : monkey . id , to : tunnel . id , arrows : 'middle' , type : EDGE _TYPE _TUNNEL , color : EDGE _COLOR _TUNNEL } ) ;
2016-07-18 22:09:48 +08:00
numOfTunnelLinks ++ ;
2016-05-27 06:06:56 +08:00
}
}
}
return edges ;
}
2015-09-29 22:01:09 +08:00
2016-06-14 19:40:14 +08:00
function createScanned ( ) {
2016-07-20 05:53:41 +08:00
// Gets all the scans performed by monkeys
2016-07-16 17:21:26 +08:00
// For each non exploited machine, adds a new node and connects it as a scanned node.
2016-07-20 05:53:41 +08:00
// Reading the JSON file containing the monkeys' informations
$ . getJSON ( jsonFileTelemetry + '?timestamp=' + temelGenerationDate + "&telem_type=scan" , function ( json ) {
temelGenerationDate = json . timestamp ;
var scans = json . objects ;
for ( var i = 0 ; i < scans . length ; i ++ ) {
var scan = scans [ i ] ;
var monkey = getMonkeyByGuid ( scan . monkey _guid ) ;
2016-07-24 06:04:42 +08:00
// And check if we've already added this scanned machine
var machineNode = getMonkeyByIP ( scan . data . machine . ip _addr ) ;
2016-07-20 05:53:41 +08:00
if ( null == machineNode ) {
2016-07-24 06:04:42 +08:00
machineNode = getScannedByIP ( scan . data . machine . ip _addr ) ;
if ( null == machineNode ) {
machineNode = createMachineNode ( scan . data . machine ) ;
scannedMachines . push ( machineNode ) ;
nodes . push ( machineNode ) ;
}
2016-07-18 22:09:48 +08:00
}
2016-07-20 05:53:41 +08:00
2016-07-24 06:04:42 +08:00
if ( ! edgeExists ( [ monkey . id , machineNode . id , EDGE _TYPE _SCAN ] ) && ! edgeExists ( [ monkey . id , machineNode . id , EDGE _TYPE _PARENT ] ) ) {
2016-07-20 05:53:41 +08:00
edges . push ( { from : monkey . id , to : machineNode . id , arrows : 'middle' , type : EDGE _TYPE _SCAN , color : EDGE _COLOR _SCAN } ) ;
numOfScanLinks ++ ;
}
}
if ( scans . length > 0 ) {
refreshDrawing ( ) ;
updateCounters ( ) ;
}
} ) ;
2016-06-14 19:40:14 +08:00
}
2015-09-29 22:01:09 +08:00
/ * *
* Builds node description
* /
function buildMonkeyDescription ( monkey ) {
var html =
"<label>Name:</label> " + monkey . hostname + "</br>" +
"<label>Description:</label> " + monkey . description + "</br>" +
2016-07-04 15:44:57 +08:00
"<label>Internet Access:</label> " + monkey . internet _access + "</br>" ;
if ( monkey . dead ) {
html += "<label>State:</label> Dead </br>" ;
}
if ( ! monkey . config . alive ) {
html += "<label>Note:</label> Marked to be dead</br>" ;
}
html +=
"<label>Last Seen:</label> " + monkey . keepalive + "</br>" +
2016-07-24 06:04:42 +08:00
"<label>IP Address:</label><br/>" ;
2015-09-29 22:01:09 +08:00
2016-07-24 06:04:42 +08:00
html += "<ul>" ;
2015-09-29 22:01:09 +08:00
for ( var i = 0 ; i < monkey . ip _addresses . length ; i ++ ) {
2016-07-24 06:04:42 +08:00
html += "<li>" + monkey . ip _addresses [ i ] ;
}
html += "</ul>" ;
if ( monkey . parent != null ) {
html += "<label>Exploited by:</label><br/>"
html += "<ul>" ;
for ( var i = 0 ; i < monkey . parent . length ; i ++ ) {
html += "<li>" ;
if ( monkey . parent [ i ] [ 0 ] == monkey . guid ) {
html += "Manual Run<br/>" ;
}
else {
parent = getMonkeyByGuid ( monkey . parent [ i ] [ 0 ] ) ;
if ( ! parent ) { html += "Unknown Source" ; continue ; }
html += parent . hostname + " (" ;
if ( monkey . parent [ i ] [ 1 ] == null ) { html += "Unknown" }
else { html += monkey . parent [ i ] [ 1 ] ; }
html += ")" ;
}
}
html += "</ul>" ;
2015-09-29 22:01:09 +08:00
}
return html ;
}
2016-07-18 22:09:48 +08:00
function updateCounters ( ) {
$ ( '#infoNumOfMonkeys' ) . html ( monkeys . length ) ;
$ ( '#infoNumOfHosts' ) . html ( scannedMachines . length ) ;
$ ( '#infoNumOfParents' ) . html ( numOfParentLinks ) ;
$ ( '#infoNumOfTunnels' ) . html ( numOfTunnelLinks ) ;
2016-07-24 06:04:42 +08:00
var numOfAlive = monkeys . length ;
for ( var i = 0 ; i < monkeys . length ; i ++ ) {
if ( monkeys [ i ] . dead ) { numOfAlive -- ; }
}
$ ( '#infoNumOfAlive' ) . html ( numOfAlive ) ;
2016-07-18 22:09:48 +08:00
}
2015-09-29 22:01:09 +08:00
/ * *
* Preparing the autocompletion search engine for the monkeys
* TODO Upgrade the search with regex
* /
function prepareSearchEngine ( ) {
var engine = new Bloodhound ( {
datumTokenizer : Bloodhound . tokenizers . obj . whitespace ( "hostname" ) ,
queryTokenizer : Bloodhound . tokenizers . whitespace ,
local : this . monkeys
} ) ;
engine . initialize ( ) ;
$ ( "#monkeySearch" ) . typeahead ( {
hint : true ,
highlight : true ,
minLength : 1
} ,
{
displayKey : "hostname" ,
source : engine . ttAdapter ( )
} ) ;
$ ( "#monkeySearch" ) . keypress ( function ( event ) {
const ENTER _KEY _CODE = 13 ;
if ( event . which == ENTER _KEY _CODE ) {
selectNode ( undefined , zoom = true ) ;
}
} ) ;
}
/ * *
* Manage the key presses events
* /
function onKeyPress ( event ) {
var charCode = ( "charCode" in event ) ? event . charCode : event . keyCode ;
console . log ( "Unicode '" + charCode + "' was pressed." ) ;
}
/ * *
* Adding the events listeners
* /
function addEventsListeners ( ) {
network . on ( "doubleClick" , onDoubleClick ) ;
network . on ( "select" , onSelect ) ;
}
/ * *
* Manage the event when an object is double - clicked
* /
function onDoubleClick ( properties ) {
for ( var i = 0 ; i < properties . nodes . length ; i ++ ) {
network . focus ( properties . nodes [ i ] , { scale : 1 } ) ;
}
onSelect ( properties ) ;
}
/ * *
* Manage the event when an object is selected
* /
function onSelect ( properties ) {
2016-07-24 06:04:42 +08:00
if ( ( properties . nodes . length > 0 ) && getMonkey ( properties . nodes [ 0 ] ) ) {
2015-09-29 22:01:09 +08:00
onNodeSelect ( properties . nodes ) ;
}
else
{
2016-07-24 06:04:42 +08:00
var content = "<b>Monkey not selected</b>"
2015-09-29 22:01:09 +08:00
$ ( "#selectionInfo" ) . html ( content ) ;
$ ( '#monkey-config' ) . hide ( )
2016-07-18 22:09:48 +08:00
$ ( '#btnConfigLoad, #btnConfigUpdate' ) . hide ( ) ;
$ ( '#monkey-enabled' ) . hide ( ) ;
2015-09-29 22:01:09 +08:00
telemTable . clear ( ) ;
telemTable . draw ( ) ;
2016-07-24 06:04:42 +08:00
if ( properties . edges . length > 0 ) {
onEdgeSelect ( properties . edges ) ;
}
2015-09-29 22:01:09 +08:00
}
}
/ * *
* Manage the event when a node is selected
* /
function onNodeSelect ( nodeId ) {
var monkey = getMonkey ( nodeId ) ;
var htmlContent = "" ;
if ( monkey ) {
htmlContent = buildMonkeyDescription ( monkey ) ;
$ ( "#monkeySearch" ) . val ( monkey . hostname ) ;
2016-07-24 06:04:42 +08:00
$ ( "#selectionInfo" ) . html ( htmlContent ) ;
$ ( '#monkey-config' ) . show ( )
$ ( '#btnConfigLoad, #btnConfigUpdate' ) . show ( ) ;
2015-09-29 22:01:09 +08:00
2016-07-24 06:04:42 +08:00
loadMonkeyConfig ( ) ;
2015-09-29 22:01:09 +08:00
2016-07-24 06:04:42 +08:00
if ( monkey . config . alive ) {
$ ( "[name='chboxMonkeyEnabled']" ) . bootstrapSwitch ( 'state' , true , true ) ;
}
else {
$ ( "[name='chboxMonkeyEnabled']" ) . bootstrapSwitch ( 'state' , false , true ) ;
}
$ ( '#monkey-enabled' ) . show ( ) ;
2015-09-29 22:01:09 +08:00
2016-07-24 06:04:42 +08:00
$ . getJSON ( '/api/telemetry?monkey_guid=' + monkey . guid , function ( json ) {
telemTable . clear ( ) ;
var telemetries = json . objects ;
2015-09-29 22:01:09 +08:00
2016-07-24 06:04:42 +08:00
for ( var i = 0 ; i < telemetries . length ; i ++ ) {
telemTable . row . add ( [ telemetries [ i ] . timestamp , telemetries [ i ] . telem _type , JSON . stringify ( telemetries [ i ] . data ) ] ) ;
}
2015-09-29 22:01:09 +08:00
2016-07-24 06:04:42 +08:00
telemTable . draw ( ) ;
} ) ;
}
2015-09-29 22:01:09 +08:00
network . selectNodes ( [ nodeId ] ) ;
}
/ * *
* Manage the event when an edge is selected
* /
function onEdgeSelect ( edge ) {
var edge = getEdge ( edge ) ;
2016-07-24 06:04:42 +08:00
var monkey = getMonkey ( edge . from ) ;
if ( ! monkey ) { return ; } ;
var target = undefined ;
if ( edge . type == 'scan' ) {
target = getScannedByIP ( edge . to )
}
else {
target = getMonkey ( edge . to )
}
2015-09-29 22:01:09 +08:00
2016-07-24 06:04:42 +08:00
$ . getJSON ( jsonFileTelemetry + '?monkey_guid=' + monkey . guid , function ( json ) {
telemTable . clear ( ) ;
var telemetries = json . objects ;
for ( var i = 0 ; i < telemetries . length ; i ++ ) {
var telem = telemetries [ i ]
if ( telem . telem _type == 'scan' || telem . telem _type == 'exploit' ) {
if ( ( ( edge . type == 'scan' ) && ( telem . data . machine . ip _addr == target . id ) ) ||
( ( edge . type == 'parent' ) && ( 0 <= $ . inArray ( telem . data . machine . ip _addr , target . ip _addresses ) ) ) ) {
telemTable . row . add ( [ telemetries [ i ] . timestamp , telemetries [ i ] . telem _type , JSON . stringify ( telemetries [ i ] . data ) ] ) ;
}
}
}
telemTable . draw ( ) ;
} ) ;
2015-09-29 22:01:09 +08:00
}
2016-07-18 22:09:48 +08:00
function toggleMonkeyEnabled ( event , state ) {
if ( event . type != "switchChange" ) {
return ;
}
if ( state ) {
reviveMonkey ( ) ;
}
else {
killMonkey ( ) ;
}
}
2016-07-04 15:44:57 +08:00
function killMonkey ( ) {
var curr _config = monkeyCfg . getValue ( ) ;
curr _config . alive = false ;
monkeyCfg . setValue ( curr _config ) ;
}
function reviveMonkey ( ) {
var curr _config = monkeyCfg . getValue ( ) ;
curr _config . alive = true ;
monkeyCfg . setValue ( curr _config ) ;
}
2015-09-29 22:01:09 +08:00
function toggleFocusOnNode ( ) {
if ( focusedOnNode ) {
network . zoomExtent ( { duration : 0 } ) ;
focusedOnNode = false ;
}
else {
2016-07-04 15:44:57 +08:00
selectNode ( undefined , true ) ;
2015-09-29 22:01:09 +08:00
}
}
2015-10-14 22:20:01 +08:00
function loadNewMonkeysConfig ( ) {
$ . getJSON ( '/api/config/new' , function ( json ) {
2015-09-29 22:01:09 +08:00
if ( jQuery . isEmptyObject ( json ) )
{
2015-10-14 22:20:01 +08:00
newCfg . setValue ( { alive : true } ) ;
2015-09-29 22:01:09 +08:00
}
else
{
if ( undefined == json . alive )
{
json . alive = true ;
}
delete json . id ;
2015-10-14 22:20:01 +08:00
newCfg . setValue ( json ) ;
2015-09-29 22:01:09 +08:00
}
2016-09-22 02:37:51 +08:00
newCfg . watch ( 'root' , updateNewMonkeysConfig ) ;
2015-09-29 22:01:09 +08:00
} ) ;
}
2015-10-14 22:20:01 +08:00
function updateNewMonkeysConfig ( ) {
var curr _config = newCfg . getValue ( )
2015-09-29 22:01:09 +08:00
$ . ajax ( {
headers : {
'Accept' : 'application/json' ,
'Content-Type' : 'application/json'
} ,
2015-10-14 22:20:01 +08:00
url : '/api/config/new' ,
2015-09-29 22:01:09 +08:00
type : 'POST' ,
data : JSON . stringify ( curr _config ) ,
success : function ( response , textStatus , jqXhr ) {
2015-10-14 22:20:01 +08:00
console . log ( "New monkeys config successfully updated!" ) ;
2016-07-21 16:21:40 +08:00
BootstrapDialog . show ( {
title : "Update New Monkeys Config" ,
message : "New monkeys config successfully updated!"
} ) ;
2015-09-29 22:01:09 +08:00
} ,
error : function ( jqXHR , textStatus , errorThrown ) {
// log the error to the console
console . log ( "The following error occured: " + textStatus , errorThrown ) ;
2016-07-21 16:21:40 +08:00
BootstrapDialog . show ( {
title : "Update New Monkeys Config" ,
message : "The following error occured: " + textStatus
} ) ;
2015-09-29 22:01:09 +08:00
} ,
complete : function ( ) {
2015-10-14 22:20:01 +08:00
console . log ( "Sending new monkeys config update..." ) ;
2015-09-29 22:01:09 +08:00
}
} ) ;
}
function loadMonkeyConfig ( ) {
2016-07-04 15:44:57 +08:00
var node = network . getSelectedNodes ( ) ;
2015-09-29 22:01:09 +08:00
2016-07-04 15:44:57 +08:00
if ( node . length != 1 ) {
2015-09-29 22:01:09 +08:00
return ;
}
2016-07-04 15:44:57 +08:00
var monkey = getMonkey ( node [ 0 ] ) ;
2015-09-29 22:01:09 +08:00
2016-09-22 02:37:51 +08:00
monkeyCfg . unwatch ( 'root' , updateMonkeyConfig ) ;
2015-09-29 22:01:09 +08:00
monkeyCfg . setValue ( monkey . config ) ;
2016-09-22 02:37:51 +08:00
monkeyCfg . watch ( 'root' , updateMonkeyConfig ) ;
2015-09-29 22:01:09 +08:00
}
function updateMonkeyConfig ( ) {
2016-07-04 15:44:57 +08:00
var node = network . getSelectedNodes ( ) ;
if ( node . length != 1 ) {
2015-09-29 22:01:09 +08:00
return ;
}
2016-07-04 15:44:57 +08:00
var monkey = getMonkey ( node [ 0 ] ) ;
2015-09-29 22:01:09 +08:00
2016-07-04 15:44:57 +08:00
var curr _config = monkeyCfg . getValue ( ) ;
2015-09-29 22:01:09 +08:00
$ . ajax ( {
headers : {
'Accept' : 'application/json' ,
'Content-Type' : 'application/json'
} ,
url : '/api/monkey/' + monkey . guid ,
type : 'PATCH' ,
data : JSON . stringify ( { config : curr _config } ) ,
success : function ( response , textStatus , jqXhr ) {
monkey . config = curr _config ;
2016-07-04 15:44:57 +08:00
console . log ( "Monkey config successfully updated! (" + monkey . hostname + ")" ) ;
selectNode ( monkey . hostname , false ) ;
2016-07-21 16:21:40 +08:00
BootstrapDialog . show ( {
title : "Update Monkey Config" ,
message : "Monkey config successfully updated! (" + monkey . hostname + ")"
} ) ;
2015-09-29 22:01:09 +08:00
} ,
error : function ( jqXHR , textStatus , errorThrown ) {
// log the error to the console
console . log ( "The following error occured: " + textStatus , errorThrown ) ;
2016-07-21 16:21:40 +08:00
BootstrapDialog . show ( {
title : "Update Monkey Config" ,
message : "The following error occured: " + textStatus
} ) ;
2015-09-29 22:01:09 +08:00
} ,
complete : function ( ) {
console . log ( "Sending monkey config update..." ) ;
}
} ) ;
}
function selectNode ( hostname , zoom ) {
if ( hostname == undefined ) {
hostname = $ ( "#monkeySearch" ) . val ( ) ;
}
if ( hostname == "" ) {
return ;
}
for ( var i = 0 ; i < monkeys . length ; i ++ ) {
var monkey = monkeys [ i ] ;
if ( monkey . hostname == hostname ) {
onNodeSelect ( [ monkey . id ] ) ;
if ( zoom ) {
network . focus ( monkey . id , { scale : 1 } ) ;
focusedOnNode = true ;
}
break ;
}
}
}
2016-08-02 04:54:41 +08:00
function showRunMonkeyDialog ( addresses ) {
var selHtml = '<select class="form-control" id="islandInt">' ;
for ( var i = 0 ; i < addresses . length ; i ++ ) {
selHtml += '<option>' + addresses [ i ] + '</option>' ;
}
selHtml += '</select>'
BootstrapDialog . show ( {
title : 'Run Monkey' ,
message : 'This action will run infection monkey on the Island server.<br>Please choose the IP address to be used as the server for the monkeys:' + selHtml ,
type : BootstrapDialog . TYPE _GENERAL ,
buttons : [ {
label : 'Run Monkey' ,
cssClass : 'btn-success' ,
action : function ( dialogItself ) {
dialogItself . close ( ) ;
$ . ajax ( {
headers : {
'Accept' : 'application/json' ,
'Content-Type' : 'application/json'
} ,
url : '/api/island' ,
type : 'POST' ,
data : JSON . stringify ( { "action" : "monkey" , "island_address" : $ ( "#islandInt option:selected" ) . text ( ) } ) ,
success : function ( response , textStatus , jqXhr ) {
if ( response . res [ 0 ] != true ) {
BootstrapDialog . show ( {
title : "Run Monkey" ,
type : BootstrapDialog . TYPE _WARNING ,
message : "The following error occured: " + response . res [ 1 ]
} ) ;
}
else {
BootstrapDialog . show ( {
title : "Run Monkey" ,
type : BootstrapDialog . TYPE _SUCCESS ,
message : "Monkey Started!"
} ) ;
}
} ,
error : function ( jqXHR , textStatus , errorThrown ) {
console . log ( "The following error occured: " + textStatus , errorThrown ) ;
BootstrapDialog . show ( {
title : "Run Monkey" ,
type : BootstrapDialog . TYPE _WARNING ,
message : "The following error occured: " + textStatus
} ) ;
} ,
} ) ;
}
} , {
label : 'Cancel' ,
cssClass : 'btn-general' ,
action : function ( dialogItself ) {
dialogItself . close ( ) ;
}
} ]
} ) ;
}
function runMonkey ( ) {
$ . getJSON ( "/api/island?type=interfaces" , function ( json ) {
showRunMonkeyDialog ( json [ "interfaces" ] ) ;
} ) ;
}
2015-09-29 22:01:09 +08:00
2016-07-27 03:32:46 +08:00
function killAll ( ) {
BootstrapDialog . show ( {
title : 'Kill All Monkeys' ,
message : 'This action will mark all existing monkeys to die.<br/>As some of the monkyes might be in the middle of exploitation, new monkeys might still apear, and you will need to perform this kill again.<br/>Perform kill all?' ,
type : BootstrapDialog . TYPE _DANGER ,
buttons : [ {
label : 'Kill All' ,
cssClass : 'btn-danger' ,
action : function ( dialogItself ) {
dialogItself . close ( ) ;
$ . ajax ( {
headers : {
'Accept' : 'application/json' ,
} ,
url : '/api?action=killall' ,
type : 'GET' ,
success : function ( response , textStatus , jqXhr ) {
console . log ( response ) ;
if ( response . status != 'OK' ) {
BootstrapDialog . show ( {
title : 'Kill All Monkeys' ,
message : "The following error occured: " + response . reason
} ) ;
}
else {
console . log ( "All monkeys marked to die" ) ;
BootstrapDialog . show ( {
title : 'Kill All Monkeys' ,
2016-08-02 04:54:41 +08:00
type : BootstrapDialog . TYPE _WARNING ,
2016-07-27 03:32:46 +08:00
message : "All existing monkeys marked to die"
} ) ;
}
} ,
error : function ( jqXHR , textStatus , errorThrown ) {
console . log ( "The following error occured: " + textStatus , errorThrown ) ;
BootstrapDialog . show ( {
title : 'Kill All Monkeys' ,
2016-08-02 04:54:41 +08:00
type : BootstrapDialog . TYPE _WARNING ,
2016-07-27 03:32:46 +08:00
message : "The following error occured: " + textStatus
} ) ;
}
} ) ;
}
} , {
label : 'Cancel' ,
2016-08-02 04:54:41 +08:00
cssClass : 'btn-general' ,
2016-07-27 03:32:46 +08:00
action : function ( dialogItself ) {
dialogItself . close ( ) ;
}
} ]
} ) ;
}
2016-07-20 05:53:41 +08:00
function resetDB ( ) {
if ( confirm ( 'Are you sure you want to empty the database?' ) ) {
$ . ajax ( {
headers : {
'Accept' : 'application/json' ,
} ,
url : '/api?action=reset' ,
type : 'GET' ,
success : function ( response , textStatus , jqXhr ) {
2016-07-24 21:27:56 +08:00
console . log ( response ) ;
if ( response . status != 'OK' ) {
BootstrapDialog . show ( {
title : "Reset DB" ,
message : "The following error occured: " + response . reason
} ) ;
}
else {
console . log ( "DB was successfully reset!" ) ;
location . reload ( ) ;
}
2016-07-20 05:53:41 +08:00
} ,
error : function ( jqXHR , textStatus , errorThrown ) {
// log the error to the console
console . log ( "The following error occured: " + textStatus , errorThrown ) ;
2016-07-21 16:21:40 +08:00
BootstrapDialog . show ( {
title : "Reset DB" ,
message : "The following error occured: " + textStatus
} ) ;
2016-07-20 05:53:41 +08:00
} ,
complete : function ( ) {
console . log ( "Trying to reset DB..." ) ;
}
} ) ;
}
}
2015-09-29 22:01:09 +08:00
/ * *
* Get a monkey from its id
* /
function getMonkey ( id ) {
for ( var i = 0 ; i < monkeys . length ; i ++ ) {
if ( monkeys [ i ] . id == id ) {
return monkeys [ i ] ;
}
}
}
function getMonkeyByGuid ( guid ) {
for ( var i = 0 ; i < monkeys . length ; i ++ ) {
if ( monkeys [ i ] . guid == guid ) {
return monkeys [ i ] ;
}
2016-07-24 06:04:42 +08:00
}
return null ;
2015-09-29 22:01:09 +08:00
}
2016-06-14 19:40:14 +08:00
function getMonkeyByIP ( ip ) {
2016-07-24 06:04:42 +08:00
for ( var i = 0 ; i < monkeys . length ; i ++ ) {
2016-06-14 19:40:14 +08:00
var monkey = monkeys [ i ] ;
2016-07-24 06:04:42 +08:00
for ( var j = 0 ; j < monkey . ip _addresses . length ; j ++ ) {
if ( monkey . ip _addresses [ j ] == ip ) {
return monkey ;
2016-06-14 19:40:14 +08:00
}
}
}
return null ;
}
2016-07-24 06:04:42 +08:00
function getScannedByIP ( ip ) {
for ( var i = 0 ; i < scannedMachines . length ; i ++ ) {
2016-06-14 19:40:14 +08:00
var machine = scannedMachines [ i ] ;
if ( machine . id == ip ) {
return machine
}
}
return null ;
}
2015-09-29 22:01:09 +08:00
function getMonkeyIndex ( guid ) {
for ( var i = 0 ; i < monkeys . length ; i ++ ) {
if ( monkeys [ i ] . guid == guid ) {
return i ;
}
}
return - 1 ;
}
/ * *
* Get a node from its id
* /
function getNode ( id ) {
for ( var i = 0 ; i < nodes . length ; i ++ ) {
if ( nodes [ i ] . id == id ) {
return nodes [ i ] ;
}
}
}
/ * *
* Get an edge from its id
* /
function getEdge ( id ) {
for ( var i = 0 ; i < edges . length ; i ++ ) {
if ( edges [ i ] . id == id ) {
return edges [ i ] ;
}
}
}
/ * *
* Verifies whether a node already exist or not
* /
function nodeExists ( id ) {
return getNode ( id ) != null ;
}
/ * *
* Verifies whether a link already exist or not
* /
function edgeExists ( link ) {
for ( var i = 0 ; i < edges . length ; i ++ ) {
var from = edges [ i ] . from ;
var to = edges [ i ] . to ;
2016-05-27 13:47:22 +08:00
var type = edges [ i ] . type ;
if ( from == link [ 0 ] && to == link [ 1 ] && type == link [ 2 ] ) {
2016-07-24 06:04:42 +08:00
return edges [ i ] ;
2015-09-29 22:01:09 +08:00
}
}
}
2016-07-24 06:04:42 +08:00
function removeEdge ( link ) {
for ( var i = 0 ; i < edges . length ; i ++ ) {
var from = edges [ i ] . from ;
var to = edges [ i ] . to ;
var type = edges [ i ] . type ;
if ( from == link [ 0 ] && to == link [ 1 ] && type == link [ 2 ] ) {
edges . splice ( i , 1 ) ;
return true ;
}
}
return false ;
}
2015-09-29 22:01:09 +08:00
/ * *
* Clears the value in the local storage
* /
function clear ( key ) {
if ( localStorage [ key ] ) {
delete localStorage [ key ] ;
}
} ;
/** /.localStorage Section **/
/** **/
/** ----- **/
/** **/
/** Utilities Section **/
/ * *
* Returns the differences between two arrays
* /
Array . prototype . diff = function ( other ) {
var diff = [ ] ;
for ( var i = 0 ; i < this . length ; i ++ ) {
var obj = this [ i ] ;
if ( other . indexOf ( obj ) == - 1 ) {
diff . push ( obj ) ;
}
}
for ( var i = 0 ; i < other . length ; i ++ ) {
var obj = other [ i ] ;
if ( this . indexOf ( obj ) == - 1 && diff . indexOf ( obj ) == - 1 ) {
diff . push ( obj ) ;
}
}
return diff ;
} ;
/** /.Utilities Section **/
/** **/