From 10c9648854218161b968b439e8907fb0052a3a9c Mon Sep 17 00:00:00 2001
From: Daniel Goldberg <danielg@guardicore.com>
Date: Mon, 25 Sep 2017 12:01:48 +0300
Subject: [PATCH 1/9] Add mysql fingerprinting  and  improve struct parsing

---
 chaos_monkey/config.py              |  4 +-
 chaos_monkey/example.conf           |  3 +-
 chaos_monkey/network/__init__.py    |  1 +
 chaos_monkey/network/mysqlfinger.py | 78 +++++++++++++++++++++++++++++
 chaos_monkey/network/tools.py       | 28 +++++++++++
 5 files changed, 111 insertions(+), 3 deletions(-)
 create mode 100644 chaos_monkey/network/mysqlfinger.py

diff --git a/chaos_monkey/config.py b/chaos_monkey/config.py
index cfda27913..b0f615552 100644
--- a/chaos_monkey/config.py
+++ b/chaos_monkey/config.py
@@ -3,7 +3,7 @@ import sys
 from network.range import FixedRange, RelativeRange, ClassCRange
 from exploit import WmiExploiter, Ms08_067_Exploiter, SmbExploiter, RdpExploiter, SSHExploiter, ShellShockExploiter,\
     SambaCryExploiter
-from network import TcpScanner, PingScanner, SMBFinger, SSHFinger, HTTPFinger
+from network import TcpScanner, PingScanner, SMBFinger, SSHFinger, HTTPFinger, MySQLFinger
 from abc import ABCMeta
 from itertools import product
 import uuid
@@ -140,7 +140,7 @@ class Configuration(object):
     max_iterations = 1
 
     scanner_class = TcpScanner
-    finger_classes = [SMBFinger, SSHFinger, PingScanner, HTTPFinger]
+    finger_classes = [SMBFinger, SSHFinger, PingScanner, HTTPFinger, MySQLFinger]
     exploiter_classes = [SmbExploiter, WmiExploiter, RdpExploiter, Ms08_067_Exploiter,  # Windows exploits
                          SSHExploiter, ShellShockExploiter, SambaCryExploiter  # Linux
                          ]
diff --git a/chaos_monkey/example.conf b/chaos_monkey/example.conf
index 4396cae34..55a716c7c 100644
--- a/chaos_monkey/example.conf
+++ b/chaos_monkey/example.conf
@@ -39,7 +39,8 @@
         "SSHFinger",
         "PingScanner",
         "HTTPFinger",
-        "SMBFinger"
+        "SMBFinger",
+        "MySQLFinger"
     ],
     "max_iterations": 3,
     "monkey_log_path_windows": "%temp%\\~df1563.tmp",
diff --git a/chaos_monkey/network/__init__.py b/chaos_monkey/network/__init__.py
index 850159342..e7f22de28 100644
--- a/chaos_monkey/network/__init__.py
+++ b/chaos_monkey/network/__init__.py
@@ -23,5 +23,6 @@ from tcp_scanner import TcpScanner
 from smbfinger import SMBFinger
 from sshfinger import SSHFinger
 from httpfinger import HTTPFinger
+from mysqlfinger import MySQLFinger
 from info import local_ips
 from info import get_free_tcp_port
