Upgrade to Pro — share decks privately, control downloads, hide ads and more …

$Hell on Sony Snatch the Kernel privilage from Browser

$Hell on Sony Snatch the Kernel privilage from Browser

Talk at KernelVM Kanto#13

Ren Kimura

July 22, 2017
Tweet

More Decks by Ren Kimura

Other Decks in Technology

Transcript

  1. $Hell on Sony: Snatch the Kernel privilage from Browser Ren

    Kimura (@RKX1209) 2017/7/22 Kernel/VM Kanto #13
  2. Aboutme • Ren Kimura - Twitter: @RKX1209 • Japanese student

    at Kobe University (M1) • Research topic: Exploit and Vulnerability detection in Kernel. • https://rkx1209.github.io/about
  3. Background • Today, Browsers can be critical Attack Surface ◦

    Many browsers in the world. (Android, iOS, PlayStation4, Nintendo Switch ….etc ) ◦ And also Many Vulnerabilities in them. (See: pwn2own ) • Only browser exploitation? No. The next step comes up to you! ◦ To get higher privilage, (i.e. root) you should do more works! ◦ Kernel Vulnerabilities are good for you to get higher privilage. ◦ Many kinds of target, Linux, Windows, Apple OS X …. • Real world exploitation? ◦ Competition: pwn2own ◦ JailBreak: iOS, Android, PlayStation4 …. etc
  4. CVE-2014-1303 • WebKit Heap based Buffer Overflow ◦ CSSSelectorList OOB

    Read ◦ When RuleSet::AddRule is called, selectorIndex is 1 ◦ However, we have only ONE CSSSelector in array. ◦ Read non existed second element in array. (OOB Read) • Not only OOB Read, But you can also 1-bit OOB Write! ◦ WebCore::CSSSelector::specify modifies some value from 0 to 1. ◦ So set the only 1 bit to 1 in OOB area! • Restrictive 1-bit write ◦ Where to set the bit to 1? ◦ ArrayBufferView->m_sizeInBytes (from 0x40 -> 0xC0) is good idea!
  5. From 1-bit write to 0x80 Read/Write Crafted ArrayBufferView can read/write

    0x80(0xC0 - 0x40) byte CSSSelector 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk:
  6. From 1-bit write to 0x80 Read/Write Crafted ArrayBufferView can read/write

    0x80(0xC0 - 0x40) byte CSSSelector 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk: ArrayBuffer->m_sizeInByte = 0x40
  7. From 1-bit write to 0x80 Read/Write Crafted ArrayBufferView can read/write

    0x80(0xC0 - 0x40) byte CSSSelector 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk: ArrayBuffer->m_sizeInByte = 0xC0 (1-bit write) Overflow! You can Read/Write 0x80 byte -> What to Read?
  8. From 1-bit write to 0x80 Read/Write Crafted ArrayBufferView can read/write

    0x80(0xC0 - 0x40) byte CSSSelector 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk: ArrayBuffer->m_sizeInByte = 0xC0 (1-bit write) Overflow! You can Read/Write 0x80 byte -> What to Read?... WebCoreObj->vtable Leak WebCoreObject->vtable address
  9. From 0x80 Read/Write to AAR/AAW • 0x80 Read/Write is bit

    restricted. What’s next? ◦ We only need 0x40 WebCore object containing vtable ◦ After leaking the vtable of 0x40 WebCore object, free it and fill it with ArrayBufferView at same address. ◦ Then change ArrayBufferView::m_baseAddress poiter for AAR/AAW. • How to free 0x40 WebCore object? ◦ There are no free interface in JavaScript, which uses GC. ◦ Some object, like WebCore::NumberInputType can freed by following code :)
  10. From 0x80 Read/Write to AAR/AAW Create WebCore::NumberInput and free. CSSSelector

    0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data 0x40 NumberInput ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk: Create WebCore::NumberInput
  11. From 0x80 Read/Write to AAR/AAW Create WebCore::NumberInput and free. CSSSelector

    0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data Freed ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk: Free WebCore::NumberInput
  12. From 0x80 Read/Write to AAR/AAW Assign ArrayBufferView to freed Chunk

    CSSSelector 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data 0x40 ArrayBufferView ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk: Create ArrayBufferView
  13. From 0x80 Read/Write to AAR/AAW Allocate 0x20000 chunks CSSSelector 0x20

    ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data 0x40 ArrayBufferView ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk: ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data 0x20000 Chunk:
  14. From 0x80 Read/Write to AAR/AAW Modify m_baseAddress using 0x80 Write.

    CSSSelector 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data 0x40 ArrayBufferView ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk: ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data 0x20000 Chunk: Modify ArrayBufferView::m_baseAddress
  15. From 0x80 Read/Write to AAR/AAW m_baseAddress is now pointing to

    0x20000 chunk (exploit payload is here) CSSSelector 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data 0x40 ArrayBufferView ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk: ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data 0x20000 Chunk: m_baseAddress point to 0x20000 chunk
  16. From AAR/AAW to Code Execution • Return Oriented Programming (ROP)

    ◦ Exploit technique ◦ Control call stack to hjiack program flow ◦ Can bypass NX protection 0x68ea123b 4096 0x63af9c00 0x691c000 0x6100a74f 0x0 0x62f10bd0 0x0 0x6711f000 0x68ea123b: pop rdx (arg3) ret 0x63af9c00: pop rsi (arg2) ret 0x6100a74f: pop rdi (arg1) ret 0x62f10bd0: pop rax (syscall num) ret 0x6711f000: syscall ret Stack
  17. From AAR/AAW to Code Execution • Return Oriented Programming (ROP)

    ◦ Exploit technique ◦ Control call stack to hjiack program flow ◦ Can bypass NX protection 0x68ea123b 4096 0x63af9c00 0x691c000 0x6100a74f 0x0 0x62f10bd0 0x0 0x6711f000 0x68ea123b: pop rdx (arg3) ret 0x63af9c00: pop rsi (arg2) ret 0x6100a74f: pop rdi (arg1) ret 0x62f10bd0: pop rax (syscall num) ret 0x6711f000: syscall ret Stack rdx = 4096
  18. From AAR/AAW to Code Execution • Return Oriented Programming (ROP)

    ◦ Exploit technique ◦ Control call stack to hjiack program flow ◦ Can bypass NX protection 0x68ea123b 4096 0x63af9c00 0x691c000 0x6100a74f 0x0 0x62f10bd0 0x0 0x6711f000 0x68ea123b: pop rdx (arg3) ret 0x63af9c00: pop rsi (arg2) ret 0x6100a74f: pop rdi (arg1) ret 0x62f10bd0: pop rax (syscall num) ret 0x6711f000: syscall ret Stack rdx = 4096 rsi = 0x691c000
  19. From AAR/AAW to Code Execution • Return Oriented Programming (ROP)

    ◦ Exploit technique ◦ Control call stack to hjiack program flow ◦ Can bypass NX protection 0x68ea123b 4096 0x63af9c00 0x691c000 0x6100a74f 0x0 0x62f10bd0 0x0 0x6711f000 0x68ea123b: pop rdx (arg3) ret 0x63af9c00: pop rsi (arg2) ret 0x6100a74f: pop rdi (arg1) ret 0x62f10bd0: pop rax (syscall num) ret 0x6711f000: syscall ret Stack rdx = 4096 rsi = 0x691c000 rdi = 0
  20. From AAR/AAW to Code Execution • Return Oriented Programming (ROP)

    ◦ Exploit technique ◦ Control call stack to hjiack program flow ◦ Can bypass NX protection 0x68ea123b 4096 0x63af9c00 0x691c000 0x6100a74f 0x0 0x62f10bd0 0x0 0x6711f000 0x68ea123b: pop rdx (arg3) ret 0x63af9c00: pop rsi (arg2) ret 0x6100a74f: pop rdi (arg1) ret 0x62f10bd0: pop rax (syscall num) ret 0x6711f000: syscall ret Stack rdx = 4096 rsi = 0x691c000 rdi = 0 rax = 0
  21. From AAR/AAW to Code Execution • Return Oriented Programming (ROP)

    ◦ Exploit technique ◦ Control call stack to hjiack program flow ◦ Can bypass NX protection 0x68ea123b 4096 0x63af9c00 0x691c000 0x6100a74f 0x0 0x62f10bd0 0x0 0x6711f000 0x68ea123b: pop rdx (arg3) ret 0x63af9c00: pop rsi (arg2) ret 0x6100a74f: pop rdi (arg1) ret 0x62f10bd0: pop rax (syscall num) ret 0x6711f000: syscall ret Stack rdx = 4096 rsi = 0x691c000 rdi = 0 rax = 0 syscall read(0, 0x691c000, 4096)
  22. From AAR/AAW to Code Execution • Return Oriented Programming (ROP)

    ◦ Stack pivot technique ◦ You can set own controled stack ◦ Firstly, jump to 0x6001e4c 0x68ea123b 4096 0x63af9c00 0x691c000 0x6100a74f 0x0 0x62f10bd0 0x0 0x6711f000 0x68ea123b: pop rdx (arg3) ret 0x63af9c00: pop rsi (arg2) ret 0x6100a74f: pop rdi (arg1) ret 0x62f10bd0: pop rax (syscall num) ret 0x6711f000: syscall ret Stack 0x6001e4c: pop rsp ret (own stack address) own stack address
  23. From AAR/AAW to Code Execution • Return Oriented Programming (ROP)

    ◦ Stack pivot technique ◦ You can set own controled stack ◦ Firstly, jump to 0x6001e4c 0x68ea123b 4096 0x63af9c00 0x691c000 0x6100a74f 0x0 0x62f10bd0 0x0 0x6711f000 0x68ea123b: pop rdx (arg3) ret 0x63af9c00: pop rsi (arg2) ret 0x6100a74f: pop rdi (arg1) ret 0x62f10bd0: pop rax (syscall num) ret 0x6711f000: syscall ret Stack 0x6001e4c: pop rsp ret (own stack address) own stack address rsp = (own stack address)
  24. From AAR/AAW to Code Execution modify vtable to stack pivot

    gadget and do ROP. ($rsp is pointing to 0x20000 chunk) CSSSelector 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 ArrayBuffer 0x20 Chunk: ArrayBuffer:: m_data 0x40 ArrayBufferView ArrayBuffer:: m_data 0x40 WebCoreObject ArrayBuffer:: m_data 0x40 Chunk: ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data ArrayBuffer:: m_data 0x20000 Chunk: Own stack for ROP
  25. From WebKit exploit to Kernel exploit • After WebKit compromise,

    Next we should move to Kernel exploit ◦ If you want do more complicated code execution, ROP is not usefull. (so many gadgets…) ◦ We should use ROP only for loading and jumping to payload from network. (i.e. stager) ◦ From remote, we can send Kernel exploit payload • Write payload(shellcode) in C ◦ Use only syscalls, because libc’s functions are bit difficult to use in shellcode. ◦ Compile C code with PIE option (shellcode can be loaded at any address) Client WebKit Controlled by ROP waiting paylod to execute... Send kernel exploit payload
  26. BadIRET (CVE-2014-9322) • Kernel vulnerability originally discoverd in Linux and

    FreeBSD ◦ When iret throws #SS exeception, one extra swapgs is perfomed ◦ GS register will switch to the userland GS whilst the kernel still expects kernel GS ◦ Userland GS is fully controllable by attacker ◦ After #SS exception and extra swapgs, kernel jump to do_general_protection ◦ “current” macro uses memory read with GS prefix 290 void do_general_protection(struct pt_regs *regs, long error_code) 291 { 292 struct task_struct *tsk; ... 306 tsk = current; ==> mov %gs:0xc780,%rbx 319 tsk->thread.error_code = error_code; 320 tsk->thread.trap_nr = X86_TRAP_GP;
  27. From %GS controll to 8-byte 0 write • Now, we

    can control %GS. Next? ◦ Forcus on force_sig_info() that’s called by do_general_protection int force_sig_info(int sig, struct siginfo *info, struct task_struct *t) { struct k_sigaction *action; … action = &t->sighand->action[sig-1]; action->sa.sa_handler = SIG_DFL; // SIG_DFL == 0 ... } • We can write 8-byte 0(SIG_DFL) to arbitrary address in kernel ◦ Use &t->sighand->action->sa.sa_handler = 0 for writing ◦ We can control address of &t (== current == %GS:0xc780)
  28. From %GS controll to 8-byte 0 write GS base current

    sighand FAKE_PERCPU FAKE_CURRENT Usermode memory Kernelmode memory CPU state You can write 0s to any kernel address
  29. From 8-byte 0 write to Code Execution • Where to

    write consecutive 8-byte 0s? ◦ Modify #PF handler in IDT(Interrupt Descriptor Table) to shellcode address ▪ This approach is used in PlayStation4(FreeBSD) exploit ▪ But in Linux, IDT is set to Read-only :( ◦ Moreover, Intel SMEP prevent direct jump to usermode area from kernelmode area • In kernel ROP(Return Orietend Programming) ◦ Use ROP gadgets in kernel binray(e.g. vmlinux) ◦ Can bypass SMEP ◦ Pivot the kernel stack to crafted stack in usermode area ◦ Disable SMEP by clearing some bits of CR4 register ◦ Finally jump to shellcode in usermode
  30. From 8-byte 0 write to Code Execution proc_iops subdir =

    0x00XXXX FAKE_PROC_DIR_ENTRY proc_root Usermode memory Kernelmode memory Write 0s to modify like: 0xffffXXXX… -> 0x0000XXXXX 0xffff800000000000 〜 0 〜 0x00007fffffffffff FAKE_IOPS ROP gadgets open(“/proc/XXX”) 1. Modify proc_root.subidr to FAKE_PROC_DIR_ENTRY 2. In usemode area, FAKE_PROC_DIR_ENTRY should be pointing to FAKE_IOPS 3. FAKE_IOPS points to Stack Pivot ROP gadget in Kernel. 4. xchg %rax(=FAKE_IOPS) %rsp 5. ROP began. Disable SMEP and jump to shellcode in usermode area. jump to shellcode in usermode area shellcode (Now SMEP is disabled)
  31. Sony PlayStation4 exploit • PlayStaion4 system overview ◦ OrbisOS is

    based on FreeBSD (Many custom syscalls are added) ◦ Many libraries (.sprx) and binary executable (.self) ◦ Internet Browser is based on WebKit • Some security problems in PS4 (fixed in latest version) ◦ Internet Browser is vulnerable against CVE-2012-3748, CVE-2014-1303... ◦ A kernel of OrbisOS is vulnerable aginast CVE-2014-9322(BadIRET) ◦ And also custom syscalls added by Sony have some vulnerablities.
  32. Sony PlayStation4 exploit • Usefull functions for exploiters in OribsOS

    ◦ sys_dynlib_XXX system calls … Dynamic linking for modules(.sprx) ◦ sys_jitshm_XXX system calls … For WebKit JIT memory area • WebKit exploit for PS4 ◦ CTurt’s PS4-playground: https://cturt.github.io/PS4-playground/ ◦ You can execute payload by using above site. • Kernel exploit for PS4 ◦ BadIRET exploit written by CTurt ◦ sys_dynlib_prepare_dlclose heap overflow by CTurt and qwertyoruiop