elf

The elf module is very similar to the pe module, but for ELF files. This module exposes most of the fields present in an ELF header. Let’s see some examples:

import "elf"

rule single_section {
    condition:
        elf.number_of_sections == 1
}

rule elf_64 {
    condition:
        elf.machine == elf.EM_X86_64
}

Functions

import_md5()

Returns the MD5 of the import table.

telfhash()

Returns the TrendMicro’s telfhash for the ELF file. This is a symbol hash for ELF files, just like imphash is an imports hash for PE files. With telfhash, you can cluster ELF files by similarity based on symbols.

For more information visit https://github.com/trendmicro/telfhash or read TrendMicro’s whitepaper.

Example

import "elf"

rule FindByTelfhash {
    condition:
        elf.telfhash() == "t166a00284751084526486df8b5df5b2fccb3f511dbc188c37156f5e714a11bc5d71014d"
}

Module structure

FieldType
typeType
machineMachine
entry_pointinteger
sh_offsetinteger
sh_entry_sizeinteger
ph_offsetinteger
ph_entry_sizeinteger
number_of_sectionsinteger
number_of_segmentsinteger
symtab_entriesinteger
dynsym_entriesinteger
dynamic_section_entriesinteger
sectionsSection array
segmentsSegment array
symtabSym array
dynsymSym array
dynamicDyn array

Dyn

This is the structure of each item in the dynamic array.

FieldType
typeDynType
valinteger

Section

This is the structure of each item in the sections array.

FieldType
typeSectionType
flagsinteger
addressinteger
sizeinteger
offsetinteger
namestring

Example

import "elf"

rule DebugInfo {
    condition:
        for any section in elf.sections : (
           section.name == ".debug_info"
        )
}

Segment

This is the structure of each item in the segments array.

FieldType
typeSegmentType
flagsinteger
offsetinteger
virtual_addressinteger
physical_addressinteger
file_sizeinteger
memory_sizeinteger
alignmentinteger

Example

import "elf"

rule NoLargeSegment {
    condition:
        for all segment in elf.segments : (
           segment.file_size < 0x100000
        )
}

Sym

This is the structure of each item in the symtab and dynsym arrays.

FieldType
namestring
valueinteger
sizeinteger
typeSymType
bindSymBind
shndxinteger
visibilitySymVisibility

Example

import "elf"

rule CrtStuff {
    condition:
        for any sym in elf.symtab : (
           sym.name == "crtstuff.c"
        )
}

DynType

These are the possible values of the type field in the Dyn structure.

NameValueDescription
DT_NULL0End of the dynamic entries
DT_NEEDED1Name of needed library
DT_PLTRELSZ2Size in bytes of PLT relocs
DT_PLTGOT3Processor defined value */
DT_HASH4Address of symbol hash table
DT_STRTAB5Address of string table
DT_SYMTAB6Address of symbol table
DT_RELA7Address of Rela relocs
DT_RELASZ8Total size of Rela relocs
DT_RELAENT9Size of one Rela reloc
DT_STRSZ10Size of string table
DT_SYMENT11Size of one symbol table entry
DT_INIT12Address of init function
DT_FINI13Address of termination function
DT_SONAME14Name of shared object
DT_RPATH15Library search path (deprecated)
DT_SYMBOLIC16Start symbol search here
DT_REL17Address of Rel relocs
DT_RELSZ18Total size of Rel relocs
DT_RELENT19Size of one Rel reloc
DT_PLTREL20Type of reloc in PLT
DT_DEBUG21For debugging; unspecified
DT_TEXTREL22Reloc might modify .text
DT_JMPREL23Address of PLT relocs
DT_BIND_NOW24Process relocations of object
DT_INIT_ARRAY25Array with addresses of init fct
DT_FINI_ARRAY26Array with addresses of fini fct
DT_INIT_ARRAYSZ27Size in bytes of DT_INIT_ARRAY
DT_FINI_ARRAYSZ28Size in bytes of DT_FINI_ARRAY
DT_RUNPATH29Library search path
DT_FLAGS30Flags for the object being loaded
DT_ENCODING32Start of encoded range
DT_LOOS1610612749
DT_HIOS1879044096
DT_VALRNGLO1879047424
DT_VALRNGHI1879047679
DT_ADDRRNGLO1879047680
DT_ADDRRNGHI1879047935
DT_VERSYM1879048176
DT_RELACOUNT1879048185
DT_RELCOUNT1879048186
DT_FLAGS_11879048187
DT_VERDEF1879048188
DT_VERDEFNUM1879048189
DT_VERNEED1879048190
DT_VERNEEDNUM1879048191
DT_LOPROC1879048192
DT_HIPROC2147483647

