Friday, June 13, 2014

Exploit NULL pointer dereference bug (ARM and x86)

A NULL pointer dereference occurs when a pointer with the value of 0 (NULL) is assumed to be a valid memory location, and that pointer is then accessed. A write from, or read to, the memory address 0x0 (+ small-offset) will generally reference invalid or unused memory, which typically leads to the majority of published denial-of-service (DoS) attacks both locally and remotely.

In x86 processor "real" mode, such an invalid memory space locates in IVT table(Interrupt Vector Table), so a NULL pointer dereference flaw will corrupt the IVT handlers. 

However, in modern operating system, at system runtime the "protected" mode is enabled/used and also virtual memory system is employed, hence an issue above won't exist any more. 

But now the invalid memory is mapped to user mode address space, so the attackers can use mmap() API to map the virtual address 0/NULL as valid address, then they can get the kernel to run your arbitrary code in privileged level. 

Please note that SMEP and SMAP can stop this kind of attacks, and besides, recent kernel has protection against mapping address 0 with mmap().

In ARM processor, typically the 0x0 address is not only mapped in memory, but also serves an Exception Vector Table (EVT), which is located starting from memory offset 0. 

When an exception is triggered on the ARM processor, execution is forced to a fixed memory offset that corresponds to the thrown exception. These fixed offsets are called the exception vectors. There are eight exception vectors, each 32 bits in length, mapped starting at address 0.

The ARM Exception Vector Table (EVT) 

  • 0x00000000: Not used (Reset in Secure state)
  • 0x00000004: Undefined instruction 
  • 0x00000008: Hypervisor, Supervisor or Security monitor call depending on processor mode.
  • 0x0000000c: Prefetch Abort vector
  • 0x00000010: Data Abort vector
  • 0x00000014: Hyp trap (not used for other mode)
  • 0x00000018: IRQ interrupt
  • 0x0000001c: FIQ interrupt

The EVT is a set of branch instructions that are executed when the corresponding exception is raised. If one were to overwrite this table, the flow of execution could be controlled by an attacker, allowing for exploitation with arbitrary code execution .

However, if the vector area is marked as non-writeable (read and executable) or the system software relocates EVT to high address memory (e.g. 0xFFFF0000) via HIVECS settings (e.g. Hyp Vector Base Address Register, or SCTRL.V bit=1), then this issue can be mitigated. 

However, why the EVT address can still be leaked as a hardcode 0xFFFF0000 in non-secure state?


No comments:

Post a Comment