Merge branch 'develop' into feature/report-backend

This commit is contained in:
itaymmguardicore 2018-01-16 16:24:44 +02:00 committed by GitHub
commit 7e77e2d33b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 693 additions and 94 deletions

View File

@ -13,7 +13,7 @@ from exploit import HostExploiter
from exploit.tools import HTTPTools, get_monkey_depth
from exploit.tools import get_target_monkey
from model import RDP_CMDLINE_HTTP_BITS, RDP_CMDLINE_HTTP_VBS
from network.tools import check_port_tcp
from network.tools import check_tcp_port
from tools import build_monkey_commandline
__author__ = 'hoffer'
@ -245,7 +245,7 @@ class RdpExploiter(HostExploiter):
return True
if not self.host.os.get('type'):
is_open, _ = check_port_tcp(self.host.ip_addr, RDP_PORT)
is_open, _ = check_tcp_port(self.host.ip_addr, RDP_PORT)
if is_open:
self.host.os['type'] = 'windows'
return True
@ -254,7 +254,7 @@ class RdpExploiter(HostExploiter):
def exploit_host(self):
global g_reactor
is_open, _ = check_port_tcp(self.host.ip_addr, RDP_PORT)
is_open, _ = check_tcp_port(self.host.ip_addr, RDP_PORT)
if not is_open:
LOG.info("RDP port is closed on %r, skipping", self.host)
return False

View File

@ -7,7 +7,7 @@ from exploit import HostExploiter
from exploit.tools import SmbTools, get_target_monkey, get_monkey_depth
from model import MONKEY_CMDLINE_DETACHED_WINDOWS, DROPPER_CMDLINE_DETACHED_WINDOWS
from network import SMBFinger
from network.tools import check_port_tcp
from network.tools import check_tcp_port
from tools import build_monkey_commandline
LOG = getLogger(__name__)
@ -31,12 +31,12 @@ class SmbExploiter(HostExploiter):
return True
if not self.host.os.get('type'):
is_smb_open, _ = check_port_tcp(self.host.ip_addr, 445)
is_smb_open, _ = check_tcp_port(self.host.ip_addr, 445)
if is_smb_open:
smb_finger = SMBFinger()
smb_finger.get_host_fingerprint(self.host)
else:
is_nb_open, _ = check_port_tcp(self.host.ip_addr, 139)
is_nb_open, _ = check_tcp_port(self.host.ip_addr, 139)
if is_nb_open:
self.host.os['type'] = 'windows'
return self.host.os.get('type') in self._TARGET_OS_TYPE

View File

@ -7,7 +7,7 @@ import monkeyfs
from exploit import HostExploiter
from exploit.tools import get_target_monkey, get_monkey_depth
from model import MONKEY_ARG
from network.tools import check_port_tcp
from network.tools import check_tcp_port
from tools import build_monkey_commandline
__author__ = 'hoffer'
@ -41,7 +41,7 @@ class SSHExploiter(HostExploiter):
if servdata.get('name') == 'ssh' and servkey.startswith('tcp-'):
port = int(servkey.replace('tcp-', ''))
is_open, _ = check_port_tcp(self.host.ip_addr, port)
is_open, _ = check_tcp_port(self.host.ip_addr, port)
if not is_open:
LOG.info("SSH port is closed on %r, skipping", self.host)
return False

View File

@ -17,7 +17,7 @@ from impacket.dcerpc.v5 import transport
from exploit.tools import SmbTools, get_target_monkey, get_monkey_depth
from model import DROPPER_CMDLINE_WINDOWS, MONKEY_CMDLINE_WINDOWS
from network import SMBFinger
from network.tools import check_port_tcp
from network.tools import check_tcp_port
from tools import build_monkey_commandline
from . import HostExploiter
@ -168,7 +168,7 @@ class Ms08_067_Exploiter(HostExploiter):
if not self.host.os.get('type') or (
self.host.os.get('type') in self._TARGET_OS_TYPE and not self.host.os.get('version')):
is_smb_open, _ = check_port_tcp(self.host.ip_addr, 445)
is_smb_open, _ = check_tcp_port(self.host.ip_addr, 445)
if is_smb_open:
smb_finger = SMBFinger()
if smb_finger.get_host_fingerprint(self.host):

