[−][src]Module sunrise_libuser::caps
Kernel Capabilities declaration
Every program loaded by Sunrise has to declare the kernel capabilities it wishes to use. Upon doing a privileged action (such as using a syscall, or creating an event for an IRQ), the kernel will check that the process was allowed to take this action.
The main use-case is to make privilege escalation more complicated. In Sunrise, an exploit only grants the capabilities of the process that was vulnerable, requiring more pivoting in order to gain better accesses. For instance, a vulnerability in the browser does not give rights to access the filesystem.
Programs declare their capabilities by putting them in the .kernel_caps
section of their ELF executable. Each capability is encoded on an u32. We
provide convenience functions to generate those capabilities. Most programs
will want to use the capabilities!
macro in order to generate this section.
The capabilities macro takes two arrays: the first contains a list of syscall numbers, and the second contains a list of raw capabilities. Syscalls are handled specially in order to make them easier to declare.
In addition, programs are expected to provide a KipHeader
, telling the
kernel various information about how to start the process - such as how much
memory it should allocate for the stack, or what the default priority of the
process is. Those are provided by the kip_header
macro.
Example
extern crate sunrise_libuser; use sunrise_libuser::{syscalls, caps, capabilities, kip_header}; use sunrise_libuser::caps::ProcessCategory; kip_header!(HEADER = caps::KipHeader { magic: *b"KIP1", name: *b"test\0\0\0\0\0\0\0\0", title_id: 0x0200000000001000, process_category: ProcessCategory::KernelBuiltin, main_thread_priority: 0, default_cpu_core: 0, reserved: 0, flags: 0, stack_page_count: 16, }); capabilities!(CAPABILITIES = Capabilities { svcs: [ syscalls::nr::SetHeapSize, syscalls::nr::QueryMemory, syscalls::nr::ExitProcess, syscalls::nr::CreateThread, syscalls::nr::StartThread, syscalls::nr::ExitThread, syscalls::nr::MapSharedMemory, syscalls::nr::UnmapSharedMemory, syscalls::nr::CloseHandle, syscalls::nr::WaitSynchronization, syscalls::nr::ConnectToNamedPort, syscalls::nr::SendSyncRequestWithUserBuffer, syscalls::nr::OutputDebugString, syscalls::nr::CreateSharedMemory, syscalls::nr::CreateInterruptEvent, syscalls::nr::SleepThread ], raw_caps: [caps::ioport(0x60), caps::ioport(0x64), caps::irq_pair(1, 0x3FF)], });
Structs
KipHeader | Header for Kernel Builtins. Can be found in the |
ProcessCategory | Category of the process. |
Functions
application_type | Declare the type of the application. 0 is a sysmodule, 1 is an application, 2 is an applet. Only one application can run at a time. |
debug_flags | Declares whether this application can be debugged (e.g. it allows the use of the debug syscalls on it), and whether it can debug other processes. |
handle_table_size | Declare the maximum number of live handles this process is allowed to have open. |
ioport | Allows the process to use the given IO Ports directly (through the in/out). |
irq_pair | Allows the process to create an IRQEvent for those IRQs. Each IRQ should be under or equal to 0xFF, or equal to 0x3FF, in which case the IRQ will be ignored. |
kernel_flags | Create a kernel flag capability. Specifies the lowest/highest priority this process is allowed to take, and which CPUs it is allowed to access. |
kernel_release_version | The minimum kernel version this process expects. |
map_normal_page | Maps the given physical memory page at a random address on process startup. |