diff --git a/chaos_monkey/network/mysqlfinger.py b/chaos_monkey/network/mysqlfinger.py
new file mode 100644
index 000000000..0bda6c5ac
--- /dev/null
+++ b/chaos_monkey/network/mysqlfinger.py
@@ -0,0 +1,78 @@
+import socket
+import logging
+from network import HostFinger
+from .tools import struct_unpack_tracker, struct_unpack_tracker_string
+from model.host import VictimHost
+
+MYSQL_PORT = 3306
+SQL_SERVICE = 'mysqld-3306'
+
+LOG = logging.getLogger(__name__)
+
+
+class MySQLFinger(HostFinger):
+    """
+        Fingerprints mysql databases, only on port 3306
+    """
+
+    def __init__(self):
+        self._config = __import__('config').WormConfiguration
+
+    def get_host_fingerprint(self, host):
+        """
+        Returns mySQLd data using the host header
+        :param host:
+        :return: Success/failure, data is saved in the host struct
+        """
+        assert isinstance(host, VictimHost)
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.settimeout(0.5)
+
+        try:
+            s.connect((host.ip_addr, MYSQL_PORT))
+            header = s.recv(4)  # max header size?
+
+            tmp, curpos = struct_unpack_tracker(header, 0, "I")
+            tmp = tmp[0]
+            response_length = tmp & 0xff
+            data = s.recv(response_length)
+            # now we can start parsing
+            protocol, curpos = struct_unpack_tracker(data, 0, "B")
+            protocol = protocol[0]
+
+            if protocol == 0xFF:
+                # error code, bug out
+                LOG.debug("Mysql server returned error")
+                return False
+
+            version, curpos = struct_unpack_tracker_string(data, curpos)  # special coded to solve string parsing
+            version = version[0]
+            host.services[SQL_SERVICE]['version'] = version
+            version = version.split('-')[0].split('.')
+            host.services[SQL_SERVICE]['major_version'] = version[0]
+            host.services[SQL_SERVICE]['minor_version'] = version[1]
+            host.services[SQL_SERVICE]['build_version'] = version[2]
+            thread_id, curpos = struct_unpack_tracker(data, curpos, "<I")  # ignore thread id
+
+            if protocol == 10:
+                # new protocol
+                self._parse_protocol_10(curpos, data, host)
+                return True
+            if protocol == 9:
+                return True
+            s.close()
+
+        except Exception as err:
+            LOG.debug("Error getting mysql fingerprint: %s", err)
+
+        return False
+
+    def _parse_protocol_10(self, curpos, data, host):
+        salt, curpos = struct_unpack_tracker(data, curpos, "s8B")
+        capabilities, curpos = struct_unpack_tracker(data, curpos, "<H")
+        host.services[SQL_SERVICE]['capabilities'] = capabilities[0]
+        charset, curpos = struct_unpack_tracker(data, curpos, "B")
+        status, curpos = struct_unpack_tracker(data, curpos, "<H")
+        extcapabilities, curpos = struct_unpack_tracker(data, curpos, "<H")
+        host.services[SQL_SERVICE]['extcapabilities'] = extcapabilities[0]
+        # there's more data but it doesn't matter
diff --git a/chaos_monkey/network/tools.py b/chaos_monkey/network/tools.py
index 8eb85704f..3d7fe64ef 100644
--- a/chaos_monkey/network/tools.py
+++ b/chaos_monkey/network/tools.py
@@ -1,6 +1,7 @@
 import socket
 import select
 import logging
+import struct
 
 DEFAULT_TIMEOUT = 10
 BANNER_READ = 1024
@@ -8,6 +9,33 @@ BANNER_READ = 1024
 LOG = logging.getLogger(__name__)
 
 
