diff --git a/chaos_monkey/exploit/smbexec.py b/chaos_monkey/exploit/smbexec.py index 17c2bb979..3acc928d2 100644 --- a/chaos_monkey/exploit/smbexec.py +++ b/chaos_monkey/exploit/smbexec.py @@ -37,6 +37,7 @@ class SmbExploiter(HostExploiter): def __init__(self): self._config = __import__('config').WormConfiguration + self._guid = __import__('config').GUID def is_os_supported(self, host): if host.os.get('type') in self._target_os_type: @@ -103,6 +104,8 @@ class SmbExploiter(HostExploiter): else: cmdline = MONKEY_CMDLINE_DETACHED % {'monkey_path': remote_full_path} + cmdline += " -p " + self._guid + if host.default_tunnel: cmdline += " -t " + host.default_tunnel if host.default_server: diff --git a/chaos_monkey/exploit/sshexec.py b/chaos_monkey/exploit/sshexec.py index 65e228e82..d6fcf52b5 100644 --- a/chaos_monkey/exploit/sshexec.py +++ b/chaos_monkey/exploit/sshexec.py @@ -19,6 +19,7 @@ class SSHExploiter(HostExploiter): def __init__(self): self._config = __import__('config').WormConfiguration + self._guid = __import__('config').GUID self._update_timestamp = 0 def log_transfer(self, transferred, total): @@ -117,6 +118,7 @@ class SSHExploiter(HostExploiter): try: cmdline = "%s %s" % (self._config.dropper_target_path_linux, MONKEY_ARG) + cmdline += " -p " + self._guid if host.default_tunnel: cmdline += " -t " + host.default_tunnel if host.default_server: diff --git a/chaos_monkey/exploit/tools.py b/chaos_monkey/exploit/tools.py index c39251f0f..d9f365aa9 100644 --- a/chaos_monkey/exploit/tools.py +++ b/chaos_monkey/exploit/tools.py @@ -393,7 +393,7 @@ def get_target_monkey(host): if host.os.get('type') == platform.system().lower(): # if exe not found, and we have the same arch or arch is unknown and we are 32bit, use our exe if (not host.os.get('machine') and sys.maxsize < 2**32) or \ - host.os.get('machine','').lower() == platform.machine().lower(): + host.os.get('machine','').lower() == platform.machine().lower(): monkey_path = sys.executable return monkey_path \ No newline at end of file diff --git a/chaos_monkey/exploit/win_ms08_067.py b/chaos_monkey/exploit/win_ms08_067.py index d42618967..0c038a535 100644 --- a/chaos_monkey/exploit/win_ms08_067.py +++ b/chaos_monkey/exploit/win_ms08_067.py @@ -171,6 +171,7 @@ class Ms08_067_Exploiter(HostExploiter): def __init__(self): self._config = __import__('config').WormConfiguration + self._guid = __import__('config').GUID def is_os_supported(self, host): if host.os.get('type') in self._target_os_type and \ @@ -249,6 +250,8 @@ class Ms08_067_Exploiter(HostExploiter): else: cmdline = MONKEY_CMDLINE % {'monkey_path': remote_full_path} + cmdline += " -p " + self._guid + if host.default_tunnel: cmdline += " -t " + host.default_tunnel if host.default_server: diff --git a/chaos_monkey/exploit/wmiexec.py b/chaos_monkey/exploit/wmiexec.py index 917113dea..4c2f0afdf 100644 --- a/chaos_monkey/exploit/wmiexec.py +++ b/chaos_monkey/exploit/wmiexec.py @@ -15,6 +15,7 @@ class WmiExploiter(HostExploiter): def __init__(self): self._config = __import__('config').WormConfiguration + self._guid = __import__('config').GUID @WmiTools.dcom_wrap def exploit_host(self, host, depth=-1, src_path=None): diff --git a/chaos_monkey/monkey.py b/chaos_monkey/monkey.py index 365198fee..be7184ad3 100644 --- a/chaos_monkey/monkey.py +++ b/chaos_monkey/monkey.py @@ -93,6 +93,7 @@ class ChaosMonkey(object): if 0 == WormConfiguration.depth: LOG.debug("Reached max depth, shutting down") + ControlClient.send_telemetry("trace", "Reached max depth, shutting down") return else: LOG.debug("Running with depth: %d" % WormConfiguration.depth) diff --git a/chaos_monkey/monkey.spec b/chaos_monkey/monkey.spec index eb894059c..8f3418ecb 100644 --- a/chaos_monkey/monkey.spec +++ b/chaos_monkey/monkey.spec @@ -1,4 +1,5 @@ # -*- mode: python -*- +import os import platform a = Analysis(['main.py'], pathex=['.'], @@ -12,7 +13,7 @@ if platform.system().find("Windows")>= 0: pyz = PYZ(a.pure) exe = EXE(pyz, a.scripts, - a.binaries, + a.binaries + [('msvcr100.dll', os.environ['WINDIR'] + '\system32\msvcr100.dll', 'BINARY')], a.zipfiles, a.datas, name='monkey.exe', diff --git a/chaos_monkey/readme.txt b/chaos_monkey/readme.txt index 82bb61f9b..a705d41c0 100644 --- a/chaos_monkey/readme.txt +++ b/chaos_monkey/readme.txt @@ -5,8 +5,11 @@ Windows: https://www.python.org/download/releases/2.7 2. install pywin32-219.win32-py2.7.exe http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/ -3. install VCForPython27.msi +3. a. install VCForPython27.msi http://www.microsoft.com/en-us/download/details.aspx?id=44266 + b. if not installed, install Microsoft Visual C++ 2010 SP1 Redistributable Package + 32bit: http://www.microsoft.com/en-us/download/details.aspx?id=8328 + 64bit: http://www.microsoft.com/en-us/download/details.aspx?id=13523 4. Download & Run get-pip.py https://bootstrap.pypa.io/get-pip.py 5. Run: diff --git a/monkey_island/cc/admin/ui/js/monkeys-admin.js b/monkey_island/cc/admin/ui/js/monkeys-admin.js index 190542f7e..a160efa1b 100644 --- a/monkey_island/cc/admin/ui/js/monkeys-admin.js +++ b/monkey_island/cc/admin/ui/js/monkeys-admin.js @@ -309,45 +309,44 @@ function createTunnels() { } function createScanned() { - 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 + // Gets all the scans performed by monkeys // 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 - // Reading the JSON file containing the monkeys' informations - $.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++) { - var scan = scans[i]; - //Check if we already exploited this machine from another PoV, if so no point in scanning. - if (null != getMonkeyByIP(scan.data.machine.ip_addr)) { - //if so, make sure we don't already have such a node - nodes = nodes.filter(function (node) { - return (node.id != ip_addr); - }); - continue; - } - //And check if we've already added this scanned machine - var machineNode = getScannedByIP(scan.data.machine.ip_addr) - if (null == machineNode) { - machineNode = createMachineNode(scan.data.machine); - scannedMachines.push(machineNode); - nodes.push(machineNode); - } - if(!edgeExists([monkey.id, machineNode.id, EDGE_TYPE_SCAN])) { - edges.push({from: monkey.id, to: machineNode.id, arrows:'middle', type: EDGE_TYPE_SCAN, color: EDGE_COLOR_SCAN}); - numOfScanLinks++; - } + // 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); + + //Check if we already exploited this machine from another PoV, if so no point in scanning. + if (null != getMonkeyByIP(scan.data.machine.ip_addr)) { + //if so, make sure we don't already have such a node + nodes = nodes.filter(function (node) { + return (node.id != ip_addr); + }); + continue; } - if (scans.length > 0) { - refreshDrawing(); - updateCounters(); + + //And check if we've already added this scanned machine + var machineNode = getScannedByIP(scan.data.machine.ip_addr) + if (null == machineNode) { + machineNode = createMachineNode(scan.data.machine); + scannedMachines.push(machineNode); + nodes.push(machineNode); } - }); - } + + if(!edgeExists([monkey.id, machineNode.id, EDGE_TYPE_SCAN])) { + 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(); + } + }); } /** @@ -414,7 +413,6 @@ function prepareSearchEngine() { }); } - /** * Manage the key presses events */ @@ -441,7 +439,6 @@ function onDoubleClick(properties) { onSelect(properties); } - /** * Manage the event when an object is selected */ @@ -482,7 +479,6 @@ function onNodeSelect(nodeId) { } $("#selectionInfo").html(htmlContent); - $('#monkey-config').show() $('#btnConfigLoad, #btnConfigUpdate').show(); @@ -496,7 +492,7 @@ function onNodeSelect(nodeId) { } $('#monkey-enabled').show(); - $.getJSON('/api/telemetry/' + monkey.guid, function(json) { + $.getJSON('/api/telemetry?monkey_guid=' + monkey.guid, function(json) { telemTable.clear(); var telemetries = json.objects; @@ -666,6 +662,29 @@ function selectNode(hostname, zoom) { } +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) { + console.log("DB was successfully reset!"); + location.reload(); + }, + error : function(jqXHR, textStatus, errorThrown) { + // log the error to the console + console.log("The following error occured: " + textStatus, errorThrown); + }, + complete : function() { + console.log("Trying to reset DB..."); + } + }); + } +} + /** * Get a monkey from its id */ diff --git a/monkey_island/cc/binaries/.gitignore b/monkey_island/cc/binaries/.gitignore new file mode 100644 index 000000000..86d0cb272 --- /dev/null +++ b/monkey_island/cc/binaries/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/monkey_island/cc/main.py b/monkey_island/cc/main.py index 64a92f0f9..97799c303 100644 --- a/monkey_island/cc/main.py +++ b/monkey_island/cc/main.py @@ -26,7 +26,7 @@ MONKEY_DOWNLOADS = [ { 'type': 'windows', 'machine': 'x86', - 'filename': 'monkey-linux-32.exe', + 'filename': 'monkey-windows-32.exe', }, { 'type': 'windows', @@ -202,7 +202,7 @@ class MonkeyDownload(restful.Resource): def post(self): host_json = json.loads(request.data) host_os = host_json.get('os') - if os: + if host_os: result = None for download in MONKEY_DOWNLOADS: if host_os.get('type') == download.get('type') and \