Merge remote-tracking branch 'origin/develop' into bugfix/various-island-fixes

# Conflicts:
#	monkey_island/cc/services/config.py
This commit is contained in:
Itay Mizeretz 2017-10-09 10:53:32 +03:00
commit 9b6c008330
7 changed files with 84 additions and 52 deletions

View File

@ -173,6 +173,8 @@ class Configuration(object):
# addresses of internet servers to ping and check if the monkey has internet acccess.
internet_services = ["monkey.guardicore.com", "www.google.com"]
keep_tunnel_open_time = 60
###########################
# scanners config
###########################

View File

@ -6,6 +6,7 @@
"monkey.guardicore.com",
"www.google.com"
],
"keep_tunnel_open_time": 60,
"range_class": "RelativeRange",
"range_fixed": [
""

View File

@ -100,7 +100,6 @@ class SambaCryExploiter(HostExploiter):
smb_client = self.connect_to_server(host.ip_addr, creds)
self.upload_module(smb_client, host, share, depth)
self.trigger_module(smb_client, share)
smb_client.close()
except (impacket.smbconnection.SessionError, SessionError):
LOG.debug(
"Exception trying to exploit host: %s, share: %s, with creds: %s." % (host.ip_addr, share, str(creds)))
@ -125,7 +124,6 @@ class SambaCryExploiter(HostExploiter):
# Ignore exception to try and delete as much as possible
pass
smb_client.disconnectTree(tree_id)
smb_client.close()
def get_trigger_result(self, ip, share, creds):
"""
@ -147,7 +145,6 @@ class SambaCryExploiter(HostExploiter):
pass
smb_client.disconnectTree(tree_id)
smb_client.close()
return file_content
def get_writable_shares_creds_dict(self, ip):
@ -159,6 +156,8 @@ class SambaCryExploiter(HostExploiter):
writable_shares_creds_dict = {}
credentials_list = self.get_credentials_list()
LOG.debug("SambaCry credential list: %s" % str(credentials_list))
for credentials in credentials_list:
try:
smb_client = self.connect_to_server(ip, credentials)
@ -169,7 +168,6 @@ class SambaCryExploiter(HostExploiter):
if self.is_share_writable(smb_client, share):
writable_shares_creds_dict[share] = credentials
smb_client.close()
except (impacket.smbconnection.SessionError, SessionError):
# If failed using some credentials, try others.
pass

View File

@ -1,17 +1,18 @@
import sys
import os
import time
import logging
import tunnel
import argparse
import logging
import os
import subprocess
from system_singleton import SystemSingleton
from network.firewall import app as firewall
from control import ControlClient
import sys
import time
import tunnel
from config import WormConfiguration
from network.network_scanner import NetworkScanner
from control import ControlClient
from model import DELAY_DELETE_CMD
from network.firewall import app as firewall
from network.network_scanner import NetworkScanner
from system_info import SystemInfoCollector
from system_singleton import SystemSingleton
__author__ = 'itamar'
@ -80,8 +81,6 @@ class ChaosMonkey(object):
if monkey_tunnel:
monkey_tunnel.start()
last_exploit_time = None
ControlClient.send_telemetry("state", {'done': False})
self._default_server = WormConfiguration.current_server
@ -101,7 +100,7 @@ class ChaosMonkey(object):
else:
LOG.debug("Running with depth: %d" % WormConfiguration.depth)
for _ in xrange(WormConfiguration.max_iterations):
for iteration_index in xrange(WormConfiguration.max_iterations):
ControlClient.keepalive()
ControlClient.load_control_config()
@ -146,7 +145,6 @@ class ChaosMonkey(object):
LOG.debug("Skipping %r - exploitation failed before", machine)
continue
if monkey_tunnel:
monkey_tunnel.set_tunnel_for_host(machine)
if self._default_server:
@ -172,15 +170,14 @@ class ChaosMonkey(object):
'exploiter': exploiter.__class__.__name__})
except Exception as exc:
LOG.error("Exception while attacking %s using %s: %s",
machine, exploiter.__class__.__name__, exc)
LOG.exception("Exception while attacking %s using %s: %s",
machine, exploiter.__class__.__name__, exc)
ControlClient.send_telemetry('exploit', {'result': False, 'machine': machine.__dict__,
'exploiter': exploiter.__class__.__name__})
continue
if successful_exploiter:
self._exploited_machines.add(machine)
last_exploit_time = time.time()
ControlClient.send_telemetry('exploit', {'result': True, 'machine': machine.__dict__,
'exploiter': successful_exploiter.__class__.__name__})
@ -196,8 +193,10 @@ class ChaosMonkey(object):
else:
self._fail_exploitation_machines.add(machine)
if not is_empty:
time.sleep(WormConfiguration.timeout_between_iterations)
if (not is_empty) and (WormConfiguration.max_iterations > iteration_index + 1):
time_to_sleep = WormConfiguration.timeout_between_iterations
LOG.info("Sleeping %d seconds before next life cycle iteration", time_to_sleep)
time.sleep(time_to_sleep)
if self._keep_running and WormConfiguration.alive:
LOG.info("Reached max iterations (%d)", WormConfiguration.max_iterations)
@ -206,8 +205,10 @@ class ChaosMonkey(object):
# if host was exploited, before continue to closing the tunnel ensure the exploited host had its chance to
# connect to the tunnel
if last_exploit_time and (time.time() - last_exploit_time < 60):
time.sleep(time.time() - last_exploit_time)
if len(self._exploited_machines) > 0:
time_to_sleep = WormConfiguration.keep_tunnel_open_time
LOG.info("Sleeping %d seconds for exploited machines to connect to tunnel", time_to_sleep)
time.sleep(time_to_sleep)
if monkey_tunnel:
monkey_tunnel.stop()
@ -242,7 +243,7 @@ class ChaosMonkey(object):
close_fds=True, startupinfo=startupinfo)
else:
os.remove(sys.executable)
except Exception, exc:
except Exception as exc:
LOG.error("Exception in self delete: %s", exc)
LOG.info("Monkey is shutting down")

View File

@ -29,6 +29,8 @@ def get_host_subnets():
for network in ipv4_nets:
if 'broadcast' in network:
network.pop('broadcast')
for attr in network:
network[attr] = network[attr].encode('utf-8').strip()
return ipv4_nets
@ -47,8 +49,7 @@ else:
def local_ips():
ipv4_nets = get_host_subnets()
valid_ips = [network['addr'] for network in ipv4_nets]
valid_ips = [network['addr'] for network in get_host_subnets()]
return valid_ips

View File

@ -1,35 +1,58 @@
How to create a monkey build environment:
How to build a monkey binary from scratch.
The monkey is composed of three seperate parts.
* The Infection Monkey itself - PyInstaller compressed python archives
* Sambacry binaries - Two linux binaries, 32/64 bit.
* Mimikatz binaries - Two windows binaries, 32/64 bit.
--- Windows ---
Windows:
1. Install python 2.7. Preferably you should use ActiveState Python which includes pywin32 built in.
You must use an up to date version, atleast version 2.7.10
http://www.activestate.com/activepython/downloads
https://www.python.org/downloads/release/python-2712/
2. install pywin32-219.win32-py2.7.exe at least
http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/
You must use an up to date version, at least version 2.7.10
http://www.activestate.com/activepython/downloads
https://www.python.org/downloads/release/python-2712/
If not using ActiveState, install pywin32, minimum build 219
http://sourceforge.net/projects/pywin32/files/pywin32
3. a. install VCForPython27.msi
http://www.microsoft.com/en-us/download/details.aspx?id=44266
https://aka.ms/vcpython27
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:
Install the python packages listed in requirements.txt. Using pip install -r requirements.txt
7. Download and extract UPX binary to [source-path]\monkey\chaos_monkey\bin\upx.exe:
http://upx.sourceforge.net/download/upx391w.zip
8. Run [source-path]\monkey\chaos_monkey\build_windows.bat to build, output is in dist\monkey.exe
4. Download the dependent python packages using
pip install -r requirements.txt
5. Download and extract UPX binary to [source-path]\monkey\chaos_monkey\bin\upx.exe:
https://github.com/upx/upx/releases/download/v3.94/upx394w.zip
6. To build the final exe:
1 cd [code location]/chaos_monkey
build_windows.bat
output is in dist\monkey.exe
--- Linux ---
Tested on Ubuntu 16.04 and 17.04.
Linux (Tested on Ubuntu 12.04):
1. Run:
sudo apt-get update
sudo apt-get install python-pip python-dev libffi-dev upx libssl-dev libc++1
Install the python packages listed in requirements.txt.
Using pip install -r requirements.txt
sudo apt-get install winbind
2. Put source code in /home/user/Code/monkey/chaos_monkey
sudo apt-get update
sudo apt-get install python-pip python-dev libffi-dev upx libssl-dev libc++1
Install the python packages listed in requirements.txt.
Using pip install -r requirements.txt
sudo apt-get install winbind dnet-common
2. Put source code in Code/monkey/chaos_monkey
3. To build, run in terminal:
cd /home/user/Code/monkey/chaos_monkey
chmod +x build_linux.sh
./build_linux.sh
cd [code location]/chaos_monkey
chmod +x build_linux.sh
./build_linux.sh
output is in dist/monkey
-- Sambacry --
Sambacry requires two standalone binaries to execute remotely.
Compiling them requires gcc
cd [code location]/chaos_monkey/monkey_utils/sambacry_monkey_runner
./build.sh
-- Mimikatz --
Mimikatz is required for the Monkey to be able to steal credentials on Windows. It's possible to either compile from sources (requires Visual Studio 2013 and up) or download the binaries from
https://github.com/guardicore/mimikatz/releases/tag/1.0.0
Download both 32 and 64 bit DLLs and place them under [code location]\chaos_monkey\bin

View File

@ -350,6 +350,12 @@ SCHEMA = {
"type": "boolean",
"default": True,
"description": "Determines whether to collect system info"
},
"keep_tunnel_open_time": {
"title": "Keep tunnel open time",
"type": "integer",
"default": 60,
"description": "Time to keep tunnel open before going down after last exploit (in seconds)"
}
}
},