+def struct_unpack_tracker(data, index, fmt):
+    """
+    Unpacks a struct from the specified index according to specified format.
+    Returns the data and the next index
+    :param data:  Buffer
+    :param index: Position index
+    :param fmt: Struct format
+    :return: (Data, new index)
+    """
+    unpacked = struct.unpack_from(fmt, data, index)
+    return unpacked, struct.calcsize(fmt)
+
+
+def struct_unpack_tracker_string(data, index):
+    """
+    Unpacks a null terminated string from the specified index
+    Returns the data and the next index
+    :param data:  Buffer
+    :param index: Position index
+    :return: (Data, new index)
+    """
+    ascii_len = data[index:].find('\0')
+    fmt = "%ds" % ascii_len
+    unpacked = struct.unpack_from(fmt, data, index)
+    return unpacked, struct.calcsize(fmt)
+
+
 def check_port_tcp(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     sock.settimeout(timeout)

From 86d6cdfba3e783627e0f5efde3e1d64efb8f1418 Mon Sep 17 00:00:00 2001
From: Daniel Goldberg <danielg@guardicore.com>
Date: Mon, 25 Sep 2017 15:13:36 +0300
Subject: [PATCH 2/9] Add elasticsearch fingerprinting.

---
 chaos_monkey/config.py                | 37 +++++++++++++++------
 chaos_monkey/example.conf             |  4 ++-
 chaos_monkey/network/__init__.py      |  1 +
 chaos_monkey/network/elasticfinger.py | 48 +++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 12 deletions(-)
 create mode 100644 chaos_monkey/network/elasticfinger.py

diff --git a/chaos_monkey/config.py b/chaos_monkey/config.py
index cfda27913..7e5165cc8 100644
--- a/chaos_monkey/config.py
+++ b/chaos_monkey/config.py
@@ -1,13 +1,14 @@
 import os
 import sys
-from network.range import FixedRange, RelativeRange, ClassCRange
-from exploit import WmiExploiter, Ms08_067_Exploiter, SmbExploiter, RdpExploiter, SSHExploiter, ShellShockExploiter,\
-    SambaCryExploiter
-from network import TcpScanner, PingScanner, SMBFinger, SSHFinger, HTTPFinger
+import types
+import uuid
 from abc import ABCMeta
 from itertools import product
-import uuid
-import types
+
+from exploit import WmiExploiter, Ms08_067_Exploiter, SmbExploiter, RdpExploiter, SSHExploiter, ShellShockExploiter, \
+    SambaCryExploiter
+from network import TcpScanner, PingScanner, SMBFinger, SSHFinger, HTTPFinger, ElasticFinger
+from network.range import FixedRange
 
 __author__ = 'itamar'
 
@@ -15,6 +16,7 @@ GUID = str(uuid.getnode())
 
 EXTERNAL_CONFIG_FILE = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), 'monkey.bin')
 
