Skip to content

Commit f6da539

Browse files
committed
feat: support mutant
1 parent 8a01589 commit f6da539

File tree

2 files changed

+107
-6
lines changed

2 files changed

+107
-6
lines changed

client/command/mutant/commands.go

Lines changed: 106 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,26 @@ import (
1414
)
1515

1616
func Commands(con *core.Console) []*cobra.Command {
17+
// Create mutant parent command
18+
mutantCmd := &cobra.Command{
19+
Use: "mutant",
20+
Short: "Malefic-mutant tools for PE/DLL manipulation",
21+
Long: "Tools for converting DLL to shellcode, stripping binaries, and PE signature manipulation",
22+
RunE: func(cmd *cobra.Command, args []string) error {
23+
return cmd.Help()
24+
},
25+
}
26+
27+
// Donut command - standalone, not under mutant
1728
donutCmd := &cobra.Command{
1829
Use: consts.CommandDonut,
1930
Short: "donut cmd",
2031
Long: "Generates x86, x64, or AMD64+x86 position-independent shellcode that loads .NET Assemblies, PE files, and other Windows payloads from memory ",
2132
Example: `
22-
gonut -i c2.dll
23-
gonut --arch x86 --class TestClass --method RunProcess --args notepad.exe --input loader.dll
24-
gonut -i loader.dll -c TestClass -m RunProcess -p "calc notepad" -s http://remote_server.com/modules/
25-
gonut -z2 -k2 -t -i loader.exe -o out.bin
33+
donut -i c2.dll
34+
donut --arch x86 --class TestClass --method RunProcess --args notepad.exe --input loader.dll
35+
donut -i loader.dll -c TestClass -m RunProcess -p "calc notepad" -s http://remote_server.com/modules/
36+
donut -z2 -k2 -t -i loader.exe -o out.bin
2637
`,
2738
RunE: func(cmd *cobra.Command, args []string) error {
2839
return DonutCmd(cmd, con)
@@ -110,7 +121,97 @@ func Commands(con *core.Console) []*cobra.Command {
110121
common.BindFlagCompletions(donutCmd, func(comp carapace.ActionMap) {
111122
comp["input"] = carapace.ActionFiles().Usage("file path")
112123
})
113-
return []*cobra.Command{donutCmd}
124+
125+
// SRDI command - DLL to Shellcode
126+
srdiCmd := &cobra.Command{
127+
Use: "srdi",
128+
Short: "Convert DLL to shellcode using SRDI",
129+
Long: "Generate SRDI shellcode from DLL files with support for TLS",
130+
Example: `
131+
mutant srdi -i beacon.dll -o beacon.bin
132+
mutant srdi -i beacon.dll -a x64 --function-name ReflectiveLoader
133+
mutant srdi -i beacon.dll -t malefic --userdata-path userdata.bin
134+
`,
135+
RunE: func(cmd *cobra.Command, args []string) error {
136+
return SrdiCmd(cmd, con)
137+
},
138+
}
139+
common.BindFlag(srdiCmd, func(f *pflag.FlagSet) {
140+
f.StringP("input", "i", "", "Source DLL file path")
141+
f.StringP("output", "o", "", "Target shellcode path (default: <input>.bin)")
142+
f.StringP("arch", "a", "x64", "Architecture: x86 or x64")
143+
f.StringP("function-name", "", "", "Function name")
144+
f.StringP("platform", "p", "win", "Platform: win")
145+
f.StringP("type", "t", "malefic", "SRDI type: link (no TLS) or malefic (with TLS)")
146+
f.StringP("userdata-path", "", "", "User data file path")
147+
f.SortFlags = false
148+
})
149+
common.BindFlagCompletions(srdiCmd, func(comp carapace.ActionMap) {
150+
comp["input"] = carapace.ActionFiles().Usage("DLL file path")
151+
comp["output"] = carapace.ActionFiles().Usage("output file path")
152+
comp["userdata-path"] = carapace.ActionFiles().Usage("userdata file path")
153+
})
154+
155+
// Strip command - Remove paths from binary
156+
stripCmd := &cobra.Command{
157+
Use: "strip",
158+
Short: "Strip paths from binary files",
159+
Long: "Remove build paths and other sensitive information from binary files",
160+
Example: `
161+
mutant strip -i malefic.exe -o malefic-stripped.exe
162+
mutant strip -i malefic.exe --custom-paths /home/user,/opt/build
163+
`,
164+
RunE: func(cmd *cobra.Command, args []string) error {
165+
return StripCmd(cmd, con)
166+
},
167+
}
168+
common.BindFlag(stripCmd, func(f *pflag.FlagSet) {
169+
f.StringP("input", "i", "", "Source binary file path")
170+
f.StringP("output", "o", "", "Output binary file path (default: <input>.stripped)")
171+
f.StringP("custom-paths", "", "", "Additional custom paths to replace (comma separated)")
172+
f.SortFlags = false
173+
})
174+
common.BindFlagCompletions(stripCmd, func(comp carapace.ActionMap) {
175+
comp["input"] = carapace.ActionFiles().Usage("binary file path")
176+
comp["output"] = carapace.ActionFiles().Usage("output file path")
177+
})
178+
179+
// Sigforge command - PE signature manipulation
180+
sigforgeCmd := &cobra.Command{
181+
Use: "sigforge",
182+
Short: "PE file signature manipulation tool",
183+
Long: "Extract, copy, inject, remove, or check PE file signatures",
184+
Example: `
185+
mutant sigforge --operation extract --source signed.exe --output signature.bin
186+
mutant sigforge --operation copy --source signed.exe --target unsigned.exe --output result.exe
187+
mutant sigforge --operation inject --source unsigned.exe --signature signature.bin --output signed.exe
188+
mutant sigforge --operation remove --source signed.exe --output unsigned.exe
189+
mutant sigforge --operation check --source target.exe
190+
`,
191+
RunE: func(cmd *cobra.Command, args []string) error {
192+
return SigforgeCmd(cmd, con)
193+
},
194+
}
195+
common.BindFlag(sigforgeCmd, func(f *pflag.FlagSet) {
196+
f.StringP("operation", "", "", "Operation: extract, copy, inject, remove, or check")
197+
f.StringP("source", "s", "", "Source PE file")
198+
f.StringP("target", "t", "", "Target PE file (for copy operation)")
199+
f.StringP("signature", "", "", "Signature file (for inject operation)")
200+
f.StringP("output", "o", "", "Output file path")
201+
f.SortFlags = false
202+
})
203+
common.BindFlagCompletions(sigforgeCmd, func(comp carapace.ActionMap) {
204+
comp["source"] = carapace.ActionFiles().Usage("source PE file")
205+
comp["target"] = carapace.ActionFiles().Usage("target PE file")
206+
comp["signature"] = carapace.ActionFiles().Usage("signature file")
207+
comp["output"] = carapace.ActionFiles().Usage("output file path")
208+
})
209+
210+
// Add subcommands to mutant parent command (excluding donut)
211+
mutantCmd.AddCommand(srdiCmd, stripCmd, sigforgeCmd)
212+
213+
// Return mutant as parent command and donut as standalone
214+
return []*cobra.Command{mutantCmd, donutCmd}
114215
}
115216

116217
func Register(con *core.Console) {

0 commit comments

Comments
 (0)