View File

@ -1,14 +1,17 @@
import os
import sys
import logging
import traceback
import logging.config
from config import WormConfiguration, EXTERNAL_CONFIG_FILE
from model import MONKEY_ARG, DROPPER_ARG
from dropper import MonkeyDrops
from monkey import ChaosMonkey
from __future__ import print_function
import argparse
import json
import logging
import logging.config
import os
import sys
import traceback
from config import WormConfiguration, EXTERNAL_CONFIG_FILE
from dropper import MonkeyDrops
from model import MONKEY_ARG, DROPPER_ARG
from monkey import ChaosMonkey
if __name__ == "__main__":
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
@ -55,22 +58,22 @@ def main():
config_file = opts.config
if os.path.isfile(config_file):
# using print because config can also change log locations
print "Loading config from %s." % config_file
print("Loading config from %s." % config_file)
try:
with open(config_file) as config_fo:
json_dict = json.load(config_fo)
WormConfiguration.from_dict(json_dict)
except ValueError as e:
print "Error loading config: %s, using default" % (e,)
print("Error loading config: %s, using default" % (e,))
else:
print("Config file wasn't supplied and default path: %s wasn't found, using internal default" % (config_file,))
print "Loaded Configuration: %r" % WormConfiguration.as_dict()
print("Loaded Configuration: %r" % WormConfiguration.as_dict())
# Make sure we're not in a machine that has the kill file
kill_path = os.path.expandvars(WormConfiguration.kill_file_path_windows) if sys.platform == "win32" else WormConfiguration.kill_file_path_linux
if os.path.exists(kill_path):
print "Kill path found, finished run"
print("Kill path found, finished run")
return True
try:

View File

@ -1,7 +1,8 @@
import re
from network import HostFinger
from network.tools import check_port_tcp
from model.host import VictimHost
from network import HostFinger
from network.tools import check_tcp_port
SSH_PORT = 22
SSH_SERVICE_DEFAULT = 'tcp-22'
@ -38,7 +39,7 @@ class SSHFinger(HostFinger):
self._banner_match(name, host, banner)
return
is_open, banner = check_port_tcp(host.ip_addr, SSH_PORT, TIMEOUT, True)
is_open, banner = check_tcp_port(host.ip_addr, SSH_PORT, TIMEOUT, True)
if is_open:
host.services[SSH_SERVICE_DEFAULT] = {}

View File

@ -1,8 +1,7 @@
import time
from random import shuffle
from network import HostScanner, HostFinger
from model.host import VictimHost
from network.tools import check_port_tcp
from network.tools import check_tcp_ports
__author__ = 'itamar'
@ -17,29 +16,24 @@ class TcpScanner(HostScanner, HostFinger):
return self.get_host_fingerprint(host, True)
def get_host_fingerprint(self, host, only_one_port=False):
assert isinstance(host, VictimHost)
"""
Scans a target host to see if it's alive using the tcp_target_ports specified in the configuration.
:param host: VictimHost structure
:param only_one_port: Currently unused.
:return: T/F if there is at least one open port. In addition, the host object is updated to mark those services as alive.
"""
count = 0
# maybe hide under really bad detection systems
target_ports = self._config.tcp_target_ports[:]
shuffle(target_ports)
for target_port in target_ports:
ports, banners = check_tcp_ports(host.ip_addr, target_ports, self._config.tcp_scan_timeout / 1000.0)
for target_port, banner in zip(ports, banners):
service = 'tcp-' + str(target_port)
host.services[service] = {}
if banner:
host.services[service]['banner'] = banner
if only_one_port:
break
is_open, banner = check_port_tcp(host.ip_addr,
target_port,
self._config.tcp_scan_timeout / 1000.0,
self._config.tcp_scan_get_banner)
if is_open:
count += 1
service = 'tcp-' + str(target_port)
host.services[service] = {}
if banner:
host.services[service]['banner'] = banner
if only_one_port:
break
else:
time.sleep(self._config.tcp_scan_interval / 1000.0)
return count != 0
return len(ports) != 0

