Aller au contenu principal
own2pwn
elf/elf-intro.tsx

C'est quoi un ELF, et pourquoi t'en croises partout

Tour d'horizon du format ELF (Executable and Linkable Format) sous Linux x86_64 : compilation, identification d'un binaire avec file et strings, et premier apercu de la segmentation memoire.

Maxime Jérôme··4 min de lecture

Prerequis

Hello ! o/

Je vais vous introduire le format ELF (Executable and Linkable Format) sous architecture Intel x86_64, qui est le format de fichier le plus populaire pour la conception d'un fichier executable sous systemes Unix-like.

Creation d'un Programme

Commençons par la base, c'est-a-dire comment vous, lecteur, pouvez concevoir un programme. Voici un exemple simple :

c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    if (argc > 1) {
        fprintf(stderr, "[!] Error: Usage: ./program\n");
        exit(EXIT_FAILURE);
    }
    fprintf(stdout, "Hello World !\n");
    return EXIT_SUCCESS;
}

Pour compiler et executer ce programme, vous pouvez utiliser les commandes suivantes :

bash
$ gcc source.c -o program
$ ./program
Hello World !
$ ./program ARG
[!] Error: Usage: ./program

Dans cet exemple, notre programme source est source.c et le programme executable est program. Lorsque nous utilisons la commande file, nous voyons que notre programme executable est bien de format ELF :

file-output.txt
$ file program
program: ELF 64-bit LSB pie executable, x86-64,
         version 1 (SYSV),
         dynamically linked,
         interpreter /lib64/ld-linux-x86-64.so.2,
         BuildID[sha1]=...,
         for GNU/Linux 3.2.0,
         not stripped
Sortie de la commande file sur notre binaire compile : l'ABI (Application Binary Interface) x86_64 et le type ELF sont clairement identifies.

Analyse du Programme Executable

Sans entrer dans les details, si nous executons strings sur program, voici un extrait de la sortie que nous obtenons :

text
/lib64/ld-linux-x86-64.so.2
libc.so.6
exit
stdout
stderr
fwrite
main
...

On remarque que certaines chaines de caracteres sont hardcodees (mises en brut) dans le programme executable. Parmi les motifs identifiables, nous avons :

  • libc.so.6
  • GCC: (Debian 8.3.0-6) 8.3.0
  • fwrite
  • main
  • exit
  • stderr

Ces elements nous donnent un apercu de ce qui est encapsule dans le programme executable, mais ne revelent pas beaucoup d'informations exploitables.

Pourquoi strings revele autant ?
Un binaire compile en dynamique embarque des symboles de debug et des references aux bibliotheques partagees qu'il utilise. Compiler avec -s (strip) reduit mais ne supprime pas totalement ces informations.

Segmentation de la Memoire

Il est important de noter qu'un programme executable s'execute sur le CPU, et que la memoire chargee peut se situer physiquement en cache, en RAM, sur le disque dur ou ailleurs. De plus, le programme ne se charge pas dans un gros bloc d'adresses virtuelles ; il est divise en plusieurs segments dans la memoire.

memory-layout.txt
  Adresses virtuelles hautes
  ┌────────────────────────────────────────┐
  │              [stack]                   │  variables locales, adresses de retour
  │                 │                      │
  │                 ▼                      │
  │                                        │
  │                 ▲                      │
  │                 │                      │
  │              [heap]                    │  allocations dynamiques (malloc)
  ├────────────────────────────────────────┤
  │               .bss                     │  variables globales non initialisees
  ├────────────────────────────────────────┤
  │               .data                    │  variables globales initialisees
  ├────────────────────────────────────────┤
  │               .text                    │  code executable (lecture seule)
  ├────────────────────────────────────────┤
  │  bibliotheques partagees (libc, ...)   │
  └────────────────────────────────────────┘
  Adresses virtuelles basses
Disposition typique des segments d'un binaire ELF 64-bit en memoire virtuelle au moment de l'execution.