diff options
-rw-r--r-- | attacksurface.md | 2 | ||||
-rw-r--r-- | conf/name.go | 3 | ||||
-rw-r--r-- | installer/installer.wxs | 6 | ||||
-rw-r--r-- | service/install.go | 10 | ||||
-rw-r--r-- | service/names.go | 2 |
5 files changed, 12 insertions, 11 deletions
diff --git a/attacksurface.md b/attacksurface.md index 20d29afb..5b545393 100644 --- a/attacksurface.md +++ b/attacksurface.md @@ -27,7 +27,7 @@ The manager service is a userspace service running as Local System, responsible - Extensive IPC using unnamed pipes, inherited by the unprivileged UI process. - A writable `CreateFileMapping` handle to a binary ringlog shared by all services, inherited by the unprivileged UI process. It's unclear if this brings with it surprising hidden attack surface in the mm system. - - It listens for service changes in tunnel services according to the string prefix "WireGuard Tunnel: ". + - It listens for service changes in tunnel services according to the string prefix "WireGuardTunnel$". - It manages DPAPI-encrypted configuration files in Local System's local appdata directory, and makes some effort to enforce good configuration filenames. - It uses `wtsEnumerateSessions` and `WTSSESSION_NOTIFICATION` to walk through each available session. It then uses `wtfQueryUserToken`, and then calls `GetTokenInformation(TokenGroups)` on it. If one of the returned group's SIDs matches `CreateWellKnownSid(WinBuiltinAdministratorsSid)`, then it spawns the unprivileged UI process as that user token, passing it three unnamed pipe handles for IPC and the log mapping handle, as descried above. diff --git a/conf/name.go b/conf/name.go index a4a599f9..00479c04 100644 --- a/conf/name.go +++ b/conf/name.go @@ -16,6 +16,7 @@ var reservedNames = []string{ "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", } +const serviceNameForbidden = "$" const netshellDllForbidden = "\\/:*?\"<>|\t" const specialChars = "/\\<>:\"|?*\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x00" @@ -38,7 +39,7 @@ func isReserved(name string) bool { } func hasSpecialChars(name string) bool { - return strings.ContainsAny(name, specialChars) || strings.ContainsAny(name, netshellDllForbidden) + return strings.ContainsAny(name, specialChars) || strings.ContainsAny(name, netshellDllForbidden) || strings.ContainsAny(name, serviceNameForbidden) } func TunnelNameIsValid(name string) bool { diff --git a/installer/installer.wxs b/installer/installer.wxs index 900c8a31..b2f22034 100644 --- a/installer/installer.wxs +++ b/installer/installer.wxs @@ -37,9 +37,9 @@ <File Source="..\wireguard.exe" KeyPath="yes"> <Shortcut Id="WireGuardStartMenuShortcut" Directory="ProgramMenuFolder" Name="WireGuard" Description="WireGuard: Fast, Modern, Secure VPN Tunnel" WorkingDirectory="INSTALLFOLDER" Advertise="yes" /> </File> - <ServiceControl Id="RemoveWireGuardManagerService" Name="WireGuard Manager" Remove="both" Stop="both"></ServiceControl> - <ServiceControl Id="RemoveWireGuardTunnelServices" Name="WireGuard Tunnel: test" Remove="both" Stop="both"></ServiceControl> - <!-- TODO: "test" is just a temporary hack. We need to enumerate all services that are "WireGuard Tunnel: *" and remove those. --> + <ServiceControl Id="RemoveWireGuardManagerService" Name="WireGuardManager" Remove="both" Stop="both"></ServiceControl> + <ServiceControl Id="RemoveWireGuardTunnelServices" Name="WireGuardTunnel$test" Remove="both" Stop="both"></ServiceControl> + <!-- TODO: "test" is just a temporary hack. We need to enumerate all services that are "WireGuardTunnel$*" and remove those. --> </Component> </ComponentGroup> diff --git a/service/install.go b/service/install.go index 7f39b2bc..95c42b2f 100644 --- a/service/install.go +++ b/service/install.go @@ -42,7 +42,7 @@ func InstallManager() error { //TODO: Do we want to bail if executable isn't being run from the right location? - serviceName := "WireGuard Manager" + serviceName := "WireGuardManager" service, err := m.OpenService(serviceName) if err == nil { status, err := service.Query() @@ -73,7 +73,7 @@ func InstallManager() error { ServiceType: windows.SERVICE_WIN32_OWN_PROCESS, StartType: mgr.StartAutomatic, ErrorControl: mgr.ErrorNormal, - DisplayName: serviceName, + DisplayName: "WireGuard Manager", } service, err = m.CreateService(serviceName, path, config, "/managerservice") @@ -89,7 +89,7 @@ func UninstallManager() error { if err != nil { return err } - serviceName := "WireGuard Manager" + serviceName := "WireGuardManager" service, err := m.OpenService(serviceName) if err != nil { return err @@ -104,7 +104,7 @@ func UninstallManager() error { } func RunManager() error { - return svc.Run("WireGuard Manager", &managerService{}) + return svc.Run("WireGuardManager", &managerService{}) } func InstallTunnel(configPath string) error { @@ -156,7 +156,7 @@ func InstallTunnel(configPath string) error { ServiceType: windows.SERVICE_WIN32_OWN_PROCESS, StartType: mgr.StartAutomatic, ErrorControl: mgr.ErrorNormal, - DisplayName: serviceName, + DisplayName: "WireGuard Tunnel: " + name, } service, err = m.CreateService(serviceName, path, config, "/tunnelservice", configPath) diff --git a/service/names.go b/service/names.go index 453f3b29..ced657aa 100644 --- a/service/names.go +++ b/service/names.go @@ -14,7 +14,7 @@ func ServiceNameOfTunnel(tunnelName string) (string, error) { if !conf.TunnelNameIsValid(tunnelName) { return "", errors.New("Tunnel name is not valid") } - return "WireGuard Tunnel: " + tunnelName, nil + return "WireGuardTunnel$" + tunnelName, nil } func PipePathOfTunnel(tunnelName string) (string, error) { |