Skip to content

Commit

Permalink
Merge branch 'attack_comand_line_interface' into attack_powershell
Browse files Browse the repository at this point in the history
# Conflicts:
#	monkey/infection_monkey/exploit/__init__.py
#	monkey/infection_monkey/exploit/hadoop.py
#	monkey/monkey_island/cc/services/attack/attack_report.py
  • Loading branch information
VakarisZ committed Jun 25, 2019
2 parents c4c53f7 + 36f917b commit fea8567
Show file tree
Hide file tree
Showing 30 changed files with 93 additions and 80 deletions.
4 changes: 2 additions & 2 deletions monkey/infection_monkey/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@ def keepalive():
return {}

@staticmethod
def send_telemetry(telem_catagory, data):
def send_telemetry(telem_category, data):
if not WormConfiguration.current_server:
return
try:
telemetry = {'monkey_guid': GUID, 'telem_catagory': telem_catagory, 'data': data}
telemetry = {'monkey_guid': GUID, 'telem_category': telem_category, 'data': data}
reply = requests.post("https://%s/api/telemetry" % (WormConfiguration.current_server,),
data=json.dumps(telemetry),
headers={'content-type': 'application/json'},
Expand Down
29 changes: 19 additions & 10 deletions monkey/infection_monkey/exploit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, host):
'finished': '',
'vulnerable_urls': [],
'vulnerable_ports': [],
'executed_cmds': {}}
'executed_cmds': []}
self._exploit_attempts = []
self.host = host

Expand All @@ -49,8 +49,20 @@ def report_login_attempt(self, result, user, password='', lm_hash='', ntlm_hash=
self._exploit_attempts.append({'result': result, 'user': user, 'password': password,
'lm_hash': lm_hash, 'ntlm_hash': ntlm_hash, 'ssh_key': ssh_key})

@abstractmethod
def exploit_host(self):
self.pre_exploit()
result = self._exploit_host()
self.post_exploit()
return result

def pre_exploit(self):
self.set_start_time()

def post_exploit(self):
self.set_finish_time()

@abstractmethod
def _exploit_host(self):
raise NotImplementedError()

def add_vuln_url(self, url):
Expand All @@ -59,16 +71,13 @@ def add_vuln_url(self, url):
def add_vuln_port(self, port):
self._exploit_info['vulnerable_ports'].append(port)

def set_example_cmd(self, cmd):
powershell = True if "powershell" in cmd.lower() else False
self._exploit_info['executed_cmds']['example'].append({'command': cmd, 'powershell': powershell})

def add_powershell_cmd(self, cmd):
def add_executed_cmd(self, cmd):
"""
Determines if command uses powershell and if so adds that command to exploiter info
:param cmd: Command used
:return: None
Appends command to exploiter's info.
:param cmd: String of executed command. e.g. 'echo Example'
"""
powershell = True if "powershell" in cmd.lower() else False
self._exploit_info['executed_cmds'].append({'cmd': cmd, 'powershell': powershell})


from infection_monkey.exploit.win_ms08_067 import Ms08_067_Exploiter
Expand Down
5 changes: 2 additions & 3 deletions monkey/infection_monkey/exploit/hadoop.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class HadoopExploiter(WebRCE):
def __init__(self, host):
super(HadoopExploiter, self).__init__(host)

def exploit_host(self):
def _exploit_host(self):
# Try to get exploitable url
urls = self.build_potential_urls(self.HADOOP_PORTS)
self.add_vulnerable_urls(urls, True)
Expand All @@ -49,8 +49,7 @@ def exploit_host(self):
return False
http_thread.join(self.DOWNLOAD_TIMEOUT)
http_thread.stop()
self.add_powershell_cmd(command)
self.set_example_cmd(command)
self.add_executed_cmd(command)
return True

def exploit(self, url, command):
Expand Down
4 changes: 2 additions & 2 deletions monkey/infection_monkey/exploit/mssqlexec.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class MSSQLExploiter(HostExploiter):
def __init__(self, host):
super(MSSQLExploiter, self).__init__(host)

def exploit_host(self):
def _exploit_host(self):
# Brute force to get connection
username_passwords_pairs_list = self._config.get_exploit_user_password_pairs()
cursor = self.brute_force(self.host.ip_addr, self.SQL_DEFAULT_TCP_PORT, username_passwords_pairs_list)
Expand Down Expand Up @@ -77,7 +77,7 @@ def exploit_host(self):
commands.extend(monkey_args)
MSSQLExploiter.execute_command(cursor, commands)
MSSQLExploiter.run_file(cursor, tmp_file_path)
self.set_example_cmd(commands[-1])
self.add_executed_cmd(commands[-1])
return True

@staticmethod
Expand Down
4 changes: 2 additions & 2 deletions monkey/infection_monkey/exploit/rdpgrinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def is_os_supported(self):
return True
return False

def exploit_host(self):
def _exploit_host(self):
global g_reactor

is_open, _ = check_tcp_port(self.host.ip_addr, RDP_PORT)
Expand Down Expand Up @@ -343,5 +343,5 @@ def exploit_host(self):

LOG.info("Executed monkey '%s' on remote victim %r",
os.path.basename(src_path), self.host)
self.set_example_cmd(command)
self.add_executed_cmd(command)
return True
2 changes: 1 addition & 1 deletion monkey/infection_monkey/exploit/sambacry.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class SambaCryExploiter(HostExploiter):
def __init__(self, host):
super(SambaCryExploiter, self).__init__(host)

def exploit_host(self):
def _exploit_host(self):
if not self.is_vulnerable():
return False

Expand Down
4 changes: 2 additions & 2 deletions monkey/infection_monkey/exploit/shellshock.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __init__(self, host):
) for _ in range(20))
self.skip_exist = self._config.skip_exploit_if_file_exist

def exploit_host(self):
def _exploit_host(self):
# start by picking ports
candidate_services = {
service: self.host.services[service] for service in self.host.services if
Expand Down Expand Up @@ -144,7 +144,7 @@ def exploit_host(self):
if not (self.check_remote_file_exists(url, header, exploit, self._config.monkey_log_path_linux)):
LOG.info("Log file does not exist, monkey might not have run")
continue
self.set_example_cmd(cmdline)
self.add_executed_cmd(cmdline)
return True

return False
Expand Down
2 changes: 1 addition & 1 deletion monkey/infection_monkey/exploit/smbexec.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def is_os_supported(self):
return self.host.os.get('type') in self._TARGET_OS_TYPE
return False

def exploit_host(self):
def _exploit_host(self):
src_path = get_target_monkey(self.host)

if not src_path:
Expand Down
4 changes: 2 additions & 2 deletions monkey/infection_monkey/exploit/sshexec.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def exploit_with_login_creds(self, port, ssh):
continue
return exploited

def exploit_host(self):
def _exploit_host(self):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.WarningPolicy())

Expand Down Expand Up @@ -178,7 +178,7 @@ def exploit_host(self):
self._config.dropper_target_path_linux, self.host, cmdline)

ssh.close()
self.set_example_cmd(cmdline)
self.add_executed_cmd(cmdline)
return True

except Exception as exc:
Expand Down
4 changes: 2 additions & 2 deletions monkey/infection_monkey/exploit/vsftpd.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def socket_send(self, s, message):
LOG.error('Failed to send payload to %s', self.host.ip_addr)
return False

def exploit_host(self):
def _exploit_host(self):
LOG.info("Attempting to trigger the Backdoor..")
ftp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Expand Down Expand Up @@ -138,7 +138,7 @@ def exploit_host(self):
if backdoor_socket.send(run_monkey):
LOG.info("Executed monkey '%s' on remote victim %r (cmdline=%r)", self._config.dropper_target_path_linux,
self.host, run_monkey)
self.set_example_cmd(run_monkey)
self.add_executed_cmd(run_monkey)
return True
else:
return False
6 changes: 3 additions & 3 deletions monkey/infection_monkey/exploit/web_rce.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def get_exploit_config(self):

return exploit_config

def exploit_host(self):
def _exploit_host(self):
"""
Method that contains default exploitation workflow
:return: True if exploited, False otherwise
Expand Down Expand Up @@ -408,7 +408,7 @@ def execute_remote_monkey(self, url, path, dropper=False):
# If exploiter returns True / False
if type(resp) is bool:
LOG.info("Execution attempt successfully finished")
self.set_example_cmd(command)
self.add_executed_cmd(command)
return resp
# If exploiter returns command output, we can check for execution errors
if 'is not recognized' in resp or 'command not found' in resp:
Expand All @@ -422,7 +422,7 @@ def execute_remote_monkey(self, url, path, dropper=False):
return False
LOG.info("Execution attempt finished")

self.set_example_cmd(command)
self.add_executed_cmd(command)
return resp

def get_monkey_upload_path(self, url_to_monkey):
Expand Down
2 changes: 1 addition & 1 deletion monkey/infection_monkey/exploit/win_ms08_067.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def is_os_supported(self):
self.host.os.get('version') in self._windows_versions.keys()
return False

def exploit_host(self):
def _exploit_host(self):
src_path = get_target_monkey(self.host)

if not src_path:
Expand Down
4 changes: 2 additions & 2 deletions monkey/infection_monkey/exploit/wmiexec.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self, host):
super(WmiExploiter, self).__init__(host)

@WmiTools.dcom_wrap
def exploit_host(self):
def _exploit_host(self):
src_path = get_target_monkey(self.host)

if not src_path:
Expand Down Expand Up @@ -114,7 +114,7 @@ def exploit_host(self):

result.RemRelease()
wmi_connection.close()
self.set_example_cmd(cmdline)
self.add_executed_cmd(cmdline)
return success

return False
2 changes: 0 additions & 2 deletions monkey/infection_monkey/monkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,7 @@ def try_exploiting(self, machine, exploiter):

result = False
try:
exploiter.set_start_time()
result = exploiter.exploit_host()
exploiter.set_finish_time()
if result:
self.successfully_exploited(machine, exploiter)
return True
Expand Down
2 changes: 1 addition & 1 deletion monkey/infection_monkey/telemetry/attack/attack_telem.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def __init__(self, technique, status):
self.technique = technique
self.status = status

telem_catagory = 'attack'
telem_category = 'attack'

def get_data(self):
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_get_data(self):

telem = VictimHostTelem(technique, status, machine)

self.assertEqual(telem.telem_catagory, 'attack')
self.assertEqual(telem.telem_category, 'attack')

expected_data = {
'machine': {
Expand Down
4 changes: 2 additions & 2 deletions monkey/infection_monkey/telemetry/base_telem.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ def send(self):
"""
Sends telemetry to island
"""
ControlClient.send_telemetry(self.telem_catagory, self.get_data())
ControlClient.send_telemetry(self.telem_category, self.get_data())

@abc.abstractproperty
def telem_catagory(self):
def telem_category(self):
"""
:return: Telemetry type
"""
Expand Down
9 changes: 6 additions & 3 deletions monkey/infection_monkey/transport/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def do_GET(self):
start_range += chunk

if f.tell() == monkeyfs.getsize(self.filename):
self.report_download(self.client_address)
if self.report_download(self.client_address):
self.close_connection = 1

f.close()

Expand Down Expand Up @@ -171,7 +172,8 @@ def report_download(dest=None):
LOG.info('File downloaded from (%s,%s)' % (dest[0], dest[1]))
self.downloads += 1
if not self.downloads < self.max_downloads:
self.close_connection = 1
return True
return False

httpd = BaseHTTPServer.HTTPServer((self._local_ip, self._local_port), TempHandler)
httpd.timeout = 0.5 # this is irrelevant?
Expand Down Expand Up @@ -217,7 +219,8 @@ def report_download(dest=None):
LOG.info('File downloaded from (%s,%s)' % (dest[0], dest[1]))
self.downloads += 1
if not self.downloads < self.max_downloads:
self.close_connection = 1
return True
return False

httpd = BaseHTTPServer.HTTPServer((self._local_ip, self._local_port), TempHandler)
self.lock.release()
Expand Down
4 changes: 2 additions & 2 deletions monkey/monkey_island/cc/resources/monkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def post(self, **kw):
parent_to_add = (monkey_json.get('guid'), None) # default values in case of manual run
if parent and parent != monkey_json.get('guid'): # current parent is known
exploit_telem = [x for x in
mongo.db.telemetry.find({'telem_catagory': {'$eq': 'exploit'}, 'data.result': {'$eq': True},
mongo.db.telemetry.find({'telem_category': {'$eq': 'exploit'}, 'data.result': {'$eq': True},
'data.machine.ip_addr': {'$in': monkey_json['ip_addresses']},
'monkey_guid': {'$eq': parent}})]
if 1 == len(exploit_telem):
Expand All @@ -104,7 +104,7 @@ def post(self, **kw):
parent_to_add = (parent, None)
elif (not parent or parent == monkey_json.get('guid')) and 'ip_addresses' in monkey_json:
exploit_telem = [x for x in
mongo.db.telemetry.find({'telem_catagory': {'$eq': 'exploit'}, 'data.result': {'$eq': True},
mongo.db.telemetry.find({'telem_category': {'$eq': 'exploit'}, 'data.result': {'$eq': True},
'data.machine.ip_addr': {'$in': monkey_json['ip_addresses']}})]

if 1 == len(exploit_telem):
Expand Down
16 changes: 8 additions & 8 deletions monkey/monkey_island/cc/resources/telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Telemetry(flask_restful.Resource):
@jwt_required()
def get(self, **kw):
monkey_guid = request.args.get('monkey_guid')
telem_catagory = request.args.get('telem_catagory')
telem_category = request.args.get('telem_category')
timestamp = request.args.get('timestamp')
if "null" == timestamp: # special case to avoid ugly JS code...
timestamp = None
Expand All @@ -36,8 +36,8 @@ def get(self, **kw):

if monkey_guid:
find_filter["monkey_guid"] = {'$eq': monkey_guid}
if telem_catagory:
find_filter["telem_catagory"] = {'$eq': telem_catagory}
if telem_category:
find_filter["telem_category"] = {'$eq': telem_category}
if timestamp:
find_filter['timestamp'] = {'$gt': dateutil.parser.parse(timestamp)}

Expand All @@ -53,11 +53,11 @@ def post(self):

try:
NodeService.update_monkey_modify_time(monkey["_id"])
telem_catagory = telemetry_json.get('telem_catagory')
if telem_catagory in TELEM_PROCESS_DICT:
TELEM_PROCESS_DICT[telem_catagory](telemetry_json)
telem_category = telemetry_json.get('telem_category')
if telem_category in TELEM_PROCESS_DICT:
TELEM_PROCESS_DICT[telem_category](telemetry_json)
else:
logger.info('Got unknown type of telemetry: %s' % telem_catagory)
logger.info('Got unknown type of telemetry: %s' % telem_category)
except Exception as ex:
logger.error("Exception caught while processing telemetry", exc_info=True)

Expand All @@ -79,7 +79,7 @@ def telemetry_to_displayed_telemetry(telemetry):
monkey_label = telem_monkey_guid
x["monkey"] = monkey_label
objects.append(x)
if x['telem_catagory'] == 'system_info_collection' and 'credentials' in x['data']:
if x['telem_category'] == 'system_info_collection' and 'credentials' in x['data']:
for user in x['data']['credentials']:
if -1 != user.find(','):
new_user = user.replace(',', '.')
Expand Down
2 changes: 1 addition & 1 deletion monkey/monkey_island/cc/resources/telemetry_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def get_displayed_telemetry(telem):
'id': telem['_id'],
'timestamp': telem['timestamp'].strftime('%d/%m/%Y %H:%M:%S'),
'hostname': monkey.get('hostname', default_hostname) if monkey else default_hostname,
'brief': TELEM_PROCESS_DICT[telem['telem_catagory']](telem)
'brief': TELEM_PROCESS_DICT[telem['telem_category']](telem)
}

@staticmethod
Expand Down
Loading

0 comments on commit fea8567

Please sign in to comment.