+
 def _cast_by_example(value, example):
     """
     a method that casts a value to the type of the parameter given as example
@@ -142,7 +144,8 @@ class Configuration(object):
     scanner_class = TcpScanner
     finger_classes = [SMBFinger, SSHFinger, PingScanner, HTTPFinger]
     exploiter_classes = [SmbExploiter, WmiExploiter, RdpExploiter, Ms08_067_Exploiter,  # Windows exploits
-                         SSHExploiter, ShellShockExploiter, SambaCryExploiter  # Linux
+                         SSHExploiter, ShellShockExploiter, SambaCryExploiter,  # Linux
+                         ElasticFinger,
                          ]
 
     # how many victims to look for in a single scan iteration
@@ -178,7 +181,7 @@ class Configuration(object):
 
     range_class = FixedRange
     range_size = 1
-    range_fixed = ['',]
+    range_fixed = ['', ]
 
     blocked_ips = ['', ]
 
@@ -186,7 +189,15 @@ class Configuration(object):
     HTTP_PORTS = [80, 8080, 443,
                   8008,  # HTTP alternate
                   ]
-    tcp_target_ports = [22, 2222, 445, 135, 3389]
+    tcp_target_ports = [22,
+                        445,
+                        135,
+                        3389,
+                        80,
+                        8080,
+                        443,
+                        8008,
+                        9200]
     tcp_target_ports.extend(HTTP_PORTS)
     tcp_scan_timeout = 3000  # 3000 Milliseconds
     tcp_scan_interval = 200
@@ -211,13 +222,17 @@ class Configuration(object):
     # User and password dictionaries for exploits.
 
     def get_exploit_user_password_pairs(self):
+        """
+        Returns all combinations of the configurations users and passwords
+        :return:
+        """
         return product(self.exploit_user_list, self.exploit_password_list)
 
     exploit_user_list = ['Administrator', 'root', 'user']
     exploit_password_list = ["Password1!", "1234", "password", "12345678"]
 
     # smb/wmi exploiter
-    smb_download_timeout = 300 # timeout in seconds
+    smb_download_timeout = 300  # timeout in seconds
     smb_service_name = "InfectionMonkey"
 
     # Timeout (in seconds) for sambacry's trigger to yield results.
@@ -243,7 +258,6 @@ class Configuration(object):
     # Monkey copy filename on share (64 bit)
     sambacry_monkey_copy_filename_64 = "monkey64_2"
 
-
     # system info collection
     collect_system_info = True
 
@@ -253,4 +267,5 @@ class Configuration(object):
 
     mimikatz_dll_name = "mk.dll"
 
+
 WormConfiguration = Configuration()
diff --git a/chaos_monkey/example.conf b/chaos_monkey/example.conf
index 4396cae34..982482cdf 100644
--- a/chaos_monkey/example.conf
+++ b/chaos_monkey/example.conf
@@ -39,6 +39,7 @@
         "SSHFinger",
         "PingScanner",
         "HTTPFinger",
+        "ElasticFinger",
         "SMBFinger"
     ],
     "max_iterations": 3,
@@ -83,7 +84,8 @@
         80,
         8080,
         443,
-        8008
+        8008,
+        9200
     ],
     "timeout_between_iterations": 10,
     "use_file_logging": true,
diff --git a/chaos_monkey/network/__init__.py b/chaos_monkey/network/__init__.py
index 850159342..8e31d3f11 100644
--- a/chaos_monkey/network/__init__.py
+++ b/chaos_monkey/network/__init__.py
@@ -23,5 +23,6 @@ from tcp_scanner import TcpScanner
 from smbfinger import SMBFinger
 from sshfinger import SSHFinger
 from httpfinger import HTTPFinger
+from elasticfinger import ElasticFinger
 from info import local_ips
 from info import get_free_tcp_port
diff --git a/chaos_monkey/network/elasticfinger.py b/chaos_monkey/network/elasticfinger.py
new file mode 100644
index 000000000..ea7bec14c
--- /dev/null
+++ b/chaos_monkey/network/elasticfinger.py
@@ -0,0 +1,48 @@
+import json
+import logging
+from contextlib import closing
+
+import requests
+from requests.exceptions import Timeout, ConnectionError
+
+from model.host import VictimHost
+from network import HostFinger
+
+ES_PORT = 9200
+ES_SERVICE = 'es-3306'
+
+LOG = logging.getLogger(__name__)
+__author__ = 'danielg'
+
+
+class ElasticFinger(HostFinger):
+    """
+        Fingerprints mysql databases, only on port 3306
+    """
+
+    def __init__(self):
+        self._config = __import__('config').WormConfiguration
+
+    def get_host_fingerprint(self, host):
+        """
+        Returns elasticsearch metadata
+        :param host:
+        :return: Success/failure, data is saved in the host struct
+        """
+        assert isinstance(host, VictimHost)
+        try:
+            url = 'http://%s:%s/' % (host.ip_addr, ES_PORT)
+            with closing(requests.get(url, timeout=1)) as req:
+                data = json.loads(req.text)
+                host.services[ES_SERVICE] = {}
+                host.services[ES_SERVICE]['name'] = 'ElasticSearch'
+                host.services[ES_SERVICE]['cluster_name'] = data['name']
+                host.services[ES_SERVICE]['version'] = data['version']['number']
+                return True
+        except Timeout:
+            LOG.debug("Got timeout while trying to read header information")
+        except ConnectionError:  # Someone doesn't like us
+            LOG.debug("Unknown connection error")
+        except KeyError:
+            LOG.debug("Failed parsing the ElasticSearch JSOn response")
+        return False

From 5ed6e37959263976bbba1107c43973646f6c6898 Mon Sep 17 00:00:00 2001
From: Daniel Goldberg <danielg@guardicore.com>
Date: Mon, 25 Sep 2017 15:32:01 +0300
Subject: [PATCH 3/9] Bug fix

---
 chaos_monkey/config.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/chaos_monkey/config.py b/chaos_monkey/config.py
index 7e5165cc8..81e583096 100644
--- a/chaos_monkey/config.py
+++ b/chaos_monkey/config.py
@@ -142,10 +142,9 @@ class Configuration(object):
     max_iterations = 1
 
     scanner_class = TcpScanner
-    finger_classes = [SMBFinger, SSHFinger, PingScanner, HTTPFinger]
+    finger_classes = [SMBFinger, SSHFinger, PingScanner, HTTPFinger, ElasticFinger, ]
     exploiter_classes = [SmbExploiter, WmiExploiter, RdpExploiter, Ms08_067_Exploiter,  # Windows exploits
                          SSHExploiter, ShellShockExploiter, SambaCryExploiter,  # Linux
-                         ElasticFinger,
                          ]
 
     # how many victims to look for in a single scan iteration

From d5f6812a080f5a792f05654635770c567c2a37fd Mon Sep 17 00:00:00 2001
From: Daniel Goldberg <danielg@guardicore.com>
Date: Mon, 25 Sep 2017 15:32:13 +0300
Subject: [PATCH 4/9] Fix permission bug to work in non admin contexts.

---
 chaos_monkey/system_info/__init__.py | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/chaos_monkey/system_info/__init__.py b/chaos_monkey/system_info/__init__.py
index b9a16d459..c95caa444 100644
--- a/chaos_monkey/system_info/__init__.py
+++ b/chaos_monkey/system_info/__init__.py
@@ -78,7 +78,19 @@ class InfoCollector(object):
                                           "cmdline": "ACCESS DENIED",
                                           "full_image_path": "null",
                                           }
-                pass
+                continue
+            except WindowsError:
+                # we may be running as non root
+                # and some processes are impossible to acquire in Windows/Linux
+                # in this case we'll just add what we can
+                processes[process.pid] = {"name": "null",
+                                          "pid": process.pid,
+                                          "ppid": process.ppid(),
+                                          "cmdline": "ACCESS DENIED",
+                                          "full_image_path": "null",
+                                          }
+                continue
+
         self.info['process_list'] = processes
 
     def get_network_info(self):

From 79e6a440081dbb18a450d9f6f397a2b2acbd1cb7 Mon Sep 17 00:00:00 2001
From: Daniel Goldberg <danielg@guardicore.com>
Date: Mon, 25 Sep 2017 17:34:19 +0300
Subject: [PATCH 5/9] Fix CR comments, see
 https://github.com/guardicore/monkey/pull/47#pullrequestreview-64871377

---
 chaos_monkey/config.py              | 22 ++++++++++++----------
 chaos_monkey/example.conf           |  1 +
 chaos_monkey/network/mysqlfinger.py | 21 ++++++++++++++-------
 chaos_monkey/network/tools.py       |  3 +--
 4 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/chaos_monkey/config.py b/chaos_monkey/config.py
index b0f615552..33c514190 100644
--- a/chaos_monkey/config.py
+++ b/chaos_monkey/config.py
@@ -1,13 +1,14 @@
 import os
 import sys
-from network.range import FixedRange, RelativeRange, ClassCRange
-from exploit import WmiExploiter, Ms08_067_Exploiter, SmbExploiter, RdpExploiter, SSHExploiter, ShellShockExploiter,\
-    SambaCryExploiter
-from network import TcpScanner, PingScanner, SMBFinger, SSHFinger, HTTPFinger, MySQLFinger
+import types
+import uuid
 from abc import ABCMeta
 from itertools import product
-import uuid
-import types
+
+from exploit import WmiExploiter, Ms08_067_Exploiter, SmbExploiter, RdpExploiter, SSHExploiter, ShellShockExploiter, \
+    SambaCryExploiter
+from network import TcpScanner, PingScanner, SMBFinger, SSHFinger, HTTPFinger, MySQLFinger
+from network.range import FixedRange
 
 __author__ = 'itamar'
 
@@ -15,6 +16,7 @@ GUID = str(uuid.getnode())
 
 EXTERNAL_CONFIG_FILE = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), 'monkey.bin')
 
+
 def _cast_by_example(value, example):
     """
     a method that casts a value to the type of the parameter given as example
