KXDB Database
Database concept
The traditional approach to kernel exploits involves embedding target-specific information (such as symbol, function, ROP gadget, and stack pivot addresses, along with structure and field sizes/offsets) directly into the exploit’s source code using #define
s. While these values can be replaced when porting, this method requires the exploit to be manually modified and recompiled for every new target.
kernelXDK decouples this target-specific information from the exploit by storing it in a database. This database contains data for multiple targets, allowing the exploit to dynamically detect the running target and use the correct offsets at runtime (rather than at compile time).
KXDB file format
To store this information, we introduced a new binary file format called the Kernel eXploit DataBase (KXDB), with the file extension .kxdb
.
The precise structure of this file format is detailed in the kxdb_file_format.txt file.
This database offers flexible integration: it can be included directly into the exploit binary as a binary blob, read from a separate file, or a combination of both approaches can be used. For instance, an exploit can be built with an up-to-date database at compilation time, yet allow it to be replaced with a newer version by placing the .kxdb
file next to the exploit binary.
Design goals
Minimize size:
Binary format instead of text.
Avoid unnecessary repetiton: e.g. if a structure layout is identical across two targets, it’s stored only once.
Variable-size integers to eliminate unnecessary zero bytes.
Backwards compatibility and extendibility:
Minor versions can introduce new fields without breaking backwards compatibility, allowing older exploits to utilize new database files.
Major versions can introduce breaking changes.
Searchable and seekable*:
Seekable structures allow skipping unnecessary information (e.g. data for non-current targets).
Internal structures are organized alphabetically to allow binary searching.
Optimized for parsing:
Strings are stored as length-prefixed, zero-terminated strings so standard C APIs (e.g.
strcmp
) can be used directly.
*Note: While the format is designed to be searchable and seekable, the current libxdk
implementation reads the entire metadata section and performs linear searches for targets, and reads all target-specific information. This will be optimized in a future release.
Contents
symbol addresses - e.g.
prepare_kernel_cred
,init_nsproxy
,anon_pipe_buf_ops
ROP actions (configurable ROP chains which execute predefined functionality):
msleep(ARG_time_msec)
commit_creds(prepare_kernel_cred(&init_task))
switch_task_namespaces(find_task_by_vpid(ARG_vpid=1), init_nsproxy)
write_what_where_64(ARG_address, ARG_new_value)
fork()
telefork(ARG_sleep_msec=0xffffffff)
ret_via_kpti_retpoline(ARG_user_rip, ARG_user_cs, ARG_user_rflags, ARG_user_sp, ARG_user_ss)
structure names, sizes
field names, offsets and sizes
stack pivots:
one gadgets (e.g.
mov rsp, rdi
)push indirects (e.g.
push rsi ; jmp qword [rsi+0x30]
)pop rsps (e.g.
pop rsp; ret
)stack shifts
target information
distribution (e.g.
kernelctf
orubuntu
)release name (e.g.
lts-6.12.40
)version (contents of
/proc/version
)
Configuration file
You can configure the database contents using the file located at kxdb_tool/config.py. Once configured, a new database can be generated by running the DB: upgrade to new config GitHub Action workflow (this requires assistance from a project maintainer).
kernelCTF KXDB distribution
The latest database version, which includes all kernelCTF targets, is available at https://storage.googleapis.com/kernelxdk/db/kernelctf.kxdb.
This file is updated daily via the DB: add missing releases Github Action workflow.