Skip to content

Commit

Permalink
Add kernelCTF CVE-2023-5345 (lts & mitigation)
Browse files Browse the repository at this point in the history
  • Loading branch information
quanggle97 authored Oct 31, 2023
1 parent c00f2d6 commit 4ae8756
Show file tree
Hide file tree
Showing 13 changed files with 4,565 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Exploitation technique

To my knowledge, the following exploitation techniques are not known/publicly-documented:

## Leverage `struct netlink_sock` to get arbitrarily read/write primitive
- This technique is used in mitigation exploit.

### Advantages
- Do not need to setup network user namespace.
- Can read large bytes from specify address.
- Live in less noisy heap. Therefore, free the current fake `struct netlink_sock` object and reclaim with new address to read from or write to is very stable.
- Can be used to perform data only attack.

### Disadvantages
- Cannot read from invalid memory address.
- Can only write 4 bytes per fake `struct netlink_sock` object.
- Only allocate on kmalloc-2048 (dyn-kmalloc-2048 in mitigation instace).
- In case Apparmor is enabled, `sk-security` need to be valid pointer.

## Leverage `struct packet_fanout` to get arbitrarily free primitive
- This technique is used in mitigation exploit.

### Advantages
- Can be allocate on kmalloc-256 -> kmalloc-8192 (dyn-kmalloc-256 -> dyn-kmalloc-8192 in mitigation instance).

### Disadvantages
- Require CAP_NET_RAW to create packet socket.
- Need to setup data look like `struct packet_fanout` object in the free location. Let's call this location: A1.
- Need to control at least one `struct packet_fanout` object linked list. This fake linked list will be used to reach A1.

## Overlap `struct user_key_payload` object with `struct packet_fanout` object
- This technique is used in mitigation exploit.

```c
struct packet_fanout {
possible_net_t net;
unsigned int num_members;
u32 max_num_members;
u16 id;
u8 type;
u8 flags;
union {
atomic_t rr_cur;
struct bpf_prog __rcu *bpf_prog;
};
struct list_head list;
spinlock_t lock;
refcount_t sk_ref;
struct packet_type prot_hook ____cacheline_aligned_in_smp;
struct sock __rcu *arr[];
};
```

```c
struct packet_type {
__be16 type; /* This is really htons(ether_type). */
bool ignore_outgoing;
struct net_device *dev; /* NULL is wildcarded here */
netdevice_tracker dev_tracker;
int (*func) (struct sk_buff *,
struct net_device *,
struct packet_type *,
struct net_device *);
void (*list_func) (struct list_head *,
struct packet_type *,
struct net_device *);
bool (*id_match)(struct packet_type *ptype,
struct sock *sk);
struct net *af_packet_net;
void *af_packet_priv;
struct list_head list;
};
```

```c
static LIST_HEAD(fanout_list);
```
- Let's call the overlapped `struct packet_fanout`: pf.
### Advantages
- Can be overlapped in kmalloc-256 -> kmalloc-8192 (dyn-kmalloc-256 -> dyn-kmalloc-8192 in mitigation instace).
- Read "in object" heap only. This make the leak 100% success. Especially useful on mitigation instance where reading out-of-slab data lead to kernel crash.
- Each new allocated `struct packet_fanout` is inserted at the head of `fanout_list`. Therefore, read `pf->list.prev` will allow to leak heap address from kmalloc-256 -> kmalloc-8192 (dyn-kmalloc-256 -> dyn-kmalloc-8192 in mitigation instance).
- Read `pf->prot_hook.func` will give us address of `packet_rcv_fanout` kernel function. This can be used to calculate kernel base.
- Read `pf->prot_hook.id_match` will give us address of `match_fanout_group` kernel function. This can be used to calculate kernel base.
- Read `pf->prot_hook.af_packet_priv` will give us address of our overlapped `struct packet_fanout` object that we are currenly using.
- Read `pf->prot_hook.af_packet_net` will give us address of current `net` namespace.
### Disadvantages
- Require CAP_NET_RAW to create packet socket.
- Require specific primitive to make the overlap happen.
## Leverage `struct ovl_dir_file` to get code execution
- This technique is used in LTS instance.
### Advantages
- Need to control only `is_real` field and `realfile` field.
- When trigger code execution through lseek, RBP register set to `offset` value passed into lseek. Usually, we can find gadget like: `mov rsp, rbp; pop rbp; ret`.
### Disadvantages
- Require CAP_SYS_ADMIN to mount overlayfs.
- Allocate only on kmalloc-64.
- Need a place to store fake `struct file_operations` object with `lseek` pointer set to gadget address
- Need a place to store fake `struct file` object with `f_op` pointer set to fake `struct file` object.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Vulnerability

A double-free vulnerability was found in the Linux kernel's SMBFS subsystem (`fs/smb/client/fs_context.c`). Forget to reset pointer to NULL after kfree_sensitive makes it possible to trigger the free again on the same pointer.

## Requirements to trigger the vulnerability:
- Capabilities: To trigger the vulnerability, `CAP_SYS_ADMIN` capability is required to use fsopen syscall.
- Kernel configuration: `CONFIG_SMBFS` is required to trigger this vulnerability.
- Are user namespaces needed?: Yes. As this vulnerability requires `CAP_SYS_ADMIN`, which is not usually given to the normal user, we used the unprivileged user namespace to achieve this capability.

## Commit which introduced the vulnerability
- This vulnerability was introduced in Linux v6.0.16, with commit [a4e430c8c8ba96be8c6ec4f2eb108bb8bcbee069](https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=a4e430c8c8ba96be8c6ec4f2eb108bb8bcbee069)
- This commit replaced `kfree` with `kfree_sensitive`.

## Commit which fixed the vulnerability
- This vulnerability was fixed with commit [e6e43b8aa7cd3c3af686caf0c2e11819a886d705](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e6e43b8aa7cd3c3af686caf0c2e11819a886d705)

## Affected kernel versions
- Linux version 6.0.16 - 6.5.5 affects to this vulnerability

## Affected component, subsystem
- fs/smb/client

## Cause (UAF, BoF, race condition, double free, refcount overflow, etc)
- Double-free

## Which syscalls or syscall parameters are needed to be blocked to prevent triggering the vulnerability? (If there is any easy way to block it.)
- Block fsopen syscall with `smb3` in `_fs_name` parameter.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
exploit:
gcc -static exploit.c -o exploit -lkeyutils

prerequisites:
sudo apt-get install libkeyutils-dev

run:
./exploit

clean:
rm exploit
Binary file not shown.
Loading

0 comments on commit 4ae8756

Please sign in to comment.