Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Davide Berardi - Linux hardening and security measures against Memory corruption

94 views

Published on

The exploding popularity of Embedded/IoT computing facilitate this security problems using low or non-existent security policies and exploits countermeasures. So why not explore some security measures that are widely available in the Linux world? We will focus on memory corruption techniques.

The Linux kernel was always focused on security features and giving bad times to the exploiters. This talk will introduce some common exploits and techniques, showing the mitigations employed by the kernel. By focusing on the major threats that affects modern Linux boxes, we will see which are the main features that can give problems to the system administator and how a preliminary penetration test can be done, ensuring that the system is in a sane state. The talk will also focus on problematics of embedded/IoT Unix systems, showing how some recent attacks gained control over a big network of devices and how a simple embedded system can be analyzed, hunting for bugs. Talk outline: Penetration testing, Linux, netfilter/bpf, memory corruption, ASLR, Spectre/Meltdown.

Published in: Software
  • Be the first to comment

  • Be the first to like this

Davide Berardi - Linux hardening and security measures against Memory corruption

  1. 1. Linux hardening and mitigations against memory corruption Davide Berardi 3 december 2018
  2. 2. Who am I? Davide Berardi ▶ davide.berardi6@unibo.it ▶ PhD @ University of Bologna since november 2018. ▶ Firmware Engineer @ T3Lab since december 2016.
  3. 3. Memory Corruption Why I’m talking about this old vulnerability class CVE-2018-5188 Memory safety bugs present in Firefox 60 [...] Some of these bugs showed evidence of memory corruption and we presume that with enough effort that some of these could be exploited to run arbitrary code. [...] CVE-2018-6069 Stack buffer overflow in Skia in Google Chrome prior to 65.0.3325.146 allowed a remote attacker to perform an out of bounds memory read via a crafted HTML page. CVE-2018-16842 Curl versions 7.14.1 through 7.61.1 are vulnerable to a heap-based buffer over-read in the tool_msgs.c:voutf() function that may result in information exposure and denial of service.
  4. 4. Spooky stories!
  5. 5. Buffer Overflow Introduction C Code uint32_t a; unsigned char b[4]; ASM sub esp,0x8 a b
  6. 6. Buffer Overflow Introduction C Code int foo(int _) { } foo(a); ASM call foo Local parameters Return address Saved state Local variables
  7. 7. Buffer Overflow Introduction C Code int foo(int _) { uint32_t a; char b[4]; return 0; } Local parameters Return address Saved State a b
  8. 8. Buffer Overflow Introduction C Code int foo(int _) { uint32_t a; char b[4]; ==> gets(b); return 0; } Local parameters Return address Saved State a b
  9. 9. Buffer Overflow Introduction C Code int foo(int _) { uint32_t a; char b[4]; ==> gets(b); return 0; } Local parameters Return address Saved State a A A A A
  10. 10. Buffer Overflow Introduction C Code int foo(int _) { uint32_t a; char b[4]; ==> gets(b); return 0; } Local parameters Return address Saved State aA A A A A A A A
  11. 11. Buffer Overflow Introduction C Code int foo(int _) { uint32_t a; char b[4]; ==> gets(b); return 0; } Local parameters Return address A A A A A A A A A A A A
  12. 12. Buffer Overflow Introduction C Code int foo(int _) { uint32_t a; char b[4]; ==> gets(b); return 0; } Local parameters A A A A A A A A A A A A A A A A
  13. 13. Buffer Overflow Introduction C Code int foo(int _) { uint32_t a; char b[4]; gets(b); ==> return 0; } Local parameters A A A A A A A A A A A A A A A A
  14. 14. Buffer Overflow Introduction
  15. 15. Buffer Overflow Shellcode ▶ Inject code in the application. xor %eax,%eax push %eax push $0x68732f2f push $0x6e69622f mov %esp,%ebx push %eax push %ebx mov %esp,%ecx mov $0xb,%al int $0x80 syscall(11, "/bin/sh"); or, in equal words exec("/bin/sh");
  16. 16. Buffer Overflow Shellcode C Code int foo(int _) { uint32_t a; char b[4]; gets(b); ==> return 0; } Local parameters 0x...... Shellcode
  17. 17. Buffer Overflow Shellcode
  18. 18. Mitigation Non executable stack ▶ What if the stack was not executable? ▶ PaX patch suite. ~ % checksec --output csv -f $(which ping) | awk -F , '{print␣$3}' NX enabled
  19. 19. Buffer Overflow Introduction
  20. 20. Buffer Overflow Return 2 libc C Code int foo(int _) { uint32_t a; char b[4]; gets(b); ==> return 0; } Local parameters Address of system Padding
  21. 21. Buffer Overflow Return 2 libc C Code int foo(int _) { uint32_t a; char b[4]; gets(b); ==> return 0; } Previous AR Fake return Address of system Padding
  22. 22. Buffer Overflow Return 2 libc C Code int foo(int _) { uint32_t a; char b[4]; gets(b); ==> return 0; } Address of ”/bin/sh” Fake return Address of system Padding
  23. 23. Buffer Overflow Return Oriented Programming ▶ What the attacker can do if the programs doesn’t have any useful target function? ▶ e.g. no libc or no useful (for the exploitation) functions at all. ▶ Weird machines! Weird MachineInput Output Malicious Input Exploit
  24. 24. Buffer Overflow ROP¹ ASM gadget1: mov eax, 11; ret ASM gadget2: mov ebx,&"/bin/sh"; ret ASM gadget3: mov ecx,&&"/bin/sh"; ret ASM gadget4: mov edx,0; ret ASM gadget5: int 0x80; ret Fake Return Address of gadget5 Address of gadget4 Address of gadget3 Address of gadget2 Address of gadget1 Padding ¹simplified
  25. 25. Mitigation ASLR ▶ Attackers need the address of functions and gadgets. ▶ Address Source Layout Randomization. ▶ cat /proc/sys/vm/mmap_rnd_bits $ ldd $(which whoami) | awk '/libc/{print␣$NF}' (0x00007f6586ee8000) $ ldd $(which whoami) | awk '/libc/{print␣$NF}' (0x00007f7bba165000)
  26. 26. Information Leak printf format parameter leak C Code: #include <stdio.h> #include <stdint.h> int main(int argc, char **argv) { uintptr_t token = 0x1234; return printf(argv[1]); } Exploit: $ ./foo hello hello $ ./foo %p 0x7ffedf09fb10 $ ./foo %9$p 0x1234
  27. 27. Information Leak Fork ASLR ▶ Fork won’t change process mappings. #include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main() { if (fork()) { printf("C:␣%pn", printf); return 0; } printf("P:␣%pn", printf); wait(NULL); return 0; } $ /tmp/test C: 0x7f99c155b3a0 P: 0x7f99c155b3a0 $ /tmp/test C: 0x7f8bc12253a0 P: 0x7f8bc12253a0
  28. 28. Side channels Spectre CVE-2017-5753 ▶ Spectre is a CPU bug tied to the BPU and the Cache. ▶ On a wrong guess of the BPU the cache isn’t invalidated. ▶ This can lead us to Information Leak.
  29. 29. Side channels Spectre CVE-2017-5753 Cache ... if (a < b) array2[array1[a]] ”warning” return
  30. 30. Side channels Spectre CVE-2017-5753 Cache array2[array1[a]] if (a < b) array2[array1[a]] ”warning” return
  31. 31. Side channels Spectre CVE-2017-5753 Cache array2[array1[a]] if (a < b) array2[array1[a]] ”warning” return
  32. 32. Side channels Spectre CVE-2017-5753 Cache ... if (a < b) array2[array1[a]] ”warning” return
  33. 33. Side channels Spectre CVE-2017-5753 Cache ... if (a < b) array2[array1[a]] ”warning” return
  34. 34. Side channels Spectre CVE-2017-5753 Cache array2[array1[a]] if (a < b) array2[array1[a]] ”warning” return
  35. 35. Side channels Spectre CVE-2017-5753 Cache array2[array1[a]] ▶ Now we can leak the memory! ▶ array1[a] == 2 array2[0] ∆time ∼= x array2[1] ∆time ∼= x array2[2] ∆time ≪ x
  36. 36. Mitigation Stack canaries gcc -fstack-protector{,-all,-strong,-explicit} mov %fs:0x28,%rax mov %rax,-0x8(%rbp) ... mov -0x8(%rbp),%rcx xor %fs:0x28,%rcx je foo+131 callq stack_chk_fail ... Local parameters Return address Stack Canary Saved State a b
  37. 37. Mitigation Stack canaries ▶ Terminator Canary 0x000d0aff ▶ Random Canary 0xXXXXXXXX ▶ Xor Canary 0xXXXXXXXX ⊕ Data ▶ Pointer Encryption QARMAE(Ret.Addr)
  38. 38. Memory Corruptions -fsanitize Vulnerable program: #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { void *s[64] = {}; printf("%pn", s[63 - atoi(argv[1])); return 0; } $ clang test.c $ ./a.out 1 (nil) $ ./a.out 2 (nil) $ ./a.out -1 0x7ffe3187bf10
  39. 39. Memory Corruptions -fsanitize
  40. 40. Fuzzer AFL ▶ American Fuzzy Lop.
  41. 41. Advanced attacks ▶ Heap Overflow; ▶ Integer overflow; ▶ Race conditions (TOCTTOU, Dirty cow, ...); ▶ Type confusion; ▶ Data only attacks; ▶ Side channels (Spectre, Meltdown, RowHammer, ...); ▶ sROP.
  42. 42. Advanced mitigations ▶ RelRO. ▶ PIE. ▶ Memory Tagging. ▶ Pointer Authentication. ▶ OpenBSD-style malloc. ▶ BPF_HARDEN. ▶ Shadow stacks. ▶ Alloca Checks. ▶ Guard Pages. ▶ PAX and GRSEC patches (PAX_REFCOUNT, PAX_SIZE_OVERFLOW, PAX_USERCOPY, PAX_MEMORY_STACKLEAK, PAX_MEMORY_STRUCTLEAK, PAX_MEMORY_SANITIZE, GRSEC_HIDESYM, PAX_CONSTIFY_PLUGIN, PAX_MEMORY_UNDERREF, ...). ▶ CFI / GRSEC RAP.
  43. 43. Thank you for your attention.
  44. 44. Mitigration Shadow stacks ▶ A shadow stack is a stack which is not editable by the attacker. ▶ Upon a return from a procedure the application will compare the call-stack values and its shadow values, if they differs an exception is raised. Shadow Stack Exec ReturnInput Output compare
  45. 45. Mitigation Guard Pages ▶ A guard page memory page is placed between the stack and the heap. Stack Heap Stack Heap Guard
  46. 46. Other problems Alloca and VLA ▶ alloca will allocate memory on the stack, this facilitates stack smashing and stack overflow! ▶ There are alloca checkers, so you can trace and hunt bugs based on this feature. int *x = alloca(3 * sizeof(int)); ▶ VLA (variable length arrays), allocated using alloca. ▶ Security Nightmare (and bad practice)! int foo(int a) { int x[a]; }
  47. 47. Mitigation RelRO ▶ A position indipendent executable can be placed in every part of the memory. ▶ The linker need to use two tables to load the dependencies: GOT and PLT; <main> callq 1030 <printf@plt > ... <printf@plt >: jmpq *0x2fe2(%rip) # printf@GLIBC_2.2.5 pushq $0x0 jmpq 1020 <.plt> ▶ These tables are still writable and can hijack functions! ▶ RelRO places this tables in read only memory, so you need to known only an offset at loading time.
  48. 48. Buffer Overflow SROP ▶ Using rop we can allocate on the stack a gadget which contains sigreturn systemcall. ▶ Before that we can place a sigcontext_t fake structure. ▶ The program will return to the allocated context, effectively running our shellcode. gadgetsigreturn sigcontext_t ▶ Mitigations are similar to the one described for stack smashing: Signal cookies (stack canaries), ASLR, ... ▶ Disabled vsyscall support.
  49. 49. Mitigations Intel MPX ▶ From Intel generation 6 (Sky lake). ▶ Registers and instructions to check if pointer bounds are valid. BNDCU BND2
  50. 50. Buffer Overflow Heap Overflow ▶ We can hijack malloc control fields (malloc-maleficarium, House of Einherjar). #include <cstdio > #include <cstring > class O { private: char buf[256]; public: void getusr(char *b) { strcpy(buf, b); } virtual void print() { printf("%sn", buf); } }; int main(int argc, char **argv) { O *o[2]={new O(), new O()}; o[0]->getusr(argv[1]); o[1]->getusr(argv[2]); o[0]->print(); o[1]->print(); }
  51. 51. Buffer Overflow Heap overflow o[0]->buf o[0]->vtable o[1]->vtable o[1]->buf o[0]->vtable AAAA AAAA BBBB
  52. 52. Side channels Row hammer ▶ Data handling in DRAM is supscetible to massaging. ▶ Resolved in LPDDR4. ▶ Can bypass ECC! Write Manipulated
  53. 53. Control Flow Integrity clang −fsanitize= c f i −f v i s i b i l i t y =hidden −f l t o ▶ You can view your program as a graph. ▶ Forward-edge-control-flow-integrity ▶ Backward-edge-contol-flow-integrity typedef void *(*foo_t)(void *); void *foo(void *_) { ... } void *bar(void *_) { ... } foo_t foos[2]; int main(int argc, char **argv) { return foo[atoi(argv[1][0])](NULL); }
  54. 54. Side channels MeltDown ▶ For performance memory mapping is not changed upon a context switch (but is protected using a guard value). raise_exception(); // the line below is never reached access(probe_array[data * 4096]); ▶ With KAISER the kernel get swapped out from the user space.
  55. 55. Side channels SpectreV2 ▶ Indirect branch predictions. C: class Base { public: virtual void Foo() = 0; }; class Derived : public Base { public: void Foo() override { … } }; Base* obj = new Derived; obj->Foo(); ASM: ... jmp [r15] ...
  56. 56. Side channels Spectre Mitigations ▶ LFENCE - serialization instruction; ▶ Retpoline - hack to avoid processor speculation on indirect branch prediction. jmp [r15] Retpoline will rewrite this indirect call to: call set_up_target loop: pause jmp loop set_up_target: mov r15, [rsp] ret lfence ; All instructions ; are serialized.
  57. 57. Fuzzer Syzkallerz
  58. 58. Kernel Self Protection Project ▶ Not protecting user space applications. ▶ Not protecting versus specific attacks. ▶ But protecting the kernel itself from attack classes. ▶ https: //kernsec.org/wiki/index.php/ Kernel_Self_Protection_Project

×