Mémoire - protection : ASLR    Enregistrer au format PDF

Le chef d’oeuvre en matière de sécurité est certainement celui-ci. En effet, bon nombre d’exploits se basent sur la prédiction des adresses de retour, que ce soit dans la pile, dans le heap ou dans les librairies partagées. ASLR a ainsi été conçu pour éliminer ces classes d’exploits.


par Tosh , S3cur3D

Le programme ldd permet d’observer ces changements. Il place la variable d’environnement LD_TRACE_LOADED_OBJECTS à 1, qui va arrêter prématurément l’exécution d’un programme et afficher l’adresse de chargement des librairies partagées :

   $ ldd /bin/sh
   linux-gate.so.1 => (0xffffe000)
   libncurses.so.5 => /lib/libncurses.so.5 (0xb7fd6000)
   libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7fd2000)
   libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e74000)
   /lib/ld-linux.so.2 (0xb801e000)
   $ ldd /bin/sh

   linux-gate.so.1 => (0xffffe000)
   libncurses.so.5 => /lib/libncurses.so.5 (0xb7eb9000)
   libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7eb5000)
   libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7d57000)
   /lib/ld-linux.so.2 (0xb7f01000)
   $

Dans l’exemple précédent, on observe bien qu’entre deux exécutions successives, l’adresse de base du chargement des librairies est différente. Les différentes pages mémoires d’un processus sont également visibles dans /proc//maps.

ASLR rends aléatoire l’emplacement des bibliothèques partagées, de la stack et du heap.

Regardons deux exécutions de cat /proc/self/maps pour voir l’effet de l’ASLR :

$ cat /proc/self/maps
08048000-08053000 r-xp 00000000 08:03 1317757    /usr/bin/cat
08053000-08054000 r--p 0000a000 08:03 1317757    /usr/bin/cat
08054000-08055000 rw-p 0000b000 08:03 1317757    /usr/bin/cat
0857e000-0859f000 rw-p 00000000 00:00 0          [heap]
b74be000-b7514000 r--p 00000000 08:03 1330849    /usr/lib/locale/locale-archive
b7514000-b7515000 rw-p 00000000 00:00 0
b7515000-b76bd000 r-xp 00000000 08:03 1313428    /usr/lib/libc-2.18.so
b76bd000-b76be000 ---p 001a8000 08:03 1313428    /usr/lib/libc-2.18.so
b76be000-b76c0000 r--p 001a8000 08:03 1313428    /usr/lib/libc-2.18.so
b76c0000-b76c1000 rw-p 001aa000 08:03 1313428    /usr/lib/libc-2.18.so
b76c1000-b76c4000 rw-p 00000000 00:00 0
b76e3000-b76e4000 rw-p 00000000 00:00 0
b76e4000-b76e5000 r-xp 00000000 00:00 0          [vdso]
b76e5000-b7705000 r-xp 00000000 08:03 1313416    /usr/lib/ld-2.18.so
b7705000-b7706000 r--p 0001f000 08:03 1313416    /usr/lib/ld-2.18.so
b7706000-b7707000 rw-p 00020000 08:03 1313416    /usr/lib/ld-2.18.so
bfb72000-bfb93000 rw-p 00000000 00:00 0          [stack]
$ cat /proc/self/maps
08048000-08053000 r-xp 00000000 08:03 1317757    /usr/bin/cat
08053000-08054000 r--p 0000a000 08:03 1317757    /usr/bin/cat
08054000-08055000 rw-p 0000b000 08:03 1317757    /usr/bin/cat
09100000-09121000 rw-p 00000000 00:00 0          [heap]
b74c2000-b7518000 r--p 00000000 08:03 1330849    /usr/lib/locale/locale-archive
b7518000-b7519000 rw-p 00000000 00:00 0
b7519000-b76c1000 r-xp 00000000 08:03 1313428    /usr/lib/libc-2.18.so
b76c1000-b76c2000 ---p 001a8000 08:03 1313428    /usr/lib/libc-2.18.so
b76c2000-b76c4000 r--p 001a8000 08:03 1313428    /usr/lib/libc-2.18.so
b76c4000-b76c5000 rw-p 001aa000 08:03 1313428    /usr/lib/libc-2.18.so
b76c5000-b76c8000 rw-p 00000000 00:00 0
b76e7000-b76e8000 rw-p 00000000 00:00 0
b76e8000-b76e9000 r-xp 00000000 00:00 0          [vdso]
b76e9000-b7709000 r-xp 00000000 08:03 1313416    /usr/lib/ld-2.18.so
b7709000-b770a000 r--p 0001f000 08:03 1313416    /usr/lib/ld-2.18.so
b770a000-b770b000 rw-p 00020000 08:03 1313416    /usr/lib/ld-2.18.so
bf969000-bf98a000 rw-p 00000000 00:00 0          [stack]

On remarque que l’adressage est aléatoire, à part 3 plages mémoires :

 08048000-08053000 r-xp -> segment de CODE
 08053000-08054000 r—p -> segment DATA read only
 08054000-08055000 rw-p -> segment DATA read/write

Documentations publiées dans cette rubrique