the elf in elf
play

The elf in ELF use 0-day to cheat all disassemblers david942j @ - PowerPoint PPT Presentation

The elf in ELF use 0-day to cheat all disassemblers david942j @ CyberSEC 2019 1 . 1 This talk Tricks to cheat disassemblers objdump, readelf, IDA Pro, etc. 2 . 1 IDA Pro The best tool for reverse-engineering Take it as examples in this


  1. The elf in ELF use 0-day to cheat all disassemblers david942j @ CyberSEC 2019 1 . 1

  2. This talk Tricks to cheat disassemblers objdump, readelf, IDA Pro, etc. 2 . 1

  3. IDA Pro The best tool for reverse-engineering Take it as examples in this talk 2 . 2

  4. anti-reverse-engineering - What you see is NOT what it really is IDA Pro 2 . 3

  5. Introduction to ELF 3 . 1

  6. ELF Executable and Linkable Format Linux 3 . 2

  7. Header ELF header Section header (not important here) Program header 3 . 3

  8. 3 . 4

  9. ELF header ELF class: 32 / 64-bit arch: x86 / ARM / MIPS .. section / program header 3 . 5

  10. Section header (static linker) ELF .text , .rodata , etc. 3 . 6

  11. Program header Needed Libraries, Segment Permissions, etc. _DYNAMIC table 3 . 7

  12. _DYNAMIC 3 . 8

  13. Example #include <stdio.h> #include <iostream> using std::cout; int main() { char s[100] = {}; scanf("%99s", s); // libc.so.6#scanf cout << "Hello, " << s << "!\n"; // libstdc++.so.6#std::cout return 0; } 3 . 9

  14. _DYNAMIC Need libraries: libc.so.6, libstdc++.so.6 Need functions: scanf & std::cout ld.so _DYNAMIC function 3 . 10

  15. In this talk IDA Pro _DYNAMIC table e.g. IDA Pro printf system 0-day bug in Linux kernel Bug(?) in ld.so 3 . 11

  16. The Linux 0-day bug 4 . 1

  17. PT_LOAD 4 . 2

  18. PT_LOAD Program header PT_LOAD entry ELF memory 4 . 3

  19. PT_LOAD 4 . 4

  20. Memory mapping ELF file In memory 0x0 0x400000 ELF header program header many tables.. executable executable code .rodata .eh_frame 0x400e08 0xe08 ... .init_array/.fini_array 0x600000 .dynamic 0x600e08 .data/.bss data 4 . 5

  21. Linux#execve 4 . 6

  22. linux/fs/binfmt_elf.c#load_elf_binary Read and check ELF header Parse program header PT_INTERP PT_LOAD PT_GNU_STACK Setup AUXV 4 . 7

  23. AUXV AUXiliary Vector interpreter(ld.so) AT_PHDR AT_ENTRY AT_UID ... 4 . 8

  24. Flow of execve execve("a.out", ... ) load_elf_binary mmap(PT_LOADs) kernel space load_elf_interp (ld.so) create_elf_tables (AUXV) *phdr, phnum, *entry, *auxv ld.so#dl_main load_libraries elf_dynamic_do_rela (relocation) 4 . 9

  25. Bug Kernel AT_PHDR 4 . 10

  26. binfmt_elf.c#create_elf_tables 4 . 11

  27. Normally load_addr exec->e_phoff 0x400000 0x40 0x400040 4 . 12

  28. load_addr is The �rst LOADed address 4 . 13

  29. ELF file In memory 0x0 0x400000 ELF header program header many tables.. executable executable code .rodata .eh_frame 0x400e08 0xe08 ... .init_array/.fini_array 0x600000 .dynamic 0x600e08 .data/.bss data 4 . 14

  30. Nobody promises PHDR is located in the �rst PT_LOAD 4 . 15

  31. Put PHDR in the second PT_LOAD 4 . 16

  32. ELF file In memory 0x0 0x400000 ELF header load_addr many tables.. executable code .eh_frame ... .init_array/.fini_array 0x4000 fake program header 0x604000 fake prog. hdr e_phoff .data .data 0x204000 program header 0x804000 program header 4 . 17

  33. Effect Kernel loads binary correctly But kernel cheats ld.so the address of PHDR 4 . 18

  34. ld.so 4 . 19

  35. ld.so ? Load shared libraries Process dynamic relocation 4 . 20

  36. _DYNAMIC 4 . 21

  37. function e.g. printf -> system 4 . 22

  38. 4 . 23

  39. Relocation type 1: scanf scanf@got type 2: put backdoor on scanf@got 4 . 24

  40. relocation table IDA scanf relocate 4 . 25

  41. lea rdi,[rip+0xba] int ret = scanf(args); mov eax,0x0 if ( trigger (args)) call 5f0 <scanf@plt> backdoor (); lea rdx,[rbp­0xe0] return ret; lea rax,[rbp­0x70] 4 . 26

  42. Demo 4 . 27

  43. Let's play ld.so 5 . 1

  44. PT_PHDR in Program header 5 . 2

  45. PT_PHDR points to itself ELF file ELF header program header PT_PHDR PT_LOAD PT_LOAD ... 5 . 3

  46. glibc/elf/rtld.c#1147 for (ph = phdr; ph < &phdr[phnum]; ++ph) switch (ph->p_type) { case PT_PHDR: /* Find out the load address. */ main_map->l_addr = phdr - ph->p_vaddr; break; case PT_DYNAMIC: /* This tells us where to find the dynamic section, which tells us everything we need to do. */ main_map->l_ld = main_map->l_addr + ph->p_vaddr; break; 5 . 4

  47. PT_PHDR ld.so binary ! 5 . 5

  48. the Linux kernel bug Program header for kernel for ld.so 5 . 6

  49. ? ld.so binary 5 . 7

  50. program header PT_PHDR main_map->l_addr = phdr - ph->p_vaddr PT_LOAD PT_LOAD PT_DYNAMIC main_map->l_ld = main_map->l_addr + ph->p_vaddr ... 5 . 8

  51. Use two PT_PHDR s 5 . 9

  52. glibc/elf/rtld.c#1147 for (ph = phdr; ph < &phdr[phnum]; ++ph) switch (ph->p_type) { case PT_PHDR: /* Find out the load address. */ main_map->l_addr = phdr - ph->p_vaddr; break; case PT_DYNAMIC: /* This tells us where to find the dynamic section, which tells us everything we need to do. */ main_map->l_ld = main_map->l_addr + ph->p_vaddr; break; 5 . 10

  53. Two PT_PHDR s PT_PHDR main_map->l_addr = phdr - ph->p_vaddr PT_DYNAMIC main_map->l_ld = main_map->l_addr + ph->p_vaddr PT_PHDR main_map->l_addr = phdr - ph->p_vaddr PT_LOAD PT_LOAD ... 5 . 11

  54. _DYNAMIC relocation 5 . 12

  55. Demo Given two ELFs Looks like A in IDA Pro but actually B 5 . 13

  56. Conclusion 6 . 1

  57. The Linux kernel 0-day bug Kernel calculates PHDR incorrectly ld.so gets wrong address of program header 6 . 2

  58. ld.so ld.so using PT_PHDR for calculating base address Nobody checks correctness of PT_PHDR 6 . 3

  59. _DYNAMIC table 6 . 4

  60. david942j @ 7 . 1

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend