If you're using distro packages, their own "packaging policy" should offer some level of assurance via policy about static linking (since as far as I know, all major distros dynamically link, to make this kind of bugfix easier).
If you're talking non distro packages (proprietary, or anything built manually from PPA or equivalent, or binaries dumped inside containers), this won't help.
Sure, but there might also be binaries outside the distro which link things statically, because makes distribution easier.
This is one of the "benefits" of go, where afaik many things are linked statically.
I'm currently playing around with grepping some function-names to find out if something uses libssl, and then check if ldd to see if libssl is loaded dynamically or not.
> Sure, but there might also be binaries outside the distro which link things statically, because makes distribution easier.
Then you'd use ldd to print the shared objects (shared libraries) required by each program or shared object: find … | xargs ldd.
> This is one of the "benefits" of go, where afaik many things are linked statically.
The static linking makes the situation worse: with dynamic link you update one package, and then restart any currently running processes. There are even helpful utilities to help you do the latter:
Indeed - this is one of the positives of Go, as all the dependencies get linked statically, giving nice portable "single binary" solutions.
Grepping function names seems a reasonable approach, as long as you're not trying to detect something that is obfuscating its use of libssl (i.e. by mangling strings together).
It appears if you strip a binary, any definitive information about the libraries linked in statically is lost, beyond function names and argument combinations. I believe there are tools in IDA and similar, which can match functions based on their input argument types and name. That might help you match to a rough version of the upstream library, if parameters changed.
Unsure why people keep referring to static linking as a positive in this thread? Downstream consumers of statically-linked binaries have no practical way to scan their systems for known-vulnerable versions of libraries, that seems a profoundly negative consequence to me.
In Go you can use "go version -m my-go-binary" and get a list of dependencies and other build information. For example (may wrap a bit ugly on HN):
[~]% go version -m =godoc
/home/belta/bin/godoc: go1.18.3
path golang.org/x/tools/cmd/godoc
mod golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
dep github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
dep golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
dep golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
dep golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
build -compiler=gc
build CGO_ENABLED=0
build GOARCH=amd64
build GOOS=linux
build GOAMD64=v1
So scanning your binaries, if you want, is fairly easy.
Other than that, this is the "Great Static vs. Dynamic Linking Debate", which has been done quite a few times. I have little desire to repeat it, but both approaches have their advantages and downsides, and with good tooling (like the above) I think many downsides of static linking can be managed quite well.
That's a great solution, actually. I'm not familiar with go, but I thought it compiled to native code and did not require a virtual machine at runtime. So is this metadata enforced/inserted by the compiler into the binary, or does it require specific build tooling that may or may not be available on end-user systems?
Unfortunately that shows the Go libraries involved, but not the C libraries those Go libraries depend on (right?). So that might tell me that a Go program includes 'crypto', but not whether or not that 'crypto' linked in OpenSSL 1.1.1 or OpenSSL 3.x.
So the static linking dependency analysis problem remains.
Indeed, there are certainly good reasons to statically link programs, but this type of security issue is the complete opposite, it's a known drawback that you may accept in exchange for the other benefits of static linking
Search the binaries for strings/messages that are unique to libssl. It's the only way (and it still doesn't give a conclusive answer) if the provenance of the binary is unknown.
If you're talking non distro packages (proprietary, or anything built manually from PPA or equivalent, or binaries dumped inside containers), this won't help.