@@ -178,7 +180,7 @@ class Configuration(object):
 
     range_class = FixedRange
     range_size = 1
-    range_fixed = ['',]
+    range_fixed = ['10.0.1.63', ]
 
     blocked_ips = ['', ]
 
@@ -186,7 +188,7 @@ class Configuration(object):
     HTTP_PORTS = [80, 8080, 443,
                   8008,  # HTTP alternate
                   ]
-    tcp_target_ports = [22, 2222, 445, 135, 3389]
+    tcp_target_ports = [22, 2222, 445, 135, 3389, 3306, ]
     tcp_target_ports.extend(HTTP_PORTS)
     tcp_scan_timeout = 3000  # 3000 Milliseconds
     tcp_scan_interval = 200
@@ -217,7 +219,7 @@ class Configuration(object):
     exploit_password_list = ["Password1!", "1234", "password", "12345678"]
 
     # smb/wmi exploiter
-    smb_download_timeout = 300 # timeout in seconds
+    smb_download_timeout = 300  # timeout in seconds
     smb_service_name = "InfectionMonkey"
 
     # Timeout (in seconds) for sambacry's trigger to yield results.
@@ -243,7 +245,6 @@ class Configuration(object):
     # Monkey copy filename on share (64 bit)
     sambacry_monkey_copy_filename_64 = "monkey64_2"
 
-
     # system info collection
     collect_system_info = True
 
@@ -253,4 +254,5 @@ class Configuration(object):
 
     mimikatz_dll_name = "mk.dll"
 
+
 WormConfiguration = Configuration()
diff --git a/chaos_monkey/example.conf b/chaos_monkey/example.conf
index 55a716c7c..6ef9558ae 100644
--- a/chaos_monkey/example.conf
+++ b/chaos_monkey/example.conf
@@ -84,6 +84,7 @@
         80,
         8080,
         443,
+        3306,
         8008
     ],
     "timeout_between_iterations": 10,
diff --git a/chaos_monkey/network/mysqlfinger.py b/chaos_monkey/network/mysqlfinger.py
index 0bda6c5ac..39baa05ac 100644
--- a/chaos_monkey/network/mysqlfinger.py
+++ b/chaos_monkey/network/mysqlfinger.py
@@ -1,8 +1,9 @@
-import socket
 import logging
+import socket
+
+from model.host import VictimHost
 from network import HostFinger
 from .tools import struct_unpack_tracker, struct_unpack_tracker_string
-from model.host import VictimHost
 
 MYSQL_PORT = 3306
 SQL_SERVICE = 'mysqld-3306'
@@ -15,6 +16,9 @@ class MySQLFinger(HostFinger):
         Fingerprints mysql databases, only on port 3306
     """
 
+    SOCKET_TIMEOUT = 0.5
+    HEADER_SIZE = 4  # in bytes
+
     def __init__(self):
         self._config = __import__('config').WormConfiguration
 
@@ -26,15 +30,15 @@ class MySQLFinger(HostFinger):
         """
         assert isinstance(host, VictimHost)
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        s.settimeout(0.5)
+        s.settimeout(self.SOCKET_TIMEOUT)
 
         try:
             s.connect((host.ip_addr, MYSQL_PORT))
-            header = s.recv(4)  # max header size?
+            header = s.recv(self.HEADER_SIZE)  # max header size?
 
-            tmp, curpos = struct_unpack_tracker(header, 0, "I")
-            tmp = tmp[0]
-            response_length = tmp & 0xff
+            response, curpos = struct_unpack_tracker(header, 0, "I")
+            response = response[0]
+            response_length = response & 0xff  # first byte is significant
             data = s.recv(response_length)
             # now we can start parsing
             protocol, curpos = struct_unpack_tracker(data, 0, "B")
@@ -47,6 +51,7 @@ class MySQLFinger(HostFinger):
 
             version, curpos = struct_unpack_tracker_string(data, curpos)  # special coded to solve string parsing
             version = version[0]
+            host.services[SQL_SERVICE] = {}
             host.services[SQL_SERVICE]['version'] = version
             version = version.split('-')[0].split('.')
             host.services[SQL_SERVICE]['major_version'] = version[0]
@@ -54,6 +59,8 @@ class MySQLFinger(HostFinger):
             host.services[SQL_SERVICE]['build_version'] = version[2]
             thread_id, curpos = struct_unpack_tracker(data, curpos, "<I")  # ignore thread id
 
+            # protocol parsing taken from
+            # https://nmap.org/nsedoc/scripts/mysql-info.html
             if protocol == 10:
                 # new protocol
                 self._parse_protocol_10(curpos, data, host)
diff --git a/chaos_monkey/network/tools.py b/chaos_monkey/network/tools.py
index 3d7fe64ef..66f4eef57 100644
--- a/chaos_monkey/network/tools.py
+++ b/chaos_monkey/network/tools.py
@@ -32,8 +32,7 @@ def struct_unpack_tracker_string(data, index):
     """
     ascii_len = data[index:].find('\0')
     fmt = "%ds" % ascii_len
-    unpacked = struct.unpack_from(fmt, data, index)
-    return unpacked, struct.calcsize(fmt)
+    return struct_unpack_tracker(data,index,fmt)
 
 
 def check_port_tcp(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):

From f3a172fc4af308389be75fa26a6a453d74ce7e8d Mon Sep 17 00:00:00 2001
From: Daniel Goldberg <danielg@guardicore.com>
Date: Mon, 25 Sep 2017 18:02:21 +0300
Subject: [PATCH 6/9] Fixed CR notes
 https://github.com/guardicore/monkey/pull/48#pullrequestreview-64914540

---
 chaos_monkey/config.py                |  1 +
 chaos_monkey/network/elasticfinger.py | 11 ++++++-----
 chaos_monkey/system_info/__init__.py  | 19 +++++--------------
 3 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/chaos_monkey/config.py b/chaos_monkey/config.py
index 81e583096..e5a7d736a 100644
--- a/chaos_monkey/config.py
+++ b/chaos_monkey/config.py
@@ -189,6 +189,7 @@ class Configuration(object):
                   8008,  # HTTP alternate
                   ]
     tcp_target_ports = [22,
+                        2222,
                         445,
                         135,
                         3389,
diff --git a/chaos_monkey/network/elasticfinger.py b/chaos_monkey/network/elasticfinger.py
index ea7bec14c..8c21887ee 100644
--- a/chaos_monkey/network/elasticfinger.py
+++ b/chaos_monkey/network/elasticfinger.py
@@ -9,15 +9,15 @@ from model.host import VictimHost
 from network import HostFinger
 
 ES_PORT = 9200
-ES_SERVICE = 'es-3306'
-
+ES_SERVICE = 'elastic-seach-3306'
+ES_HTTP_TIMEOUT = 5
 LOG = logging.getLogger(__name__)
 __author__ = 'danielg'
 
 
 class ElasticFinger(HostFinger):
     """
-        Fingerprints mysql databases, only on port 3306
+        Fingerprints elastic search clusters, only on port 3306
     """
 
     def __init__(self):
@@ -32,11 +32,12 @@ class ElasticFinger(HostFinger):
         assert isinstance(host, VictimHost)
         try:
             url = 'http://%s:%s/' % (host.ip_addr, ES_PORT)
-            with closing(requests.get(url, timeout=1)) as req:
+            with closing(requests.get(url, timeout=ES_HTTP_TIMEOUT)) as req:
                 data = json.loads(req.text)
                 host.services[ES_SERVICE] = {}
                 host.services[ES_SERVICE]['name'] = 'ElasticSearch'
-                host.services[ES_SERVICE]['cluster_name'] = data['name']
+                host.services[ES_SERVICE]['cluster_name'] = data['cluster_name']
+                host.services[ES_SERVICE]['name'] = data['name']
                 host.services[ES_SERVICE]['version'] = data['version']['number']
                 return True
         except Timeout:
diff --git a/chaos_monkey/system_info/__init__.py b/chaos_monkey/system_info/__init__.py
index c95caa444..ddf13d885 100644
--- a/chaos_monkey/system_info/__init__.py
+++ b/chaos_monkey/system_info/__init__.py
@@ -1,8 +1,10 @@
-import sys
 import socket
+import sys
+
 import psutil
 from enum import IntEnum
-from network.info import get_host_subnets, local_ips
+
+from network.info import get_host_subnets
 
 __author__ = 'uri'
 
@@ -68,18 +70,7 @@ class InfoCollector(object):
                                           "cmdline": " ".join(process.cmdline()),
                                           "full_image_path": process.exe(),
                                           }
-            except psutil.AccessDenied:
-                # we may be running as non root
-                # and some processes are impossible to acquire in Windows/Linux
-                # in this case we'll just add what we can
-                processes[process.pid] = {"name": "null",
-                                          "pid": process.pid,
-                                          "ppid": process.ppid(),
-                                          "cmdline": "ACCESS DENIED",
-                                          "full_image_path": "null",
-                                          }
-                continue
-            except WindowsError:
+            except (psutil.AccessDenied, WindowsError):
                 # we may be running as non root
                 # and some processes are impossible to acquire in Windows/Linux
                 # in this case we'll just add what we can

From 8bace9794a3bdc9763c6d3ae9671989ff6dcc65f Mon Sep 17 00:00:00 2001
From: Daniel Goldberg <danielg@guardicore.com>
Date: Mon, 25 Sep 2017 18:07:26 +0300
Subject: [PATCH 7/9] Update config.py

---
 chaos_monkey/config.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/chaos_monkey/config.py b/chaos_monkey/config.py
index 33c514190..e1ebfcdcd 100644
--- a/chaos_monkey/config.py
+++ b/chaos_monkey/config.py
@@ -180,7 +180,7 @@ class Configuration(object):
 
     range_class = FixedRange
     range_size = 1
-    range_fixed = ['10.0.1.63', ]
+    range_fixed = ['', ]
 
     blocked_ips = ['', ]
 

From bd279446fed65ac28480e6c4e492598e7a49d96b Mon Sep 17 00:00:00 2001
From: itaymmguardicore <30774653+itaymmguardicore@users.noreply.github.com>
Date: Mon, 25 Sep 2017 18:15:14 +0300
Subject: [PATCH 8/9] Update elasticfinger.py

---
 chaos_monkey/network/elasticfinger.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/chaos_monkey/network/elasticfinger.py b/chaos_monkey/network/elasticfinger.py
index 8c21887ee..28710ca80 100644
--- a/chaos_monkey/network/elasticfinger.py
+++ b/chaos_monkey/network/elasticfinger.py
@@ -9,7 +9,7 @@ from model.host import VictimHost
 from network import HostFinger
 
 ES_PORT = 9200
-ES_SERVICE = 'elastic-seach-3306'
+ES_SERVICE = 'elastic-search-3306'
 ES_HTTP_TIMEOUT = 5
 LOG = logging.getLogger(__name__)
 __author__ = 'danielg'

From 192c24f6d4205e92c03c28c108cfed7fc815004f Mon Sep 17 00:00:00 2001
From: itaymmguardicore <30774653+itaymmguardicore@users.noreply.github.com>
Date: Mon, 25 Sep 2017 18:17:51 +0300
Subject: [PATCH 9/9] Update elasticfinger.py

---
 chaos_monkey/network/elasticfinger.py | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/chaos_monkey/network/elasticfinger.py b/chaos_monkey/network/elasticfinger.py
index 28710ca80..730decf4f 100644
--- a/chaos_monkey/network/elasticfinger.py
+++ b/chaos_monkey/network/elasticfinger.py
@@ -9,7 +9,7 @@ from model.host import VictimHost
 from network import HostFinger
 
 ES_PORT = 9200
-ES_SERVICE = 'elastic-search-3306'
+ES_SERVICE = 'elastic-search-9200'
 ES_HTTP_TIMEOUT = 5
 LOG = logging.getLogger(__name__)
 __author__ = 'danielg'
@@ -17,7 +17,7 @@ __author__ = 'danielg'
 
 class ElasticFinger(HostFinger):
     """
-        Fingerprints elastic search clusters, only on port 3306
+        Fingerprints elastic search clusters, only on port 9200
     """
 
     def __init__(self):
@@ -35,7 +35,6 @@ class ElasticFinger(HostFinger):
             with closing(requests.get(url, timeout=ES_HTTP_TIMEOUT)) as req:
                 data = json.loads(req.text)
                 host.services[ES_SERVICE] = {}
-                host.services[ES_SERVICE]['name'] = 'ElasticSearch'
                 host.services[ES_SERVICE]['cluster_name'] = data['cluster_name']
                 host.services[ES_SERVICE]['name'] = data['name']
                 host.services[ES_SERVICE]['version'] = data['version']['number']