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

detect OS from ELF file #724

Closed
williballenthin opened this issue Aug 11, 2021 · 12 comments · Fixed by #723
Closed

detect OS from ELF file #724

williballenthin opened this issue Aug 11, 2021 · 12 comments · Fixed by #723

Comments

@williballenthin
Copy link
Collaborator

In support of the discussions in #701, we want to extract the OS associated with each file. For PE files, we can pretty much assume they're for Windows. For ELF files, we should try to determine if they're targeting Linux, *BSD, Solaris, etc. How can we do this well?

To be direct, I don't have a lot of experience with this. So, I'll document my research in this thread and would welcome feedback from anyone with insight.

@williballenthin
Copy link
Collaborator Author

The e_ident[EI_OSABI] header at offset 0x7 specifies the target operating system ABI. However, Wikipedia notes that this is often set to 0x0.

image

https://en.wikipedia.org/wiki/Executable_and_Linkable_Format

@williballenthin
Copy link
Collaborator Author

williballenthin commented Aug 11, 2021

The Linux standard requires that executables should have a NOTE section that indicates its meant for Linux and the earliest compatible kernel version:

Every executable shall contain a section named .note.ABI-tag of type SHT_NOTE. This section is structured as a note section as documented in the ELF spec. The section must contain at least the following entry. The name field (namesz/name) contains the string "GNU". The type field shall be 1. The descsz field shall be at least 16, and the first 16 bytes of the desc field shall be as follows.

The first 32-bit word of the desc field must be 0 (this signifies a Linux executable). The second, third, and fourth 32-bit words of the desc field contain the earliest compatible kernel version. For example, if the 3 words are 2, 2, and 5, this signifies a 2.2.5 kernel.

https://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html

i dont know if this applies to libraries, too.

@williballenthin
Copy link
Collaborator Author

OpenBSD also uses a similar NOTE system:

image
image

image
https://man.openbsd.org/elf.5#.note.openbsd.ident

@williballenthin
Copy link
Collaborator Author

williballenthin commented Aug 11, 2021

Dynamically linked ELF files have an INTERP section that points to their dynamic linker. This path likely contains one of a small set of values correlated with the OS, such as /lib64/ld-linux-x86-64.so.2 for Linux and /usr/libexec/ld.so on OpenBSD. Would need to build this mapping from a large set of samples.

image
image

unscientific collection of interpreters (from 100 each of freebsd, hp-ux, linux, netbsd, openbsd, and openvms identified by mime on VT):

    176 DEBUG:capa.detect-elf-os:linker: /usr/libexec/ld.so
     59 DEBUG:capa.detect-elf-os:linker: /usr/libexec/ld.elf_so
     14 DEBUG:capa.detect-elf-os:linker: /libexec/ld.elf_so
     10 DEBUG:capa.detect-elf-os:linker: /libexec/ld-elf.so.1
      5 DEBUG:capa.detect-elf-os:linker: /lib64/ld-linux-x86-64.so.2
/usr/libexec/ld.so
    100 openbsd
     76 hp-ux
/usr/libexec/ld.elf_so
     59 netbsd
/libexec/ld.elf_so
     73 netbsd
/libexec/ld-elf.so.1
     10 freebsd
/lib64/ld-linux-x86-64.so.2
      6 linux

@williballenthin
Copy link
Collaborator Author

VT search: magic:"NetBSD" and tag:elf and size:1MB-

@williballenthin
Copy link
Collaborator Author

@schrodyn i'd love your insight here

@williballenthin
Copy link
Collaborator Author

williballenthin commented Aug 11, 2021

OpenBSD may have an note with type==1 and name OpenBSD:

image

@williballenthin
Copy link
Collaborator Author

NetBSD may have a note with type == 1 and name NetBSD:

image

@schrodyn
Copy link

schrodyn commented Aug 11, 2021

https://www.freebsd.org/cgi/man.cgi?query=elf&sektion=5&apropos=0&manpath=FreeBSD+13.0-stable The FreeBSD man page for elf(5) documents its note types. I'll get more information later, afk currently.

williballenthin added a commit that referenced this issue Aug 11, 2021
@williballenthin
Copy link
Collaborator Author

williballenthin commented Aug 11, 2021

added implementation of heuristics above here: https://github.com/fireeye/capa/blob/baaa8ba2c10b2dd27554223e5469ce712c5c1902/scripts/detect-elf-os.py

prefers in order:

  • ei_osabi
  • NOTE section
  • INTERP section

@schrodyn
Copy link

schrodyn commented Aug 11, 2021

$ python3.7 detect-elf-os.py /bin/ls
not ida
FREEBSD
$ sha256 /bin/ls
SHA256 (/bin/ls) = a34e5b38019626a7a4e49a858edaca7cf580d4f39344f0b9961fff0c2bdd0b8f
$ r2 -A /bin/ls  
[0x00203bc0]> i

humansz  33.6K
mode     r-x
format   elf64
iorw     false
blksz    0x0
block    0x100
type     EXEC (Executable file)
arch     x86
baddr    0x200000
binsz    32563
bintype  elf
bits     64
canary   true
class    ELF64
compiler $FreeBSD: releng/12.2/lib/csu/amd64/reloc.c 339351 2018-10-13 23:52:55Z kib $/$FreeBSD: releng/12.2/lib/csu/amd64/crt1.c 339351 2018-10-13 23:52:55Z kib $/$FreeBSD: releng/12.2/lib/csu/common/ignore_init.c 339351 2018-10-13 23:52:55Z kib $/$FreeBSD: releng/12.2/bin/ls/ls.c 361818 2020-06-05 02:56:42Z kevans $/$FreeBSD: releng/12.2/bin/ls/util.c 337956 2018-08-17 04:15:51Z kevans $/$FreeBSD: releng/12.2/lib/csu/amd64/crti.S 217105 2011-01-07 16:07:51Z kib $/$FreeBSD: releng/12.2/bin/ls/print.c 337956 2018-08-17 04:15:51Z kevans $/FreeBSD clang version 10.0.1 (git@github.com:llvm/llvm-project.git llvmorg-10.0.1-0-gef32c611aa2)/Linker: LLD 10.0.1 (FreeBSD llvmorg-10.0.1-0-gef32c611aa2-1200012)/$FreeBSD: releng/12.2/lib/csu/common/crtbrand.c 366954 2020-10-23 00:00:52Z gjb $//$FreeBSD: releng/12.2/bin/ls/cmp.c 326025 2017-11-20 19:49:47Z pfg $/$FreeBSD: releng/12.2/lib/csu/amd64/crtn.S 217105 2011-01-07 16:07:51Z kib $
crypto   false
endian   little
havecode true
intrp    /libexec/ld-elf.so.1
laddr    0x0
lang     c
linenum  false
lsyms    false
machine  AMD x86-64 architecture
maxopsz  16
minopsz  1
nx       true
os       freebsd
pcalign  0
pic      false
relocs   false
relro    partial
rpath    NONE
sanitiz  false
static   false
stripped true
subsys   freebsd
va       true

[0x00203bc0]> pxw 12 @section..note.tag
0x002002c0  0x00000008 0x00000004 0x00000001             ............
[0x00203bc0]> psz @section..note.tag+12
FreeBSD
[0x00203bc0]>

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

Successfully merging a pull request may close this issue.

2 participants