Example

import "elf"

rule HasSymTab {
    condition:
        for any dyn in elf.dynamic : (
           dyn.type == elf.DT_SYMTAB
        )
}

Machine

These are the possible values of the machine field.

NameValueDescription
EM_NONE0x0000No type
EM_M320x0001AT&T WE 32100
EM_SPARC0x0002SPARC
EM_3860x0003Intel 80386
EM_68K0x0004Motorola 68000
EM_88K0x0005Motorola 88000
EM_IAMCU0x0006Intel MCU
EM_8600x0007Intel 80860
EM_MIPS0x0008MIPS I Architecture
EM_S3700x0009IBM S370
EM_MIPS_RS3_LE0x000AMIPS RS3000 Little-endian
EM_PPC0x0014PowerPC
EM_PPC640x001564-bit PowerPC
EM_ARM0x0028ARM
EM_X86_640x003EAMD/Intel x86_64
EM_AARCH640x00B764-bit ARM

Example

import "elf"

rule SparcELF {
    condition:
        elf.machine == elf.EM_SPARC
}

SectionType

Each of the possible values for the type field in the Section structure.

NameValueDescription
SHT_NULL0Section header table entry unused
SHT_PROGBITS1Program data
SHT_SYMTAB2Symbol table
SHT_STRTAB3String table
SHT_RELA4Relocation entries with addends
SHT_HASH5Symbol hash table
SHT_DYNAMIC6Dynamic linking information
SHT_NOTE7Notes
SHT_NOBITS8Program space with no data (bss)
SHT_REL9Relocation entries, no addends
SHT_SHLIB10Reserved
SHT_DYNSYM11Dynamic linker symbol table
SHT_INIT_ARRAY14Array of constructors
SHT_FINI_ARRAY15Array of destructors

Example

import "elf"

rule ElfWithRelocations {
    condition:
        for any section in elf.sections : (
           section.type == elf.SHT_REL or
           section.type == elf.SHT_RELA or
        )
}

SegmentFlags

Possible flags in the flags fields of the Segment structure.

NameValueDescription
PF_X0x01Segment is executable
PF_W0x02Segment is writable
PF_R0x04Segment is readable

Example

import "elf"

rule WritableExecutableSegment {
    condition:
        for any segment in elf.segments : (
           segment.flags & elf.PF_W != 0 and
           segment.flags & elf.PF_X != 0
        )
}

SegmentType

NameValueDescription
PT_NULL0The array element is unused
PT_LOAD1Loadable segment
PT_DYNAMIC2Segment contains dynamic linking info
PT_INTERP3Contains interpreter pathname
PT_NOTE4Location & size of auxiliary info
PT_SHLIB5Reserved, unspecified semantics
PT_PHDR6Location and size of program header table
PT_TLS7Thread-Local Storage
PT_GNU_EH_FRAME1685382480
PT_GNU_STACK1685382481
PT_GNU_RELRO1685382482
PT_GNU_PROPERTY1685382483

SymBind

NameValueDescription
STB_LOCAL0Local symbol
STB_GLOBAL1Global symbol
STB_WEAK2Weak symbol

SymType

NameValueDescription
STT_NOTYPE0Symbol type is unspecified
STT_OBJECT1Symbol is a data object
STT_FUNC2Symbol is a code object
STT_SECTION3Symbol associated with a section
STT_FILE4Symbol's name is file name
STT_COMMON5Symbol is a common data object
STT_TLS6Symbol is thread-local data object

SymVisibility

NameValueDescription
STV_DEFAULT0Visibility by binding
STV_INTERNAL1Reserved
STV_HIDDEN2Not visible to other components
STV_PROTECTED3Visible in other but cannot be preempted.

Type

NameValueDescription
ET_NONE0x0000No type
ET_REL0x0001Relocatable
ET_EXEC0x0002Executable
ET_DYN0x0003Shared-Object-File
ET_CORE0x0004Corefile
ET_LOPROC0xFF00Processor-specific
ET_HIPROC0x00FFProcessor-specific