View File

@ -1,9 +1,11 @@
import socket
import select
import logging
import select
import socket
import struct
import time
DEFAULT_TIMEOUT = 10
SLEEP_BETWEEN_POLL = 0.5
BANNER_READ = 1024
LOG = logging.getLogger(__name__)
@ -32,10 +34,18 @@ def struct_unpack_tracker_string(data, index):
"""
ascii_len = data[index:].find('\0')
fmt = "%ds" % ascii_len
return struct_unpack_tracker(data,index,fmt)
return struct_unpack_tracker(data, index, fmt)
def check_port_tcp(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
def check_tcp_port(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
"""
Checks if a given TCP port is open
:param ip: Target IP
:param port: Target Port
:param timeout: Timeout for socket connection
:param get_banner: if true, pulls first BANNER_READ bytes from the socket.
:return: Tuple, T/F + banner if requested.
"""
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
@ -43,7 +53,7 @@ def check_port_tcp(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
sock.connect((ip, port))
except socket.timeout:
return False, None
except socket.error, exc:
except socket.error as exc:
LOG.debug("Check port: %s:%s, Exception: %s", ip, port, exc)
return False, None
@ -54,26 +64,96 @@ def check_port_tcp(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
read_ready, _, _ = select.select([sock], [], [], timeout)
if len(read_ready) > 0:
banner = sock.recv(BANNER_READ)
except:
except socket.error:
pass
sock.close()
return True, banner
def check_port_udp(ip, port, timeout=DEFAULT_TIMEOUT):
def check_udp_port(ip, port, timeout=DEFAULT_TIMEOUT):
"""
Checks if a given UDP port is open by checking if it replies to an empty message
:param ip: Target IP
:param port: Target port
:param timeout: Timeout to wait
:return: Tuple, T/F + banner
"""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(timeout)
data = None
is_open = False
try:
sock.sendto("-", (ip, port))
data, _ = sock.recvfrom(BANNER_READ)
is_open = True
except:
except socket.error:
pass
sock.close()
return is_open, data
def check_tcp_ports(ip, ports, timeout=DEFAULT_TIMEOUT, get_banner=False):
"""
Checks whether any of the given ports are open on a target IP.
:param ip: IP of host to attack
:param ports: List of ports to attack. Must not be empty.
:param timeout: Amount of time to wait for connection.
:param get_banner: T/F if to get first packets from server
:return: list of open ports. If get_banner=True, then a matching list of banners.
"""
sockets = [socket.socket(socket.AF_INET, socket.SOCK_STREAM) for _ in range(len(ports))]
[s.setblocking(0) for s in sockets]
port_attempts = []
try:
for sock, port in zip(sockets, ports):
LOG.debug("Connecting to port %d" % port)
err = sock.connect_ex((ip, port))
if err == 0:
port_attempts.append((port, sock))
if err == 10035: # WSAEWOULDBLOCK is valid, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
port_attempts.append((port, sock))
if len(port_attempts) != 0:
num_replies = 0
timeout = int(round(timeout)) # clamp to integer, to avoid checking input
time_left = timeout
write_sockets = []
read_sockets = []
while num_replies != len(port_attempts):
# bad ports show up as err_sockets
read_sockets, write_sockets, err_sockets = \
select.select(
[s[1] for s in port_attempts],
[s[1] for s in port_attempts],
[s[1] for s in port_attempts],
time_left)
# any read_socket is automatically a writesocket
num_replies = len(write_sockets) + len(err_sockets)
if num_replies == len(port_attempts) or time_left <= 0:
break
else:
time_left -= SLEEP_BETWEEN_POLL
time.sleep(SLEEP_BETWEEN_POLL)
connected_ports_sockets = [x for x in port_attempts if x[1] in write_sockets]
LOG.debug(
"On host %s discovered the following ports %s" %
(str(ip), ",".join([str(x) for x in connected_ports_sockets])))
banners = []
if get_banner:
# read first X bytes
banners = [sock.recv(BANNER_READ) if sock in read_sockets else ""
for port, sock in connected_ports_sockets]
pass
# try to cleanup
[s[1].close() for s in port_attempts]
return [port for port, sock in connected_ports_sockets], banners
else:
return [], []
except socket.error as exc:
LOG.warning("Exception when checking ports on host %s, Exception: %s", str(ip), exc)
return [], []

View File

@ -1,3 +1,4 @@
import logging
import socket
import sys
@ -6,6 +7,8 @@ from enum import IntEnum
from network.info import get_host_subnets
LOG = logging.getLogger(__name__)
# Linux doesn't have WindowsError
try:
WindowsError
@ -56,8 +59,9 @@ class InfoCollector(object):
def get_hostname(self):
"""
Adds the fully qualified computer hostname to the system information.
:return: Nothing
:return: None. Updates class information
"""
LOG.debug("Reading hostname")
self.info['hostname'] = socket.getfqdn()
def get_process_list(self):
@ -65,8 +69,9 @@ class InfoCollector(object):
Adds process information from the host to the system information.
Currently lists process name, ID, parent ID, command line
and the full image path of each process.
:return: Nothing
:return: None. Updates class information
"""
LOG.debug("Reading process list")
processes = {}
for process in psutil.process_iter():
try:
@ -95,6 +100,7 @@ class InfoCollector(object):
Adds network information from the host to the system information.
Currently updates with a list of networks accessible from host,
containing host ip and the subnet range.
:return: None
:return: None. Updates class information
"""
LOG.debug("Reading subnets")
self.info['network_info'] = {'networks': get_host_subnets()}

View File

@ -1,7 +1,11 @@
import logging
from . import InfoCollector
__author__ = 'uri'
LOG = logging.getLogger(__name__)
class LinuxInfoCollector(InfoCollector):
"""
@ -12,6 +16,12 @@ class LinuxInfoCollector(InfoCollector):
super(LinuxInfoCollector, self).__init__()
def get_info(self):
"""
Collect Linux system information
Hostname, process list and network subnets
:return: Dict of system information
"""
LOG.debug("Running Linux collector")
self.get_hostname()
self.get_process_list()
self.get_network_info()

View File

@ -1,5 +1,5 @@
import ctypes
import binascii
import ctypes
import logging
import socket
@ -8,13 +8,14 @@ __author__ = 'itay.mizeretz'
LOG = logging.getLogger(__name__)
class MimikatzCollector:
class MimikatzCollector(object):
"""
Password collection module for Windows using Mimikatz.
"""
def __init__(self):
try:
self._isInit = False
self._config = __import__('config').WormConfiguration
self._dll = ctypes.WinDLL(self._config.mimikatz_dll_name)
@ -31,9 +32,9 @@ class MimikatzCollector:
Gets the logon info from mimikatz.
Returns a dictionary of users with their known credentials.
"""
if not self._isInit:
return {}
LOG.debug("Running mimikatz collector")
try:
entry_count = self._collect()

View File

@ -1,5 +1,10 @@
from . import InfoCollector
import logging
from mimikatz_collector import MimikatzCollector
from . import InfoCollector
LOG = logging.getLogger(__name__)
__author__ = 'uri'
@ -12,6 +17,13 @@ class WindowsInfoCollector(InfoCollector):
super(WindowsInfoCollector, self).__init__()
def get_info(self):
"""
Collect Windows system information
Hostname, process list and network subnets
Tries to read credential secrets using mimikatz
:return: Dict of system information
"""
LOG.debug("Running Windows collector")
self.get_hostname()
self.get_process_list()
self.get_network_info()

View File

@ -8,7 +8,7 @@ from threading import Thread
from model import VictimHost
from network.firewall import app as firewall
from network.info import local_ips, get_free_tcp_port
from network.tools import check_port_tcp
from network.tools import check_tcp_port
from transport.base import get_last_serve_time
__author__ = 'hoffer'
@ -40,7 +40,7 @@ def _check_tunnel(address, port, existing_sock=None):
sock = existing_sock
LOG.debug("Checking tunnel %s:%s", address, port)
is_open, _ = check_port_tcp(address, int(port))
is_open, _ = check_tcp_port(address, int(port))
if not is_open:
LOG.debug("Could not connect to %s:%s", address, port)
if not existing_sock:

View File

@ -17,6 +17,7 @@ from cc.resources.edge import Edge
from cc.resources.node import Node
from cc.resources.report import Report
from cc.resources.root import Root
from cc.resources.telemetry_feed import TelemetryFeed
from cc.services.config import ConfigService
__author__ = 'Barak'
@ -89,5 +90,6 @@ def init_app(mongo_url):
api.add_resource(Edge, '/api/netmap/edge', '/api/netmap/edge/')
api.add_resource(Node, '/api/netmap/node', '/api/netmap/node/')
api.add_resource(Report, '/api/report', '/api/report/')
api.add_resource(TelemetryFeed, '/api/telemetry-feed', '/api/telemetry-feed/')
return app

View File

@ -36,7 +36,7 @@ def run_local_monkey():
# run the monkey
try:
args = ["%s m0nk3y -s %s:%s" % (target_path, local_ip_addresses()[0], ISLAND_PORT)]
args = ['"%s" m0nk3y -s %s:%s' % (target_path, local_ip_addresses()[0], ISLAND_PORT)]
if sys.platform == "win32":
args = "".join(args)
pid = subprocess.Popen(args, shell=True).pid

View File

@ -0,0 +1,85 @@
from datetime import datetime
import dateutil
import flask_restful
from flask import request
from cc.database import mongo
from cc.services.node import NodeService
__author__ = 'itay.mizeretz'
class TelemetryFeed(flask_restful.Resource):
def get(self, **kw):
timestamp = request.args.get('timestamp')
if "null" == timestamp or timestamp is None: # special case to avoid ugly JS code...
telemetries = mongo.db.telemetry.find({})
else:
telemetries = mongo.db.telemetry.find({'timestamp': {'$gt': dateutil.parser.parse(timestamp)}})
return \
{
'telemetries': [TelemetryFeed.get_displayed_telemetry(telem) for telem in telemetries],
'timestamp': datetime.now().isoformat()
}
@staticmethod
def get_displayed_telemetry(telem):
return \
{
'id': telem['_id'],
'timestamp': telem['timestamp'].strftime('%d/%m/%Y %H:%M:%S'),
'hostname': NodeService.get_monkey_by_guid(telem['monkey_guid'])['hostname'],
'brief': TELEM_PROCESS_DICT[telem['telem_type']](telem)
}
@staticmethod
def get_tunnel_telem_brief(telem):
tunnel = telem['data']['proxy']
if tunnel is None:
return 'No tunnel is used.'
else:
tunnel_host_ip = tunnel.split(":")[-2].replace("//", "")
tunnel_host = NodeService.get_monkey_by_ip(tunnel_host_ip)['hostname']
return 'Tunnel set up to machine: %s.' % tunnel_host
@staticmethod
def get_state_telem_brief(telem):
if telem['data']['done']:
return 'Monkey died.'
else:
return 'Monkey started.'
@staticmethod
def get_exploit_telem_brief(telem):
target = telem['data']['machine']['ip_addr']
exploiter = telem['data']['exploiter']
result = telem['data']['result']
if result:
return 'Monkey successfully exploited %s using the %s exploiter.' % (target, exploiter)
else:
return 'Monkey failed exploiting %s using the %s exploiter.' % (target, exploiter)
@staticmethod
def get_scan_telem_brief(telem):
return 'Monkey discovered machine %s.' % telem['data']['machine']['ip_addr']
@staticmethod
def get_systeminfo_telem_brief(telem):
return 'Monkey collected system information.'
@staticmethod
def get_trace_telem_brief(telem):
return 'Monkey reached max depth.'
TELEM_PROCESS_DICT = \
{
'tunnel': TelemetryFeed.get_tunnel_telem_brief,
'state': TelemetryFeed.get_state_telem_brief,
'exploit': TelemetryFeed.get_exploit_telem_brief,
'scan': TelemetryFeed.get_scan_telem_brief,
'system_info_collection': TelemetryFeed.get_systeminfo_telem_brief,
'trace': TelemetryFeed.get_trace_telem_brief
}

View File

@ -15,7 +15,9 @@ class MapPageComponent extends React.Component {
selected: null,
selectedType: null,
killPressed: false,
showKillDialog: false
showKillDialog: false,
telemetry: [],
telemetryLastTimestamp: null
};
}
@ -25,13 +27,18 @@ class MapPageComponent extends React.Component {
componentDidMount() {
this.updateMapFromServer();
this.interval = setInterval(this.updateMapFromServer, 1000);
this.interval = setInterval(this.timedEvents, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
timedEvents = () => {
this.updateMapFromServer();
this.updateTelemetryFromServer();
};
updateMapFromServer = () => {
fetch('/api/netmap')
.then(res => res.json())
@ -44,6 +51,21 @@ class MapPageComponent extends React.Component {
});
};
updateTelemetryFromServer = () => {
fetch('/api/telemetry-feed?timestamp='+this.state.telemetryLastTimestamp)
.then(res => res.json())
.then(res => {
let newTelem = this.state.telemetry.concat(res['telemetries']);
this.setState(
{
telemetry: newTelem,
telemetryLastTimestamp: res['timestamp']
});
this.props.onStatusChange();
});
};
selectionChanged(event) {
if (event.nodes.length === 1) {
fetch('/api/netmap/node?id=' + event.nodes[0])
@ -104,6 +126,26 @@ class MapPageComponent extends React.Component {
)
};
renderTelemetryEntry(telemetry) {
return (
<div key={telemetry.id}>
<span className="date">{telemetry.timestamp}</span>
<span className="source"> {telemetry.hostname}:</span>
<span className="event"> {telemetry.brief}</span>
</div>
);
}
renderTelemetryConsole() {
return (
<div className="telemetry-console">
{
this.state.telemetry.map(this.renderTelemetryEntry)
}
</div>
);
}
render() {
return (
<div>
@ -122,17 +164,7 @@ class MapPageComponent extends React.Component {
<b style={{color: '#aeaeae'}}> | </b>
<span>Island Communication <i className="fa fa-lg fa-minus" style={{color: '#a9aaa9'}} /></span>
</div>
{
/*
<div className="telemetry-console">
<div>
<span className="date">2017-10-16 16:00:05</span>
<span className="source"> monkey-elastic</span>
<span className="event"> bla bla</span>
</div>
</div>
*/
}
{ this.renderTelemetryConsole() }
<div style={{height: '80vh'}}>
<ReactiveGraph graph={this.state.graph} options={options} events={this.events}/>
</div>

View File

@ -277,13 +277,14 @@ body {
bottom: 0;
left: 0;
right: 0;
height: 70px;
height: 130px;
background: rgba(0,0,0,0.7);
border-radius: 5px;
border: 3px solid #aaa;
padding: 0.5em;
color: white;
font-family: Consolas, "Courier New", monospace;
overflow: auto;
}
.telemetry-console .date {

View File

@ -2,16 +2,17 @@
MONKEY_FOLDER=/var/monkey_island
INSTALLATION_FOLDER=/var/monkey_island/installation
PYTHON_FOLDER=/var/monkey_island/bin/python
cp -f ${MONKEY_FOLDER}/monkey.sh /usr/bin/monkey
chmod 755 /usr/bin/monkey
# Fix dependency bug
pip uninstall -y bson
# Prepare python virtualenv
pip2 install virtualenv --no-index --find-links file://$INSTALLATION_FOLDER
virtualenv -p python2.7 ${PYTHON_FOLDER}
# install pip requirements
pip install -r $MONKEY_FOLDER/pip_requirements.txt --no-index --find-links file://$INSTALLATION_FOLDER
${PYTHON_FOLDER}/bin/python -m pip install -r $MONKEY_FOLDER/pip_requirements.txt --no-index --find-links file://$INSTALLATION_FOLDER
# remove installation folder and unnecessary files
rm -rf ${INSTALLATION_FOLDER}

View File

@ -8,4 +8,6 @@ rm -f /etc/init/monkey-mongo.conf
[ -f "/lib/systemd/system/monkey-island.service" ] && rm -f /lib/systemd/system/monkey-island.service
[ -f "/lib/systemd/system/monkey-mongo.service" ] && rm -f /lib/systemd/system/monkey-mongo.service
rm -r -f /var/monkey_island
exit 0

View File

@ -9,4 +9,5 @@ flask
Flask-Pymongo
Flask-Restful
jsonschema
netifaces
netifaces
virtualenv

View File

@ -1,4 +1,4 @@
#!/bin/bash
cd /var/monkey_island/cc
python main.py
/var/monkey_island/bin/python/bin/python main.py

View File

@ -0,0 +1 @@
xcopy %1 %2

View File

@ -1,3 +1,18 @@
bin\openssl\openssl.exe genrsa -out cc\server.key 1024
bin\openssl\openssl.exe req -new -config bin\openssl\openssl.cfg -key cc\server.key -out cc\server.csr -subj "/C=GB/ST=London/L=London/O=Global Security/OU=Monkey Department/CN=monkey.com"
bin\openssl\openssl.exe x509 -req -days 366 -in cc\server.csr -signkey cc\server.key -out cc\server.crt
@echo off
IF [%1] == [] (
set mydir=%cd%\
) ELSE (
set mydir=%~1%
)
echo Monkey Island folder: %mydir%
SET OPENSSL_CONF=%mydir%bin\openssl\openssl.cfg
copy "%mydir%windows\openssl.cfg" "%mydir%bin\openssl\openssl.cfg"
@echo on
"%mydir%bin\openssl\openssl.exe" genrsa -out "%mydir%cc\server.key" 1024
"%mydir%bin\openssl\openssl.exe" req -new -config "%mydir%bin\openssl\openssl.cfg" -key "%mydir%cc\server.key" -out "%mydir%cc\server.csr" -subj "/C=GB/ST=London/L=London/O=Global Security/OU=Monkey Department/CN=monkey.com"
"%mydir%bin\openssl\openssl.exe" x509 -req -days 366 -in "%mydir%cc\server.csr" -signkey "%mydir%cc\server.key" -out "%mydir%cc\server.crt"

View File

@ -0,0 +1,350 @@
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
# Policies used by the TSA examples.
tsa_policy1 = 1.2.3.4.1
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = ./demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = default # use public key default MD
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
# utf8only: only UTF8Strings (PKIX recommendation after 2004).
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
string_mask = utf8only
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = AU
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Some-State
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Internet Widgits Pty Ltd
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This is required for TSA certificates.
# extendedKeyUsage = critical,timeStamping
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
####################################################################
[ tsa ]
default_tsa = tsa_config1 # the default TSA section
[ tsa_config1 ]
# These are used by the TSA reply generation only.
dir = ./demoCA # TSA root directory
serial = $dir/tsaserial # The current serial number (mandatory)
crypto_device = builtin # OpenSSL engine to use for signing
signer_cert = $dir/tsacert.pem # The TSA signing certificate
# (optional)
certs = $dir/cacert.pem # Certificate chain to include in reply
# (optional)
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
default_policy = tsa_policy1 # Policy if request did not specify it
# (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
digests = md5, sha1 # Acceptable message digests (mandatory)
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
clock_precision_digits = 0 # number of digits after dot. (optional)
ordering = yes # Is ordering defined for timestamps?
# (optional, default: no)
tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)

View File

@ -0,0 +1 @@
del %1

View File

@ -1,3 +1,4 @@
if not exist db mkdir db
start windows\run_mongodb.bat
start windows\run_cc.bat
start windows\run_cc.bat
start https://localhost:5000