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 #defines. 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 or ubuntu)

    • 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.