forked from p15670423/monkey
Merge branch 'master' of https://github.com/guardicore/monkey
# Conflicts: # chaos_monkey/config.py # chaos_monkey/network/info.py
This commit is contained in:
commit
5eb2379fa2
|
@ -33,7 +33,8 @@ The Monkey itself has been tested on Windows XP, 7, 8.1 and 10. The Linux build
|
|||
|
||||
### Installation
|
||||
|
||||
For off the shelf use, download our pre-compiled binaries from our website, to setup the C&C server follow the instructions in [Monkey Island readme](monkey_island/readme.txt). If you with to compile the binaries yourself, follow the build instructions in the appropiate [readme](build_env/readme.txt).
|
||||
For off the shelf use, download our pre-compiled binaries from our website, to setup the C&C server follow the instructions in [Monkey Island readme](monkey_island/readme.txt). If you with to compile the binaries yourself, follow the build instructions later on in this readme.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
|
@ -148,7 +149,7 @@ Dependency | License |
|
|||
----------------------------|----------------------------
|
||||
libffi-dev | https://github.com/atgreen/libffi/blob/master/LICENSE
|
||||
PyCrypto | Public domain
|
||||
upx | Custom license, http://upx.sourceforge.net/upx-license.html, according to it (IANL) we're fine as long as we're not modifying UPX
|
||||
upx | Custom license, http://upx.sourceforge.net/upx-license.html
|
||||
bson | BSD
|
||||
enum34 | BSD
|
||||
pyasn1 | BSD
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
REM c:\Python27\python -m PyInstaller.main --name monkey -F -y --clean -i monkey.ico main.py
|
||||
c:\python27\Scripts\pyinstaller --upx-dir=.\bin monkey.spec
|
||||
c:\python27\Scripts\pyinstaller --log-level=DEBUG --clean --upx-dir=.\bin monkey.spec
|
||||
|
|
|
@ -112,13 +112,13 @@ class Configuration(object):
|
|||
###########################
|
||||
# monkey config
|
||||
###########################
|
||||
#sets whether or not the monkey is alive. if false will stop scanning and exploiting
|
||||
# sets whether or not the monkey is alive. if false will stop scanning and exploiting
|
||||
alive = True
|
||||
|
||||
#sets whether or not to self delete the monkey executable when stopped
|
||||
# sets whether or not to self delete the monkey executable when stopped
|
||||
self_delete_in_cleanup = False
|
||||
|
||||
#string of the mutex name for single instance
|
||||
# string of the mutex name for single instance
|
||||
singleton_mutex_name = "{2384ec59-0df8-4ab9-918c-843740924a28}"
|
||||
|
||||
# how long to wait between scan iterations
|
||||
|
@ -146,7 +146,7 @@ class Configuration(object):
|
|||
"127.0.0.1:5000"
|
||||
]
|
||||
|
||||
#sets whether or not to retry failed hosts on next scan
|
||||
# sets whether or not to retry failed hosts on next scan
|
||||
retry_failed_explotation = True
|
||||
|
||||
#addresses of internet servers to ping and check if the monkey has internet acccess.
|
||||
|
@ -156,6 +156,9 @@ class Configuration(object):
|
|||
# scanners config
|
||||
###########################
|
||||
|
||||
# Auto detect and scan local subnets
|
||||
local_network_scan = True
|
||||
|
||||
range_class = FixedRange
|
||||
range_size = 1
|
||||
range_fixed = ["", ]
|
||||
|
|
|
@ -53,7 +53,8 @@ class ControlClient(object):
|
|||
data=json.dumps(monkey),
|
||||
headers={'content-type': 'application/json'},
|
||||
verify=False,
|
||||
proxies=ControlClient.proxies)
|
||||
proxies=ControlClient.proxies,
|
||||
timeout=20)
|
||||
break
|
||||
|
||||
except Exception, exc:
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
"singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}",
|
||||
"skip_exploit_if_file_exist": true,
|
||||
"ssh_user": "root",
|
||||
"local_network_scan": true,
|
||||
"tcp_scan_get_banner": true,
|
||||
"tcp_scan_interval": 200,
|
||||
"tcp_scan_timeout": 10000,
|
||||
|
|
|
@ -3,46 +3,74 @@ import sys
|
|||
import socket
|
||||
import struct
|
||||
import array
|
||||
import ipaddress
|
||||
from random import randint
|
||||
|
||||
__author__ = 'hoffer'
|
||||
|
||||
if sys.platform == "win32":
|
||||
import netifaces
|
||||
|
||||
def local_ips():
|
||||
local_hostname = socket.gethostname()
|
||||
return socket.gethostbyname_ex(local_hostname)[2]
|
||||
|
||||
def get_host_subnets(only_ips=False):
|
||||
network_adapters = []
|
||||
valid_ips = local_ips()
|
||||
if only_ips:
|
||||
return valid_ips
|
||||
interfaces = [netifaces.ifaddresses(x) for x in netifaces.interfaces()]
|
||||
for inte in interfaces:
|
||||
if netifaces.AF_INET in inte:
|
||||
for add in inte[netifaces.AF_INET]:
|
||||
if "netmask" in add and add["addr"] in valid_ips:
|
||||
network_adapters.append((add["addr"], add["netmask"]))
|
||||
return network_adapters
|
||||
|
||||
else:
|
||||
import fcntl
|
||||
|
||||
def local_ips():
|
||||
result = []
|
||||
try:
|
||||
is_64bits = sys.maxsize > 2**32
|
||||
struct_size = 40 if is_64bits else 32
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
max_possible = 8 # initial value
|
||||
while True:
|
||||
bytes = max_possible * struct_size
|
||||
names = array.array('B', '\0' * bytes)
|
||||
outbytes = struct.unpack('iL', fcntl.ioctl(
|
||||
s.fileno(),
|
||||
0x8912, # SIOCGIFCONF
|
||||
struct.pack('iL', bytes, names.buffer_info()[0])
|
||||
))[0]
|
||||
if outbytes == bytes:
|
||||
max_possible *= 2
|
||||
else:
|
||||
break
|
||||
namestr = names.tostring()
|
||||
def get_host_subnets(only_ips=False):
|
||||
"""Get the list of Linux network adapters."""
|
||||
import fcntl
|
||||
max_bytes = 8096
|
||||
is_64bits = sys.maxsize > 2 ** 32
|
||||
if is_64bits:
|
||||
offset1 = 16
|
||||
offset2 = 40
|
||||
else:
|
||||
offset1 = 32
|
||||
offset2 = 32
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
names = array.array('B', '\0' * max_bytes)
|
||||
outbytes = struct.unpack('iL', fcntl.ioctl(
|
||||
sock.fileno(),
|
||||
0x8912,
|
||||
struct.pack('iL', max_bytes, names.buffer_info()[0])))[0]
|
||||
adapter_names = [names.tostring()[n_cnt:n_cnt + offset1].split('\0', 1)[0]
|
||||
for n_cnt in xrange(0, outbytes, offset2)]
|
||||
network_adapters = []
|
||||
for adapter_name in adapter_names:
|
||||
ip_address = socket.inet_ntoa(fcntl.ioctl(
|
||||
sock.fileno(),
|
||||
0x8915,
|
||||
struct.pack('256s', adapter_name))[20:24])
|
||||
if ip_address.startswith('127'):
|
||||
continue
|
||||
subnet_mask = socket.inet_ntoa(fcntl.ioctl(
|
||||
sock.fileno(),
|
||||
0x891b,
|
||||
struct.pack('256s', adapter_name))[20:24])
|
||||
|
||||
for i in range(0, outbytes, struct_size):
|
||||
addr = socket.inet_ntoa(namestr[i+20:i+24])
|
||||
if not addr.startswith('127'):
|
||||
result.append(addr)
|
||||
# name of interface is (namestr[i:i+16].split('\0', 1)[0]
|
||||
finally:
|
||||
return result
|
||||
if only_ips:
|
||||
network_adapters.append(ip_address)
|
||||
else:
|
||||
network_adapters.append((ip_address, subnet_mask))
|
||||
|
||||
return network_adapters
|
||||
|
||||
|
||||
def local_ips():
|
||||
return get_host_subnets(only_ips=True)
|
||||
|
||||
|
||||
def get_free_tcp_port(min_range=1000, max_range=65535):
|
||||
|
@ -59,9 +87,25 @@ def get_free_tcp_port(min_range=1000, max_range=65535):
|
|||
|
||||
return None
|
||||
|
||||
|
||||
def check_internet_access(services):
|
||||
ping_str = "-n 1" if sys.platform.startswith("win") else "-c 1"
|
||||
for host in services:
|
||||
if os.system("ping " + ping_str + " " + host) == 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_ips_from_interfaces():
|
||||
res = []
|
||||
ifs = get_host_subnets()
|
||||
for interface in ifs:
|
||||
ipint = ipaddress.ip_interface(u"%s/%s" % interface)
|
||||
# limit subnet scans to class C only
|
||||
if ipint.network.num_addresses > 255:
|
||||
ipint = ipaddress.ip_interface(u"%s/24" % interface[0])
|
||||
for addr in ipint.network.hosts():
|
||||
if str(addr) == interface[0]:
|
||||
continue
|
||||
res.append(str(addr))
|
||||
return res
|
||||
|
|
|
@ -2,7 +2,7 @@ import time
|
|||
import logging
|
||||
from . import HostScanner
|
||||
from config import WormConfiguration
|
||||
from info import local_ips
|
||||
from info import local_ips, get_ips_from_interfaces
|
||||
from range import *
|
||||
|
||||
__author__ = 'itamar'
|
||||
|
@ -27,10 +27,12 @@ class NetworkScanner(object):
|
|||
LOG.info("Found local IP addresses of the machine: %r", self._ip_addresses)
|
||||
# for fixed range, only scan once.
|
||||
if WormConfiguration.range_class is FixedRange:
|
||||
self._ranges = [WormConfiguration.range_class('0.0.0.0')]
|
||||
self._ranges = [WormConfiguration.range_class(None)]
|
||||
else:
|
||||
self._ranges = [WormConfiguration.range_class(ip_address)
|
||||
for ip_address in self._ip_addresses]
|
||||
if WormConfiguration.local_network_scan:
|
||||
self._ranges += [FixedRange([ip_address for ip_address in get_ips_from_interfaces()])]
|
||||
LOG.info("Base local networks to scan are: %r", self._ranges)
|
||||
|
||||
def get_victim_machines(self, scan_type, max_find=5, stop_callback=None):
|
||||
|
|
|
@ -58,10 +58,16 @@ class RelativeRange(NetworkRange):
|
|||
|
||||
|
||||
class FixedRange(NetworkRange):
|
||||
def __init__(self, base_address, shuffle=True):
|
||||
def __init__(self, fixed_addresses=None, shuffle=True):
|
||||
base_address = 0
|
||||
super(FixedRange, self).__init__(base_address, shuffle=shuffle)
|
||||
self._fixed_addresses = self._config.range_fixed
|
||||
if not fixed_addresses:
|
||||
self._fixed_addresses = self._config.range_fixed
|
||||
else:
|
||||
if type(fixed_addresses) is str:
|
||||
self._fixed_addresses = [fixed_addresses]
|
||||
else:
|
||||
self._fixed_addresses = list(fixed_addresses)
|
||||
|
||||
def __repr__(self):
|
||||
return "<FixedRange %s>" % (",".join(self._fixed_addresses))
|
||||
|
|
|
@ -21,7 +21,8 @@ Windows:
|
|||
python -m pip install requests
|
||||
python -m pip install odict
|
||||
python -m pip install paramiko
|
||||
python -m pip install psutil
|
||||
python -m pip install psutil
|
||||
python -m pip install netifaces
|
||||
python -m pip install PyInstaller
|
||||
type > C:\Python27\Lib\site-packages\zope\__init__.py
|
||||
7. Download and extract UPX binary to [source-path]\monkey\chaos_monkey\bin\upx.exe:
|
||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 6.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
|
@ -10,6 +10,7 @@
|
|||
<script type="text/javascript" src="./js/typeahead.bundle.min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="./js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="./js/bootstrap-switch.min.js"></script>
|
||||
<script type="text/javascript" src="./js/sb-admin-2/sb-admin-2.js"></script>
|
||||
<script type="text/javascript" src="./js/sb-admin-2/metisMenu.js"></script>
|
||||
<script type="text/javascript" src="./js/jsoneditor.js"></script>
|
||||
|
@ -23,6 +24,7 @@
|
|||
<link type="text/css" href="./css/typeahead.css" rel="stylesheet"/>
|
||||
<!-- <link type="text/css" href="./css/font-awesome.min.css" rel="stylesheet"/> -->
|
||||
<link type="text/css" href="./css/bootstrap.min.css" rel="stylesheet"/>
|
||||
<link type="text/css" href="./css/bootstrap-switch.min.css" rel="stylesheet"/>
|
||||
<link type="text/css" href="./css/sb-admin-2/sb-admin-2.css" rel="stylesheet"/>
|
||||
<link type="text/css" href="./css/sb-admin-2/metisMenu.css" rel="stylesheet"/>
|
||||
<link type="text/css" href="./css/jquery.dataTables.min.css" rel="stylesheet"/>
|
||||
|
@ -71,11 +73,33 @@
|
|||
</div>
|
||||
<!-- /.Network section -->
|
||||
|
||||
<!-- Info section -->
|
||||
<div class="col-lg-3 col-md-6 col-sm-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<a href="#info" data-toggle="collapse">General Info</a>
|
||||
</div>
|
||||
<div id="info" class="panel-body panel-collapse collapse in">
|
||||
<div>
|
||||
Num of Monkeys: <label id="infoNumOfMonkeys">0</label> (<label id="infoNumOfParents">0</label> by exploiting)<br/>
|
||||
Num of Hosts Detected: <label id="infoNumOfHosts">0</label><br/>
|
||||
Num of Tunnels Used: <label id="infoNumOfTunnels">0</label><br/>
|
||||
</div>
|
||||
<div>
|
||||
Display Scanned Hosts: <input type="checkbox" data-size="mini" name="chboxShowScanned" checked>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- /.Info section -->
|
||||
|
||||
<!-- Details section -->
|
||||
<div class="col-lg-3 col-md-6 col-sm-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<a href="#details" data-toggle="collapse">Details</a>
|
||||
<a href="#details" data-toggle="collapse">Monkey Details</a>
|
||||
</div>
|
||||
<div id="details" class="panel-body panel-collapse collapse in">
|
||||
<div id="search" class="input-group custom-search-form">
|
||||
|
@ -99,24 +123,21 @@
|
|||
<a href="#mconfig" data-toggle="collapse">Monkey Config</a>
|
||||
</div>
|
||||
<div id="mconfig" style="overflow: visible" class="panel-body panel-collapse collapse in" aria-expanded="true">
|
||||
<span class="input-group-btn">
|
||||
<button id="btnConfigLoad" style="display: none;" class="btn btn-default" type="button"
|
||||
onclick="loadMonkeyConfig()" style="margin-top:-4px">
|
||||
Refresh
|
||||
</button>
|
||||
<button id="btnConfigUpdate" style="display: none;" class="btn btn-default" type="button"
|
||||
onclick="updateMonkeyConfig()" style="margin-top:-4px">
|
||||
Update
|
||||
</button>
|
||||
<button id="btnKillMonkey" style="display: none;" class="btn btn-default" type="button"
|
||||
onclick="killMonkey()" style="margin-top:-4px">
|
||||
Mark for Kill
|
||||
</button>
|
||||
<button id="btnReviveMonkey" style="display: none;" class="btn btn-default" type="button"
|
||||
onclick="reviveMonkey()" style="margin-top:-4px">
|
||||
Revive Monkey
|
||||
</button>
|
||||
</span>
|
||||
<div style="display: none;" id="monkey-enabled">
|
||||
Allow running: <input type="checkbox" data-size="mini" name="chboxMonkeyEnabled" checked>
|
||||
</div><br/>
|
||||
<div>
|
||||
<span class="input-group-btn">
|
||||
<button id="btnConfigLoad" style="display: none;" class="btn btn-default" type="button"
|
||||
onclick="loadMonkeyConfig()" style="margin-top:-4px">
|
||||
Refresh
|
||||
</button>
|
||||
<button id="btnConfigUpdate" style="display: none;" class="btn btn-default" type="button"
|
||||
onclick="updateMonkeyConfig()" style="margin-top:-4px">
|
||||
Update
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div style="display: none;" id="monkey-config">
|
||||
</div>
|
||||
</div>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -21,15 +21,27 @@ $.getJSON(jsonFile, function(json) {
|
|||
var network = null;
|
||||
var nodes = [];
|
||||
var edges = [];
|
||||
var numOfParentLinks = 0;
|
||||
var numOfTunnelLinks = 0;
|
||||
var numOfScanLinks = 0;
|
||||
|
||||
var showScannedHosts = true;
|
||||
|
||||
// Images/icons constants
|
||||
const ICONS_DIR = "./css/img/objects/";
|
||||
const ICONS_EXT = ".png";
|
||||
|
||||
const HOST_TYPE_MONKEY = "monkey";
|
||||
const HOST_TYPE_SCAN = "scanned";
|
||||
|
||||
const EDGE_TYPE_PARENT = "parent";
|
||||
const EDGE_TYPE_TUNNEL = "tunnel";
|
||||
const EDGE_TYPE_SCAN = "scan";
|
||||
|
||||
const EDGE_COLOR_PARENT = "red";
|
||||
const EDGE_COLOR_TUNNEL = "blue";
|
||||
const EDGE_COLOR_SCAN = "gray";
|
||||
|
||||
// General options
|
||||
// If variable from local storage != null, assign it, otherwise set it's default value.
|
||||
|
||||
|
@ -59,6 +71,8 @@ function initAdmin() {
|
|||
edges: edges
|
||||
};
|
||||
|
||||
updateCounters();
|
||||
|
||||
var options = {
|
||||
};
|
||||
|
||||
|
@ -67,6 +81,9 @@ function initAdmin() {
|
|||
|
||||
network = new vis.Network(container, data, options);
|
||||
|
||||
$("[name='chboxShowScanned']").bootstrapSwitch('onSwitchChange', toggleScannedHosts);
|
||||
$("[name='chboxMonkeyEnabled']").bootstrapSwitch('onSwitchChange', toggleMonkeyEnabled);
|
||||
|
||||
prepareSearchEngine();
|
||||
|
||||
monkeyCfg = new JSONEditor(document.getElementById('monkey-config'),{
|
||||
|
@ -115,6 +132,55 @@ function initAdmin() {
|
|||
addEventsListeners();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateMonkeys() {
|
||||
$.getJSON(jsonFile + '?timestamp='+ generationDate, function(json) {
|
||||
generationDate = json.timestamp;
|
||||
|
@ -128,6 +194,7 @@ function updateMonkeys() {
|
|||
{
|
||||
monkeys.push(new_monkeys[i]);
|
||||
nodes.push(createMonkeyNode(new_monkeys[i]));
|
||||
updateCounters();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,16 +202,7 @@ function updateMonkeys() {
|
|||
{
|
||||
createEdges();
|
||||
createTunnels();
|
||||
|
||||
// keep old selection
|
||||
var selNode = network.getSelectedNodes();
|
||||
network.setData({nodes: nodes, edges: edges});
|
||||
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);
|
||||
}
|
||||
}
|
||||
refreshDrawing();
|
||||
}
|
||||
createScanned();
|
||||
window.setTimeout(updateMonkeys, 10000);
|
||||
|
@ -163,7 +221,6 @@ function createNodes() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
|
||||
function createMonkeyNode(monkey) {
|
||||
var title = undefined;
|
||||
var img = "monkey";
|
||||
|
@ -187,12 +244,24 @@ function createMonkeyNode(monkey) {
|
|||
'image': img,
|
||||
'title': title,
|
||||
'value': undefined,
|
||||
'type' : HOST_TYPE_MONKEY,
|
||||
'mass': 1,
|
||||
};
|
||||
}
|
||||
|
||||
function createMachineNode(machine) {
|
||||
img = ICONS_DIR + "computer" + ICONS_EXT;
|
||||
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;
|
||||
|
||||
return {
|
||||
'id': machine.ip_addr,
|
||||
|
@ -202,6 +271,7 @@ function createMachineNode(machine) {
|
|||
'image': img,
|
||||
'title': undefined,
|
||||
'value': undefined,
|
||||
'type' : HOST_TYPE_SCAN,
|
||||
'mass': 1,
|
||||
};
|
||||
}
|
||||
|
@ -213,7 +283,8 @@ function createEdges() {
|
|||
var parent = getMonkeyByGuid(monkey.parent);
|
||||
|
||||
if(parent && !edgeExists([parent.id, monkey.id, EDGE_TYPE_PARENT])) {
|
||||
edges.push({from: parent.id, to: monkey.id, arrows:'middle', type: EDGE_TYPE_PARENT, color: 'red'});
|
||||
edges.push({from: parent.id, to: monkey.id, arrows:'middle', type: EDGE_TYPE_PARENT, color: EDGE_COLOR_PARENT});
|
||||
numOfParentLinks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +299,8 @@ function createTunnels() {
|
|||
var tunnel = getMonkeyByGuid(monkey.tunnel_guid);
|
||||
|
||||
if(tunnel && !edgeExists([monkey.id, tunnel.id, EDGE_TYPE_TUNNEL])) {
|
||||
edges.push({from: monkey.id, to: tunnel.id, arrows:'middle', type: EDGE_TYPE_TUNNEL, color:'blue'});
|
||||
edges.push({from: monkey.id, to: tunnel.id, arrows:'middle', type: EDGE_TYPE_TUNNEL, color: EDGE_COLOR_TUNNEL});
|
||||
numOfTunnelLinks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -237,13 +309,14 @@ function createTunnels() {
|
|||
}
|
||||
|
||||
function createScanned() {
|
||||
//For each existing monkey, gets all the scans performed by it
|
||||
//For each non exploited machine, adds a new node and connects it as a scanned node.
|
||||
var genTime = temelGenerationDate; // save the initial value as it's going to be changed in each json call
|
||||
// For each existing monkey, gets all the scans performed by it
|
||||
// For each non exploited machine, adds a new node and connects it as a scanned node.
|
||||
for (var i = 0; i < monkeys.length; i++) {
|
||||
var monkey = monkeys[i];
|
||||
//Get scans for each monkey
|
||||
// Get scans for each monkey
|
||||
// Reading the JSON file containing the monkeys' informations
|
||||
$.getJSON(jsonFileTelemetry +'?timestamp='+ temelGenerationDate+ "&monkey_guid=" + monkey.guid+"&telem_type=scan", function(json) {
|
||||
$.getJSON(jsonFileTelemetry +'?timestamp='+ genTime + "&monkey_guid=" + monkey.guid+"&telem_type=scan", function(json) {
|
||||
temelGenerationDate = json.timestamp;
|
||||
var scans = json.objects;
|
||||
for (var i = 0; i < scans.length; i++) {
|
||||
|
@ -265,9 +338,14 @@ function createScanned() {
|
|||
}
|
||||
|
||||
if(!edgeExists([monkey.id, machineNode.id, EDGE_TYPE_SCAN])) {
|
||||
edges.push({from: monkey.id, to: machineNode.id, arrows:'middle', type: EDGE_TYPE_SCAN, color: 'red'});
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -297,6 +375,13 @@ function buildMonkeyDescription(monkey) {
|
|||
return html;
|
||||
}
|
||||
|
||||
function updateCounters() {
|
||||
$('#infoNumOfMonkeys').html(monkeys.length);
|
||||
$('#infoNumOfHosts').html(scannedMachines.length);
|
||||
$('#infoNumOfParents').html(numOfParentLinks);
|
||||
$('#infoNumOfTunnels').html(numOfTunnelLinks);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Preparing the autocompletion search engine for the monkeys
|
||||
|
@ -370,7 +455,8 @@ function onSelect(properties) {
|
|||
var content = "<b>No selection</b>"
|
||||
$("#selectionInfo").html(content);
|
||||
$('#monkey-config').hide()
|
||||
$('#btnConfigLoad, #btnConfigUpdate, #btnKillMonkey, #btnReviveMonkey').hide();
|
||||
$('#btnConfigLoad, #btnConfigUpdate').hide();
|
||||
$('#monkey-enabled').hide();
|
||||
telemTable.clear();
|
||||
telemTable.draw();
|
||||
}
|
||||
|
@ -403,14 +489,12 @@ function onNodeSelect(nodeId) {
|
|||
loadMonkeyConfig();
|
||||
|
||||
if (monkey.config.alive) {
|
||||
$('#btnKillMonkey').show();
|
||||
$('#btnReviveMonkey').hide();
|
||||
$("[name='chboxMonkeyEnabled']").bootstrapSwitch('state', true);
|
||||
}
|
||||
else {
|
||||
$('#btnKillMonkey').hide();
|
||||
$('#btnReviveMonkey').show();
|
||||
$("[name='chboxMonkeyEnabled']").bootstrapSwitch('state', false);
|
||||
}
|
||||
|
||||
$('#monkey-enabled').show();
|
||||
|
||||
$.getJSON('/api/telemetry/' + monkey.guid, function(json) {
|
||||
telemTable.clear();
|
||||
|
@ -434,6 +518,19 @@ function onEdgeSelect(edge) {
|
|||
|
||||
}
|
||||
|
||||
function toggleMonkeyEnabled(event, state) {
|
||||
if (event.type != "switchChange") {
|
||||
return;
|
||||
}
|
||||
if (state) {
|
||||
reviveMonkey();
|
||||
}
|
||||
else {
|
||||
killMonkey();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function killMonkey() {
|
||||
var curr_config = monkeyCfg.getValue();
|
||||
curr_config.alive = false;
|
||||
|
|
|
@ -11,27 +11,19 @@ How to set C&C server:
|
|||
python -m pip install Flask-Pymongo
|
||||
python -m pip install Flask-Restful
|
||||
python -m pip install python-dateutil
|
||||
mkdir C:\MonkeyIsland\bin
|
||||
mkdir C:\MonkeyIsland\db
|
||||
mkdir C:\MonkeyIsland\cc\binaries
|
||||
4. Put monkey binaries in C:\MonkeyIsland\cc\binaries:
|
||||
mkdir MonkeyIsland\bin
|
||||
mkdir MonkeyIsland\db
|
||||
mkdir MonkeyIsland\cc\binaries
|
||||
4. Put monkey binaries in MonkeyIsland\cc\binaries:
|
||||
monkey-linux-64 - monkey binary for linux 64bit
|
||||
monkey-linux-32 - monkey binary for linux 32bit
|
||||
monkey-windows-32.exe - monkey binary for windows 32bit
|
||||
monkey-windows-64.exe - monkey binary for windows 64bit
|
||||
4. Download MongoDB & Extract to C:\MonkeyIsland\bin\mongodb
|
||||
4. Download MongoDB & Extract to MonkeyIsland\bin\mongodb
|
||||
http://downloads.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-latest.zip
|
||||
5. Install OpenSSL
|
||||
https://slproweb.com/download/Win64OpenSSL_Light-1_0_2d.exe
|
||||
6. Generate SSL Certificate, Run create_certificate.bat
|
||||
|
||||
How to Connect to build environment:
|
||||
1. set hostname to MONKEYCC
|
||||
2. Put monkey source code at C:\Code\monkey
|
||||
3. Run:
|
||||
net share binaries=C:\MonkeyIsland\cc\binaries
|
||||
net share sources=C:\Code\monkey\chaos_monkey
|
||||
4. Run batch/sh script according to build environment readme
|
||||
6. Generate SSL Certificate, run create_certificate.bat when your current working directory is MonkeyIsland
|
||||
|
||||
How to run:
|
||||
1. start run_mongodb.bat
|
||||
|
|
Loading…
Reference in New Issue