Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filenames and import paths leaked via assembly files #605

Closed
Ne0nd0g opened this issue Nov 11, 2022 · 2 comments · Fixed by #606
Closed

Filenames and import paths leaked via assembly files #605

Ne0nd0g opened this issue Nov 11, 2022 · 2 comments · Fixed by #606

Comments

@Ne0nd0g
Copy link

Ne0nd0g commented Nov 11, 2022

What version of Garble and Go are you using?

$ garble version

mvdan.cc/garble v0.7.2

Build settings:
       -compiler gc
     CGO_ENABLED 1
          GOARCH amd64
            GOOS linux
         GOAMD64 v1


$ go version

go version go1.19.3 linux/amd64

What environment are you running Garble on?

go env Output
$ go env

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/rastley/.cache/go-build"
GOENV="/home/rastley/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/rastley/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/rastley/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.19.3"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/tmp/test/merlin-agent/go.mod"
GOWORK=""
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 -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3883891253=/tmp/go-build -gno-record-gcc-switches"

What did you do?

rastley@ubuntu:/tmp/test$ git clone https://github.com/Ne0nd0g/merlin-agent
Cloning into 'merlin-agent'...
remote: Enumerating objects: 873, done.
remote: Counting objects: 100% (245/245), done.
remote: Compressing objects: 100% (140/140), done.
remote: Total 873 (delta 125), reused 178 (delta 90), pack-reused 628
Receiving objects: 100% (873/873), 352.33 KiB | 3.67 MiB/s, done.
Resolving deltas: 100% (495/495), done.
rastley@ubuntu:/tmp/test$ cd merlin-agent/
rastley@ubuntu:/tmp/test/merlin-agent$ make linux-garble
export GOGARBLE=golang.org,gopkg.in,github.com;export GOOS=linux GOARCH=amd64;garble -tiny -literals -seed d0d03a0ae4722535a0e1d5d0c8385ce42015511e68d960fadef4b4eaf5942feb build -trimpath -ldflags '-s -w -X "main.build=890d80f1e940c46a915e6a2d8abfd97b6655c78c" -X "github.com/Ne0nd0g/merlin-agent/agent.build=890d80f1e940c46a915e6a2d8abfd97b6655c78c" -X "main.protocol=h2" -X "main.url=https://127.0.0.1:443" -X "main.host=" -X "main.psk=merlin" -X "main.sleep=30s" -X "main.proxy=" -X "main.useragent=Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36" -X "main.headers=" -X "main.skew=3000" -X "main.padding=4096" -X "main.killdate=0" -X "main.maxretry=7" -X "main.parrot=" -buildid=' -gcflags=all=-trimpath= -asmflags=all=-trimpath= -o bin/v1.6.0/890d80f1e940c46a915e6a2d8abfd97b6655c78c/merlinAgent-Linux-x64 ./main.go

What did you expect to see?

To run strings on the output binary and NOT see references for modules in GOGARBLE like github.com.

What did you see instead?

rastley@ubuntu:/tmp/test/merlin-agent$ strings bin/v1.6.0/890d80f1e940c46a915e6a2d8abfd97b6655c78c/merlinAgent-Linux-x64|grep -i github.com
/tmp/garble-shared54321534/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s
/tmp/garble-shared54321534/github.com/klauspost/compress/huff0/decompress_amd64.s
/tmp/garble-shared54321534/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s
/tmp/garble-shared54321534/github.com/klauspost/compress/zstd/fse_decoder_amd64.s
/tmp/garble-shared54321534/github.com/klauspost/compress/zstd/seqdec_amd64.s

There were 490 lines, this is just a snippet:

rastley@ubuntu:/tmp/test/merlin-agent$ strings bin/v1.6.0/890d80f1e940c46a915e6a2d8abfd97b6655c78c/merlinAgent-Linux-x64|grep -i golang.org
vendor/golang.org/x/sys/cpu
vendor/golang.org/x/net/idna
vendor/golang.org/x/crypto/hkdf
#vendor/golang.org/x/net/http2/hpack
%vendor/golang.org/x/crypto/cryptobyte
%vendor/golang.org/x/text/unicode/bidi
%vendor/golang.org/x/text/unicode/norm
&vendor/golang.org/x/net/dns/dnsmessage
&vendor/golang.org/x/net/http/httpproxy
*vendor/golang.org/x/crypto/cryptobyte/asn1
+vendor/golang.org/x/crypto/chacha20poly1305
!refusing to use HTTP_PROXY value in CGI environment; see golang.org/s/cgihttpproxyx509: a root or intermediate certificate is not authorized to sign for this name: |
vendor/golang.org/x/net/dns/dnsmessage.(*nestedError).Error
vendor/golang.org/x/net/dns/dnsmessage.(*header).pack
vendor/golang.org/x/net/dns/dnsmessage.packUint16
vendor/golang.org/x/net/dns/dnsmessage.(*header).unpack
vendor/golang.org/x/net/dns/dnsmessage.unpackUint16
vendor/golang.org/x/net/dns/dnsmessage.(*Parser).Start
vendor/golang.org/x/net/dns/dnsmessage.(*header).header
vendor/golang.org/x/net/dns/dnsmessage.(*Parser).resourceHeader
vendor/golang.org/x/net/dns/dnsmessage.(*Parser).checkAdvance
vendor/golang.org/x/net/dns/dnsmessage.(*header).count
vendor/golang.org/x/net/dns/dnsmessage.(*Parser).skipResource
vendor/golang.org/x/net/dns/dnsmessage.(*Parser).Question
vendor/golang.org/x/net/dns/dnsmessage.(*Name).unpack
vendor/golang.org/x/net/dns/dnsmessage.unpackType
vendor/golang.org/x/net/dns/dnsmessage.unpackClass
rastley@ubuntu:/tmp/test/merlin-agent$ strings bin/v1.6.0/890d80f1e940c46a915e6a2d8abfd97b6655c78c/merlinAgent-Linux-x64|grep -i merlin
avx512chan<-closedcookiedomainerrno exec: expectgopherhangupheaderinternip+netkilledlistenmerlinminutendots:netdnsobjectpopcntrdrandrdseedrdtscpremovereturnsecondselectsendtoserversetenvsocketsocks socks5splicestatusstringstructsysmontelnettimersuint16uint32uint64unusedwaitid %v=%v, (conn) (trap  Value> flags= len=%d%s %s; (%s,%s)19531252.5.4.32.5.4.52.5.4.62.5.4.72.5.4.82.5.4.99765625::1/128:method:scheme:statusA256GCMAvestanBengaliBrailleCONNECTChanDirConvertCreatedCypriotDeseretEd25519ElbasanElymaicExpiresGODEBUGGranthaHEADERSHanunooIM UsedIO waitJanuaryKannadaMD2-RSAMD5-RSAMakasarMandaicMarchenMultaniMyanmarOctoberOsmanyaRadicalRefererSHA-224SHA-256SHA-384SHA-512SharadaShavianSiddhamSinhalaSogdianSoyomboSubjectSwapperTagalogTibetanTirhutaTrailerTuesdayTypeALLTypeOPTTypePTRTypeSOATypeSRVTypeTXTTypeWKSUNKNOWNUpgradeUsage:
merlin
@Ne0nd0g
Copy link
Author

Ne0nd0g commented Nov 11, 2022

Using my merlin-agent-dll repository I see:

rastley@ubuntu:/tmp/test/merlin-agent-dll$ make garble
export GOGARBLE=golang.org,gopkg.in,github.com; export GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CGO_ENABLED=1; \
garble -tiny -literals -seed d0d03a0ae4722535a0e1d5d0c8385ce42015511e68d960fadef4b4eaf5942feb build -ldflags '-s -w -X main.build=a9ac493631448d8532bdce8cf56c4eab899b9e0e -X github.com/Ne0nd0g/merlin/pkg/agent.build=a9ac493631448d8532bdce8cf56c4eab899b9e0e -X main.protocol=h2 -X main.url=https://127.0.0.1:443 -X main.host= -X main.psk=merlin -X main.proxy= -X main.killdate=0 -X main.maxretry=7 -X main.padding=4096 -X main.skew=0 -X "main.useragent=Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36" -X main.sleep=30s -buildid=' -gcflags=all=-trimpath= -asmflags=all=-trimpath= -buildmode=c-archive -o bin/v1.5.0/a9ac493631448d8532bdce8cf56c4eab899b9e0e/main.a main.go; \
cp merlin.c bin/v1.5.0/a9ac493631448d8532bdce8cf56c4eab899b9e0e; \
x86_64-w64-mingw32-gcc -shared -pthread -o bin/v1.5.0/a9ac493631448d8532bdce8cf56c4eab899b9e0e/merlin.dll bin/v1.5.0/a9ac493631448d8532bdce8cf56c4eab899b9e0e/merlin.c bin/v1.5.0/a9ac493631448d8532bdce8cf56c4eab899b9e0e/main.a -lwinmm -lntdll -lws2_32
rastley@ubuntu:/tmp/test/merlin-agent-dll$ strings bin/v1.5.0/a9ac493631448d8532bdce8cf56c4eab899b9e0e/merlin.dll|grep -i github.com
/tmp/garble-shared3989654714/github.com/C-Sto/BananaPhone/pkg/BananaPhone/asm_x64.s
/tmp/garble-shared3989654714/github.com/refraction-networking/utls/cpu/cpu_x86.s

I get 888 lines for golang.org

@mvdan
Copy link
Member

mvdan commented Nov 11, 2022

Thanks for reporting, I can reproduce even with GOGARBLE=*.

@mvdan mvdan changed the title Module Paths Persist in Binary Filenames and import paths leaked via assembly files Nov 11, 2022
mvdan added a commit to mvdan/garble-fork that referenced this issue Nov 11, 2022
We were still leaking the filenames for assembly files.
In our existing asm.txtar test's output binary,
the string `test/main/garble_main_amd64.s` was present.
This leaked full import paths on one hand,
and the filenames of each assembly file on the other.

We avoid this in Go files by using `/*line` directives,
but those are not supported in assembly files.
Instead, obfuscate the paths in the temporary directory.
Note that we still need a separate temporary directory per package,
because otherwise any included header files might collide.

We must remove the `main` package panic in obfuscatedImportPath,
as we now need to use that function for all packages.

While here, remove the outdated comment about `-trimpath`.

Fixes burrowers#605.
mvdan added a commit to mvdan/garble-fork that referenced this issue Nov 11, 2022
We were still leaking the filenames for assembly files.
In our existing asm.txtar test's output binary,
the string `test/main/garble_main_amd64.s` was present.
This leaked full import paths on one hand,
and the filenames of each assembly file on the other.

We avoid this in Go files by using `/*line` directives,
but those are not supported in assembly files.
Instead, obfuscate the paths in the temporary directory.
Note that we still need a separate temporary directory per package,
because otherwise any included header files might collide.

We must remove the `main` package panic in obfuscatedImportPath,
as we now need to use that function for all packages.

While here, remove the outdated comment about `-trimpath`.

Fixes burrowers#605.
@lu4p lu4p closed this as completed in #606 Nov 12, 2022
lu4p pushed a commit that referenced this issue Nov 12, 2022
We were still leaking the filenames for assembly files.
In our existing asm.txtar test's output binary,
the string `test/main/garble_main_amd64.s` was present.
This leaked full import paths on one hand,
and the filenames of each assembly file on the other.

We avoid this in Go files by using `/*line` directives,
but those are not supported in assembly files.
Instead, obfuscate the paths in the temporary directory.
Note that we still need a separate temporary directory per package,
because otherwise any included header files might collide.

We must remove the `main` package panic in obfuscatedImportPath,
as we now need to use that function for all packages.

While here, remove the outdated comment about `-trimpath`.

Fixes #605.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants