golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.83k stars 17.51k forks source link

x/sys/windows/registry: error reading/writing Windows Defender Registry #35730

Open KyhleOhlinger opened 4 years ago

KyhleOhlinger commented 4 years ago

What version of Go are you using (go version)?

$ go version
go version go 1.13.4 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOENV="/home/user/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/user/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go-1.13"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go-1.13/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build848002775=/tmp/go-build -gno-record-gcc-switches"

However, the code was compiled to Windows executable using: env GOOS=windows GOARCH=386

What did you do?

The issue was raised on Go-Nuts: https://groups.google.com/forum/#!topic/golang-nuts/V-0GT02SMIs

I have been working with the Golang registry and noticed an issue when attempting to access / read from SOFTWARE\Microsoft\Windows Defender. The following code calls SOFTWARE\Microsoft\Windows NT\CurrentVersion and it outputs the correct information.

winInfo, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
check(err)
defer winInfo.Close()

CurrentVersion, _, err := winInfo.GetStringValue("CurrentVersion")
check(err)
fmt.Printf("Value: " + CurrentVersion +"\n")

-----------------
Output:
-----------------
Value: 6.3

However, when attempting to access the Windows Defender registry key using the following code, it doesn't return any information.

regInfo, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows Defender`, registry.QUERY_VALUE)
check(err)
defer regInfo.Close()

BackVersion, _, err := regInfo.GetStringValue("BackupLocation")
check(err)
fmt.Printf("Value: " + BackVersion)

-----------------
Output:
-----------------
The system cannot find the file specified.
Value:

I thought this may be an issue with permissions, so I checked the ACLs for the registry keys and all Authenticated Users do have read access to the object, and Adminstrators have Special permissions to the object. In order to confirm this, I used REG QUERY as shown below from a low privileged user account:

REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender" /v BackupLocation

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender
BackupLocation REG_SZ C:\ProgramData\Microsoft\Windows Defender\platform\4.18.1909.6-0

After this I thought it may require signed Microsoft binaries in order to access the registry location, I then installed Registry Editor, a 3rd party viewer which was able to access the information. Finally, I thought it could be an issue with programming languages being unable to access the registry, so I tried it using the following Python code:

import errno, os, winreg

RawKey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows NT\CurrentVersion",0, winreg.KEY_READ)
print(winreg.QueryValueEx(RawKey,"CurrentVersion"))

RawKey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows Defender",0, winreg.KEY_READ)
print(winreg.QueryValueEx(RawKey,"BackupLocation"))

-----------------
Output:
-----------------
('6.3', 1)  
('C:\\ProgramData\\Microsoft\\Windows Defender\\platform\\4.18.1909.6-0', 1)                                                                                                                            

The code above did return the correct information, which leads me to believe that there is an issue with the Golang registry implementation. Either that, or I am not using the registry correctly with Golang.

Any help would be greatly appreciated.

What did you expect to see?

I expected to see a value returned from the Windows Defender registry: HKLM\SOFTWARE\Microsoft\Windows Defender.

What did you see instead?

The following error was returned instead: The system cannot find the file specified

KyhleOhlinger commented 4 years ago

Current Windows Version: OS Name: Microsoft Windows 10 Enterprise OS Version: 10.0.18362 N/A Build 18362

toothrot commented 4 years ago

/cc @alexbrainman @bradfitz

alexbrainman commented 4 years ago

@KyhleOhlinger I cannot reproduce your problem here.

I run https://play.golang.org/p/cco7-UO_j-E here, and I see this output


C:\>u:\test -test.v
=== RUN   TestALEX
    TestALEX: registry_test.go:21: got="C:\\ProgramData\\Microsoft\\Windows Defender\\platform\\4.18.1909.6-0" gottype=1
--- PASS: TestALEX (0.01s)
PASS

C:\>```

I also use Windows 10.

Alex
KyhleOhlinger commented 4 years ago

@alexbrainman I wonder if it it not an issue with compilation. I am using the following to compile the binary on Linux and then I'm executing it on Windows:

go build env GOOS=Windows GOARCH=386 file.go

alexbrainman commented 4 years ago

I wonder if it it not an issue with compilation.

I don't know what the problem is.

I am using the following to compile the binary on Linux and then I'm executing it on Windows:

Same.

Alex