1

I need to determine whether a given ELF file originated from Go. According to this link:

$ readelf -a traefik.stripped | grep "\.note\.go\.buildid"

Is this in any way inferior to go's native way:

$ go tool buildid traefik.stripped
oPIWoPjqt1P3rttpA3ee/ByNXPhvgS37nIoJY-HYB/8b25JYXrgktA-FYgU5MU/0Posfq41xZW9BEPEG4Ub

Are both methods guaranteed to work on stripped binaries?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87
  • I'm sure it depends on what you mean by "guaranteed". No doubt it's possible to craft/modify an ELF binary that fools the tools, to either produce a false negative or a false positive. – Jonathan Hall Nov 03 '21 at 08:58
  • @Flimzy can you describe a scenario where this section is removed *without* compromising the functionality of the ELF file? – OrenIshShalom Nov 03 '21 at 09:02
  • I cannot. I'm not that familiar with ELF binary formats. But I know that this is exactly the sorts of things virus authors (and others) do, so I'm sure it can be done. Whether anyone would have a reason to do so, I don't know. But you asked about guarantees. I don't think there are any. – Jonathan Hall Nov 03 '21 at 09:04
  • 3
    Think of it this way: What's to prevent a Python script from building a byte-for-byte identical ELF binary, compared to one generated by a Go compiler? Nothing, obvoiusly, other than the time and motivation. – Jonathan Hall Nov 03 '21 at 09:05
  • But if that is possible, then how come `strip` itself doesn't remove this section? – OrenIshShalom Nov 03 '21 at 09:10
  • 1
    I don't know. That's a very different question. How/why strip behaves the way it does has little to nothing to do with the technical possibility of fooling a heuristic. – Jonathan Hall Nov 03 '21 at 09:11
  • What are you trying to accomplish here? – Jonathan Hall Nov 03 '21 at 09:12
  • can an innocent go developer build a golang ELF and accidentally remove this (redundant??) section – OrenIshShalom Nov 03 '21 at 09:16

3 Answers3

2

I need to determine whether a given ELF file originated from Go

That is impossible to do in general. What is and isn't a Go binary is not well defined, and a sufficiently optimized Go binary may end up containing just a few instructions. E.g. on x86_64, you may end up with a single HLT instruction.

how come strip itself doesn't remove this section?

This section (indeed every section) is not necessary for execution -- you can remove all sections, and the binary will still work.

This section is present only to help developers identify a particular build. strip doesn't remove it by default because that would defeat the purpose of this section, but it certainly can do so.

can an innocent go developer build a golang ELF and accidentally remove this (redundant??) section

Sure. The developer can run a broken version of strip, or he can have aliased strip with strip --strip-all, or he could have used some other ELF post-processing tool, or he could have used UPX, or ...

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
1

The mentioned section is a NOTE section:

$ readelf -a traefik.stripped | grep "\.note\.go\.buildid" | sed -n "1,1p"
  [11] .note.go.buildid  NOTE             0000000000400f9c  00000f9c

And apparently NOTE sections might sometimes be removed for size reductions (related):

objcopy --remove-section=.note.go.buildid traefik.stripped traefik.super.stripped

Removing the mentioned section does not seem to harm the integrity of the whole binary

OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87
1

As for using standard go tools the section should be there, but there is a way that the go nature of a binary can be hidden without any malicious intent. Using upx to reduce the size of the binary will completely hide the go nature of the binary as upx works with binaries from any language.

NuLo
  • 1,298
  • 1
  • 11
  • 16