AI prompts
base on Linux kernel CVE exploit analysis report and relative debug environment. You don't need to compile Linux kernel and configure your environment anymore. # kernel-exploit-factory
Keep updating......
Linux kernel CVE exploit analysis report and relative debug environment. You don't need to compile Linux kernel and configure your environment anymore.
This repository is to extract all Linux kernel exploit and relative debug environment. You can use Qemu to boot the kernel and test the exploit.
---
## Example
```bash
# Eg, test CVE-2017-11176, finally you levate privileges and get the shell
john@john-virtual-machine:~/Desktop/kernel-exploit-factory/CVE-2017-11176$ ./start.sh
chmod: /dev/csaw: No such file or directory
ifconfig: SIOCSIFADDR: No such device
route: SIOCADDRT: No such device
/ $ uname -a
Linux (none) 4.11.9 #1 SMP Sat Feb 20 21:52:39 CST 2021 x86_64 GNU/Linux
/ $ id
uid=1000(chal) gid=1000(chal) groups=1000(chal)
/ $ cd exp
/exp $ ./exp-slab-4119
[*] sk_rmem_alloc > sk_rcvbuf ==> ok
[*] mq_notify start
[*] wake up thread 1
... ...
/exp # id
uid=0(root) gid=0(root)
/exp #
```
---
## Catalog
1. CVE-2015-8550
2. CVE-2016-9793
3. 4-20-BPF-integer
4. CVE-2017-5123
5. CVE-2017-6074
6. CVE-2017-7308
7. CVE-2017-8890
8. CVE-2017-11176
9. CVE-2017-16995
10. CVE-2017-1000112
11. CVE-2018-5333
12. CVE-2019-9213 & CVE-2019-8956
13. CVE-2019-15666
14. CVE-2020-8835
15. CVE-2020-27194
16. CVE-2021-3156
17. CVE-2021-31440
18. CVE-2021-3490
19. CVE-2021-22555
20. CVE-2021-41073
21. CVE-2021-4154
22. CVE-2021-42008
23. CVE-2021-43267
24. CVE-2022-0185
25. CVE-2022-0847
26. CVE-2022-0995
27. CVE-2022-1015
28. CVE-2022-2588
29. CVE-2022-2602
30. CVE-2022-2639
31. CVE-2022-25636
32. CVE-2022-27666
33. CVE-2022-32250
34. CVE-2022-34918
35. CVE-2023-2598
36. CVE-2024-1086
---
## Detail
#### 1.CVE-2015-8550
[writeup](https://blog.csdn.net/panhewu9919/article/details/100891770)
**Test version**: Linux-4.19.65
**Protection**: 开启kaslr/SMEP,未开启SMAP。
**Vulnerability**: gcc 编译优化导致的**Double-Fetch漏洞**,可直接劫持控制流。
#### 2. CVE-2016-9793
[writeup](https://blog.csdn.net/panhewu9919/article/details/120164051)
**Test version**: Linux-4.8.13
**Protection**: 未开 KASLR/SMAP/SMEP。伪造的[skb_shared_info](https://elixir.bootlin.com/linux/v4.8.13/source/include/linux/skbuff.h#L414)结构在用户空间,显然不能绕过SMAP。
**Vulnerability**: `net/core/sock.c`中的 [sock_setsockopt()](https://elixir.bootlin.com/linux/v4.8.13/source/net/core/sock.c#L658) 函数**错误处理负值**,导致 `sk_sndbuf` 和 `sk_rcvbuf`取值为负。调用`write`时将`skb->head`和`skb->end`设置错误,最后调用`close`释放时会访问用户空间报错。用户空间地址`0xfffffed0`处伪造[skb_shared_info](https://elixir.bootlin.com/linux/v4.8.13/source/include/linux/skbuff.h#L414)结构,通过`skb_shared_info->destructor_arg->callback` 劫持控制流。
#### 3. 4-20-BPF-integer
[writeup](https://www.cnblogs.com/bsauce/p/11560224.html)
**Test version**: Linux-4.20.0-rc3
**Protection**: 开启SMEP,未开启kaslr/SMAP。
**Vulnerability**: Linux ebpf 模块中`queue_stack_map_alloc()`中**整数溢出**漏洞,导致堆溢出。修改虚表指针劫持控制流到`xchg eax, esp`。
#### 4.CVE-2017-5123
[writeup](https://www.jianshu.com/p/90a040114188)
**Test version**: Linux 4.14-rc4
**Protection**: 开启 SMEP / SMAP,关闭KASLR。
**Vulnerability**: `/kernel/exit.c`中的`waitid`的实现,在调用`unsafe_put_user()`将内核数据拷贝到用户空间地址时,没有调用`access_ok()`检测用户空间地址的合法性,导致实际可以往内核空间地址拷贝数据。 **waitid未检测用户地址合法性 导致 null 任意地址写**。可执行0地址shellcode 或 覆盖某猜测范围的cred 来提权。
#### 5.CVE-2017-6074
[writeup](https://bsauce.github.io/2021/09/17/CVE-2017-6074/) [reference](https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-6074)
**Test version**: Linux-4.9.12
**Protection**: 开启SMEP/SMAP,关闭kASLR。
**Vulnerability**: Linux内核IP V6协议簇的DCCP(数据报拥塞控制协议),`net/dccp/input.c`中的 [dccp_rcv_state_process()](https://elixir.bootlin.com/linux/v4.9.12/source/net/dccp/input.c#L574) 函数,在`LISTEN`状态下错误处理 `DCCP_PKT_REQUEST` 包数据结构,用户采用`IPV6_RECVPKTINFO`选项调用`setsockopt()`时会触发**`sk_buff`结构的 Double-Free**。利用方式类似CVE-2016-8655。第一次触发漏洞,堆喷伪造`po->rx_ring->prb_bdqc->retire_blk_timer`结构,执行`native_write_cr4(0x406e0)`来关闭SMEP/SMAP;第二次触发漏洞,堆喷伪造`skb-> ... ->destructor_arg`结构,执行`commit_creds(prepare_kernel_cred(0))`来提权。
#### 6.CVE-2017-7308
[writeup](https://www.jianshu.com/p/b53862cd64a6) [reference](https://github.com/xairy/kernel-exploits/tree/master/CVE-2017-7308)
**Test version**: Linux-4.10.6
**Protection**: 开启 SMEP / SMAP,关闭KASLR。
**Vulnerability**: `net/packet/af_packet.c`中的[`packet_set_ring()`](https://elixir.bootlin.com/linux/v4.10.6/source/net/packet/af_packet.c#L4181)函数没有正确检查块size,长度判断条件错误,导致**堆溢出**,需要`CAP_NET_RAW `权限。两次劫持函数指针,先关闭SMEP/SMAP防护,再提权。
#### 7.CVE-2017-8890
[writeup](https://www.jianshu.com/p/699de662f567) [reference](https://xz.aliyun.com/t/2383)
**Test version**: Linux-4.10.15
**Protection**: 开启SMEP,关闭kASLR、SMAP。
**Vulnerability**: `net/ipv4/inet_connection_sock.c`文件中的[`inet_csk_clone_lock()`](https://elixir.bootlin.com/linux/v4.10.15/source/net/ipv4/inet_connection_sock.c#L652)函数存在**Double-Free**漏洞。利用Double-Free来篡改RCU的回调函数指针,关闭SMEP并跳转到shellcode来修改cred。
#### 8.CVE-2017-11176
[writeup](https://www.jianshu.com/p/76041ec5c59f)
**Test version**: Linux-4.11.9
**Protection**: 开启SMEP,关闭kASLR、SMAP。
**Vulnerability**: Linux内核中的POSIX消息队列的实现,`mq_notify()`函数没有把sock指针置为null,导致UAF。实际上是由于**竞争导致的Double-Free漏洞**,但竞态的时间可以无限延长。
#### 9.CVE-2017-16995
[writeup](https://www.cnblogs.com/bsauce/p/11583310.html)
**Test version**: Linux-4.4.110
**Protection**: 开启SMEP/SMAP/kaslr。
**Vulnerability**: Linux ebpf 模块**整数扩展**问题,主要问题是二者寄存器值类型不同,导致check函数和真正的函数的执行方法不一致。本漏洞不包含堆栈攻击或控制流劫持,仅用系统调用数据进行提权,是Data-Oriented Attacks在linux内核上的一个典型应用。
#### 10. CVE-2017-1000112
[writeup](https://www.jianshu.com/p/1fa163fd5b82) [reference](https://bbs.pediy.com/thread-265319.htm)
**Test version**: Linux-4.12.6
**Protection**: 开启SMEP,关闭SMAP/kaslr。
**Vulnerability**: `net/ipv4/ip_output.c` 中的[__ip_append_data()](https://elixir.bootlin.com/linux/v4.12.6/source/net/ipv4/ip_output.c#L910) 没有保证UDP报文处理的一致性,导致两次send报文时,可从UFO路径切换为non-UFO路径,导致**堆溢出**。利用时可通过覆盖`skb_shared_info->destructor_arg->callback`劫持控制流。
#### 11. CVE-2018-5333
[writeup](https://blog.csdn.net/panhewu9919/article/details/119153052)
**Test version**: Linux-4.14.13
**Protection**: 开启SMEP,关闭SMAP/kaslr。
**Vulnerability**: `net/rds/rdma.c`中的 [`rds_cmsg_atomic()`](https://elixir.bootlin.com/linux/v4.14.13/source/net/rds/rdma.c#L788) 函数中忘记将`rm->atomic.op_active`置0,导致 [rds_atomic_free_op()](https://elixir.bootlin.com/linux/v4.14.13/source/net/rds/rdma.c#L474) -> [set_page_dirty()](https://elixir.bootlin.com/linux/v4.14.13/source/mm/page-writeback.c#L2559) 引用`page->page_link`时发生 **`null-dereference` 漏洞**。在0地址伪造结构和函数指针,劫持控制流。
#### 12. CVE-2019-9213 & CVE-2019-8956
[CVE-2019-9213-writeup](https://blog.csdn.net/panhewu9919/article/details/118557802) [CVE-2019-8956-writeup](https://blog.csdn.net/panhewu9919/article/details/118557844)
**Test version**: Linux-4.20.0 32位
**Protection**: 开启SMEP,关闭SMAP/kaslr。
**Vulnerability**:
- CVE-2019-9213:`mm/mmap.c`中的[`expand_downwards()`](https://elixir.bootlin.com/linux/v4.20.7/source/mm/mmap.c#L2413)对mmap最小地址的检查出错,对错误的task进行了capability检查,导致绕过了`mmap_min_addr`的限制,**逻辑漏洞**。利用`LD_DEBUG=help /bin/su 1>&%d`命令执行write操作,本来应检测exp的cred,结果错误检测了write进程的cred,就将低地址标记为特权可访问。只有32位系统能成功利用漏洞,原因不详。
- CVE-2019-8956:`net/sctp/socket.c`中的 [`sctp_sendmsg()`](https://elixir.bootlin.com/linux/v4.20.7/source/net/sctp/socket.c#L2025) 函数在处理`SCTP_SENDALL` flag时出现**空指针引用**漏洞。结合CVE-2019-9213,绕过`mmap_min_addr`的限制,可以mmap到低地址0xd4并伪造结构,劫持控制流。
#### 13. CVE-2019-15666
[writeup](https://bsauce.github.io/2021/09/14/CVE-2019-15666/) [reference](https://github.com/riskeco/Lucky/blob/master/lucky0_RE.c)
**Test version**: Ubuntu 18.04(4.15.0-20-generic #21)
**Protection**: 开启SMEP/SMAP/kaslr。
**Vulnerability**: `net/xfrm/xfrm_user.c`中的 [verify_newpolicy_info()](https://elixir.bootlin.com/linux/v5.0.18/source/net/xfrm/xfrm_user.c#L1379) 错误处理了`dir`验证,导致[__xfrm_policy_unlink()](https://elixir.bootlin.com/linux/v5.0.18/source/net/xfrm/xfrm_policy.c#L2202)中出现**越界访问**。漏洞原本是个越界减1,可以利用别的路径来构造UAF,可以往**空闲块上的8字节写null**。漏洞对象`xfrm_policy`位于`kmalloc-1024`,cred结构位于`kmalloc-192`。首先利用`setxattr+userfaultfd`在`policy0`周围都喷射`kmalloc-1024`堆块,释放`policy0`后同时释放喷射块,促使该slab释放后被c子进程的cred复用,然后触发UAF 空闲块8字节NULL写来修改cred中的`gid/suid`,再将当前用户添加到sudoers,即可提权。
#### 14. CVE-2020-8835
[writeup](https://www.cnblogs.com/bsauce/p/14123111.html) [reference](https://xz.aliyun.com/t/7690)
**Test version**: Linux-5.5.0
**Protection**: 开启SMEP/SMAP/kaslr。
**Vulnerability**: kernel/bpf/verifier.c没有正确将64位值转换为32位(直接取低32位),发生**整数截断**,使得BPF代码验证阶段和实际执行阶段不一致,导致越界读写。
#### 15. CVE-2020-27194
[writeup](https://www.jianshu.com/p/b6f11d8df37a) [reference](https://github.com/willinin/CVE-2020-27194-exp)
**Test version**: Linux-5.8.14
**Protection**: 开启SMEP/SMAP/kaslr。
**Vulnerability**: eBPF验证程序中进行or操作时,`scalar32_min_max_or()`函数将64位的值赋值到32位的变量上,导致**整数截断**,进而错误计算了寄存器的范围,从而绕过bpf的检查,导致越界读写。
#### 16. CVE-2021-3156
[writeup](https://www.jianshu.com/p/18f36f1342b3) [exploit](https://github.com/blasty/CVE-2021-3156)
**Test version**: Ubuntu 19.04、Sudo 1.8.27
**Protection**: 开启SMEP/SMAP/kaslr。
**Vulnerability**: sudo在处理命令行参数时,处理单个反斜杠结尾的命令时,发生逻辑错误,导致**堆溢出**。
#### 17. CVE-2021-31440
[writeup](https://bsauce.github.io/2021/06/09/CVE-2021-31440/) [exploit](https://github.com/bsauce/kernel-exploit-factory/tree/main/CVE-2021-31440/exp)
**Test version**: Linux-5.11
**Protection**: 开启SMEP/SMAP/kaslr。
**Vulnerability**: eBPF模块—`kernel/bpf/verifier.c`的[`__reg_combine_64_into_32()`](https://elixir.bootlin.com/linux/v5.11.20/source/kernel/bpf/verifier.c#L1312) 函数,寄存器计算错误。利用verifier阶段与实际执行阶段的不一致性,进行越界读写。泄露内核基址、伪造函数表、实现任意读写后篡改本线程的cred。
#### 18. CVE-2021-3490
[writeup](https://bsauce.github.io/2021/08/31/CVE-2021-3490/) [exploit](https://github.com/chompie1337/Linux_LPE_eBPF_CVE-2021-3490)
**Test version**: Linux-5.11 Linux-5.11.16
**Protection**: 开启SMEP/SMAP/kaslr。
**Vulnerability**: eBPF模块—`kernel/bpf/verifier.c`的按位操作(AND、OR 和 XOR)的 eBPF ALU32 边界跟踪没有正确更新 32 位边界,造成 Linux 内核中的越界读取和写入,从而导致任意代码执行。三个漏洞函数分别是 [scalar32_min_max_and()](https://elixir.bootlin.com/linux/v5.13-rc3/source/kernel/bpf/verifier.c#L7078) 、[scalar32_min_max_or()](https://elixir.bootlin.com/linux/v5.13-rc3/source/kernel/bpf/verifier.c#L7149)、[scalar32_min_max_xor()](https://elixir.bootlin.com/linux/v5.13-rc3/source/kernel/bpf/verifier.c#L7219)。利用verifier阶段与实际执行阶段的不一致性,进行越界读写。泄露内核基址、伪造函数表、实现任意读写后篡改本线程的cred。
#### 19. CVE-2021-22555
[writeup](https://bsauce.github.io/2021/09/23/CVE-2021-22555/) [exploit](https://github.com/google/security-research/blob/master/pocs/linux/cve-2021-22555/exploit.c)
**Test version**: Linux-5.11.14
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: `net/netfilter/x_tables.c` 中 `Netfilter` 模块的`ip_tables`子模块, 当调用`setsockopt()`和选项`IPT_SO_SET_REPLACE`(或 `IP6T_SO_SET_REPLACE`)时,内核结构需要从32位转换为64位,由于错误计算转换大小,导致在调用 [xt_compat_match_from_user()](https://elixir.bootlin.com/linux/v5.11.14/source/net/netfilter/x_tables.c#L731) 函数时**堆溢出写 0 ,可转化为UAF**。攻击者可用于提权,或者从docker、k8s容器([kubernetes](https://zhuanlan.zhihu.com/p/29232090))中逃逸。需要`CAP_NET_ADMIN`权限,或者支持`user+network`命名空间。
#### 20. CVE-2021-41073
[writeup](https://bsauce.github.io/2022/07/11/CVE-2021-41073/) [reference](https://www.graplsecurity.com/post/iou-ring-exploiting-the-linux-kernel)
**Test version**: Linux-5.14.6
**Protection**: 开启KASLR/SMEP/SMAP。未开启 `CONFIG_SLAB_FREELIST_RANDOM` / `CONFIG_SLAB_FREELIST_HARDENED` / `CONFIG_BPF_JIT_ALWAYS_ON` / `CONFIG_MEMCG `(默认是开启的)。
**Vulnerability**: `fs/io_uring.c`中的`loop_rw_iter()`函数存在 **`type confusion`漏洞**,`io_kiocb->rw.addr` 既充当内核地址又充当用户地址,但是在`loop_rw_iter()`函数中递增时没有作区分,导致在读文件时错误将内核地址递增,最后错误**将位于可控偏移处的相邻buffer释放掉**(kmalloc-32)。利用条件很严格,由于漏洞对象位于 kmalloc-32,所以关闭了 freelist 保护机制;由于 `seq_operations` 对象采用 `GFP_KERNEL_ACCOUNT` flag 分配,所以还关闭了 `CONFIG_MEMCG*` 机制;本漏洞采用篡改eBPF中的 `sk_filter->prog` 指针并伪造 BPF程序的方式来进行提权,所以还关闭了 `CONFIG_BPF_JIT_ALWAYS_ON` 配置。
#### 21. CVE-2021-4154
[writeup](https://bsauce.github.io/2022/10/17/CVE-2021-4154/) [reference](https://github.com/Markakd/DirtyCred)
**Test version**: Linux-5.13.3
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: `kernel/cgroup/cgroup-v1.c` 的 [cgroup1_parse_param()](https://elixir.bootlin.com/linux/v5.13.3/source/kernel/cgroup/cgroup-v1.c#L905) 函数(通过`fsconfig` 系统调用触发)存在类型混淆,导致**UAF漏洞**。可以调用syscall `fsconfig` 设置任意的 fd,最终关闭该文件后 fd 对应 `file` 对象会被释放。这样我们就能**释放任意一个文件描述符对应的 `file` 结构**。本文采用两种方法实现利用,一是DirtyCred,二是构造ROP。对比两种方法,DirtyCred方法的优点是跨内核版本通用,不需要适配,缺点是需要覆写特权文件来提权,所以在docker等容器中无法提权;ROP的优点是可以任意读写内核内存并执行任意代码,缺点是对不同内核版本的适配很麻烦。
#### 22. CVE-2021-42008
[writeup](https://bsauce.github.io/2021/12/09/CVE-2021-42008/) [reference](https://syst3mfailure.io/sixpack-slab-out-of-bounds)
**Test version**: Linux-5.13.12
**Protection**: 开启KASLR / SMEP / SMAP / PTI。
**Vulnerability**: `drivers/net/hamradio/6pack.c`中 [decode_data()](https://elixir.bootlin.com/linux/v5.13.12/source/drivers/net/hamradio/6pack.c#L826) 函数存在**堆溢出**,用户需具备 `CAP_NET_ADMIN` 权限。[sixpack_decode()](https://elixir.bootlin.com/linux/v5.13.12/source/drivers/net/hamradio/6pack.c#L962) 可多次调用 [decode_data()](https://elixir.bootlin.com/linux/v5.13.12/source/drivers/net/hamradio/6pack.c#L826) ,对输入进行解码并保存到 [sixpack->cooked_buf](https://elixir.bootlin.com/linux/v5.13.12/source/drivers/net/hamradio/6pack.c#L98) ,`sixpack->rx_count_cooked`成员充当访问 `sixpack->cooked_buf` 的下标,确定写入解码字节的目标偏移。问题是如果多次调用`decode_data()`,`rx_count_cooked`就会一直递增,直到超过 `cooked_buf` 的长度(400字节),导致越界写。参考[Linux内核中利用msg_msg结构实现任意地址读写](https://www.anquanke.com/post/id/252558)构造越界读和任意地址写,篡改`modprobe_path`提权,缺点是得用到`userfaultfd`,且绕不开 `CAP_NET_ADMIN` 的槛。
#### 23. CVE-2021-43267
[writeup](https://bsauce.github.io/2021/12/06/CVE-2021-43267/) [reference](https://haxx.in/posts/pwning-tipc/)
**Test version**: Linux-5.14.15
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: 漏洞位于 `net/tipc/crypto.c` 文件,TIPC(Transparent Inter-Process Communication)集群内通信协议中对 `MSG_CRYPTO` 类型的消息长度验证出错,导致**堆溢出**。[tipc_crypto_key_rcv()](https://elixir.bootlin.com/linux/v5.14.15/source/net/tipc/crypto.c#L2281) 函数中,TIPC消息([tipc_msg](https://elixir.bootlin.com/linux/v5.14.15/source/net/tipc/msg.h#L148)结构)的数据部分指向`MSG_CRYPTO`消息([tipc_aead_key](https://elixir.bootlin.com/linux/v5.14.15/source/include/uapi/linux/tipc.h#L241)结构),在分配`tipc_aead_key` 空间并拷贝 `tipc_aead_key->key` 时,未校验`tipc_aead_key->keylen`的有效性,导致拷贝越界。只对TIPC消息的 `header size` 和 `msg size` 进行检查,却没有对 `MSG_CRYPTO`消息的`tipc_aead_key->keylen`进行检查。利用 `elastic object` 泄露内核基址,并篡改`tty_struct->tty_operations.ioctl` 指向任意写gadget (`mov QWORD PTR [rdx],rsi`),篡改 `modprobe_path` 提权。
#### 24. CVE-2022-0185
[writeup](https://bsauce.github.io/2022/04/08/CVE-2022-0185/)
**Test version**: Linux-5.11.22
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: 在google kctf 上完成提权,赢得3万美金。内核的 `File System Context` 模块(文件系统环境)的`fs/fs_context.c`文件中存在**整数溢出**导致堆溢出。攻击者必须具备 `CAP_SYS_ADMIN` 权限,或者使用命名空间或者使用`unshare(CLONE_NEWNS|CLONE_NEWUSER)` (等同于命令`$ unshare -Urm`)来进入含有`CAP_SYS_ADMIN`权限的命名空间。两种方法利用,一是利用 **FUSE**(相当于userfault)构造任意地址写,修改 `modprobe_path`,二是利用 `msg_msg` 构造任意释放,再构造ROP提权。
#### 25. CVE-2022-0847
[writeup](https://bsauce.github.io/2022/04/03/CVE-2022-0847/) reference-[1](https://blog.csdn.net/Breeze_CAT/article/details/123393188) [2](https://www.anquanke.com/post/id/269886) [3](https://www.freebuf.com/vuls/324700.html)
**Test version**: Linux-5.16.10
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: **DirtyPipe漏洞**。`splice`调用将包含文件的页面缓存(page cache),链接到pipe的环形缓冲区 [pipe_buffer](https://elixir.bootlin.com/linux/v5.16.10/source/include/linux/pipe_fs_i.h#L26) 时,[copy_page_to_iter_pipe()](https://elixir.bootlin.com/linux/v5.16.10/source/lib/iov_iter.c#L384) 和 [push_pipe()](https://elixir.bootlin.com/linux/v5.16.10/source/lib/iov_iter.c#L547) 函数都没有将 [pipe_buffer](https://elixir.bootlin.com/linux/v5.16.10/source/include/linux/pipe_fs_i.h#L26) -> `flag` 成员初始化(变量未初始化漏洞)。由于没有清除 `PIPE_BUF_FLAG_CAN_MERGE` 属性,导致后续进行 `pipe_write()` 时误以为write操作可合并,从而将非法数据写入了文件页面缓存(重启可复原),导致任意文件覆盖漏洞。该漏洞能写任意文件的page cache,提权方法是修改/etc/passwd的page cache,短时间内所有访问该文件的进程都将访问到被篡改的文件缓存页。
#### 26. CVE-2022-0995
[writeup](https://bsauce.github.io/2022/04/15/CVE-2022-0995/)
**Test version**: Linux-5.11.22
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: `watch_queue ` 事件通知子系统存在**堆溢出**,漏洞函数是[watch_queue_set_filter()](https://elixir.bootlin.com/linux/v5.16.14/source/kernel/watch_queue.c#L286)。内核会对用户传入的 [watch_notification_type_filter](https://elixir.bootlin.com/linux/v5.16.14/source/include/uapi/linux/watch_queue.h#L52) 类型的 filter 进行两次有效性检查,第1次检查是为了确定分配的内存大小,第2次是为了将用户filter 存入该内存。但是两次检查不一致,导致分配空间过小,可溢出存入更多的 filter。可以利用第2次溢出,对相邻的堆块特定bit位置1,接下来的利用方法和 [CVE-2021-22555](https://bsauce.github.io/2021/09/23/CVE-2021-22555/) 一样。
#### 27. CVE-2022-1015
[writeup](https://bsauce.github.io/2022/07/16/CVE-2022-1015/) [reference](https://blog.dbouman.nl/2022/04/02/How-The-Tables-Have-Turned-CVE-2022-1015-1016/)
**Test version**: Linux-5.17
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: nftables模块中,[nft_parse_register_load()](https://elixir.bootlin.com/linux/v5.17/source/net/netfilter/nf_tables_api.c#L9325) 和 [nft_parse_register_store()](https://elixir.bootlin.com/linux/v5.17/source/net/netfilter/nf_tables_api.c#L9377) 函数没有限制传入的寄存器下标范围,导致整数溢出(能够通过范围校验),从而触发**栈溢出越界读写**。漏洞利用时,需从中断上下文中返回到用户态,需要利用 `__do_softirq()` 函数的末尾完美返回到syscall的上下文,然后调用 `switch_task_namespaces(current, &init_nsproxy)` 和 `commit_cred(&init_cred)` 提权。
#### 28. CVE-2022-2588
[writeup](https://bsauce.github.io/2022/10/21/CVE-2022-2588/) [reference](https://github.com/Markakd/CVE-2022-2588)
**Test version**: Linux-5.19.1
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: 和 [CVE-2021-3715](https://access.redhat.com/security/cve/cve-2021-3715) (参见 [BlackHat 2021-Europe-Your Trash Kernel Bug, My Precious 0-day](https://zplin.me/talks/BHEU21_trash_kernel_bug.pdf) 16页)类似,由于将 `route4_filter` 对象从链表中删除和释放时的检查条件不一致,导致该对象被释放后仍存于链表中,后面可以触发 **Double-Free**。需要 `User Namespaces` 才能触发。采用 **DirtCred** 方法进行提权。
#### 29. CVE-2022-2602
[writeup](https://bsauce.github.io/2022/06/08/CVE-2022-2602/) [reference](https://1day.dev/notes/CVE-2022-2602-DirtyCred-File-Exploitation-applied-on-an-io_uring-UAF/)
**Test version**: Linux-5.18.19
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: io_uring组件中有个功能 `IORING_REGISTER_FILES`,可以将文件放入 io_uring 的 `sock->receive_queue` 队列中。而Linux的垃圾回收机制GC(只处理 io_uring 和 sock 文件的飞行计数)可能会将io_uring中注册的文件当做垃圾释放,io_uring 下次使用该文件时(利用writev写文件,对应`IORING_OP_WRITEV`功能)触发**UAF漏洞**。利用方法,由于UNIX_GC垃圾回收机制会错误释放 `io_uring` 中还在使用的文件结构体(正在往`"/tmp/rwA"`普通文件写入恶意数据),可以**采用DirtyCred方法**,打开大量`"/etc/passwd"`文件,覆盖刚刚释放的`file`结构体,这样最后就会实际往`"/etc/passwd"`文件写入恶意数据。
#### 30. CVE-2022-2639
[writeup](https://bsauce.github.io/2022/11/24/CVE-2022-2639/) [reference](https://veritas501.github.io/2022_10_18-CVE-2022-2639%20%20openvswitch%20LPE%20%20%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/)
**Test version**: Linux-5.17.4
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: `openvswitch` 内核模块中,[reserve_sfa_size()](https://elixir.bootlin.com/linux/v5.17.4/source/net/openvswitch/flow_netlink.c#L2439) 存在整数溢出导致 **kmalloc-0x10000 堆溢出写**,需要利用页喷射构造 cross-cache 溢出。本文基于 `pipe-primitive` 来篡改任意文件,所以不需要绕过 KASLR/SMEP/SMAP/KPTI 保护机制,跨版本不需要适配就能完成利用。**先创建pipe并splice到只读文件`/usr/bin/mount`,堆喷伪造 `pipe_buffer->flags = PIPE_BUF_FLAG_CAN_MERGE` ,这样就能往 `/usr/bin/mount` 文件写入 suid-shell 然后执行提权**。 两次触发OOB,第一次是溢出篡改 `msg_msg->m_ts` 越界读取相邻的 `msg_msg->m_list.next` **泄露kmalloc-1024堆地址**;第2次是溢出篡改 `msg_msg->m_list.next` 指向泄露的kmalloc-1024堆地址,**构造任意释放**。
#### 31. CVE-2022-25636
[writeup](https://bsauce.github.io/2022/12/13/CVE-2022-25636/) [reference](https://github.com/Bonfee/CVE-2022-25636)
**Test version**: Linux-5.13.19
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: `nf_table` 模块的 `net/netfilter/nf_dup_netdev.c`中的 [nft_fwd_dup_netdev_offload()](https://elixir.bootlin.com/linux/v5.16.11/source/net/netfilter/nf_dup_netdev.c#L67) 函数由于计算分配空间与实际初始化时判断条件不一致,存在**OOB write**(系统必须支持包处理卸载-Network Interface Cards (NICs),但是现实中很少见),**溢出写入一个 `net_device` 对象的地址(位于kmalloc-4k)**,且漏洞对象的大小可以变化(由传入的含 `NFT_OFFLOAD_F_ACTION` 标记的rule个数决定,可以位于 `kmalloc-128` 或 `kmalloc-192` 等等),需要 `SYS_ADMIN` 权限。利用时**通过 `msg_msgseg` 泄露 `net_device` kmalloc-4k 堆指针,通过覆写 `msg_msg->security` 指针构造任意释放,通过自带功能 `ioctl(fd, SIOCGIFHWADDR, leak)` 读取 `net_device->dev_addr` 来泄露内核基址,通过伪造 `net_device->ethtool_ops->begin` 函数指针劫持控制流提权**。
#### 32. CVE-2022-27666
[writeup](https://paper.seebug.org/1889/) [reference](https://etenal.me/archives/1825)
**Test version**: Linux-5.16.14
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: 在PWN2OWN比赛上,完成对Ubuntu 21.10 的提权。内核的 esp6 crypto 模块,接收缓冲区是 8-page,但发送者可以发送大于 8-page 的数据,由 [null_skcipher_crypt()](https://elixir.bootlin.com/linux/v5.16.14/source/crypto/crypto_null.c#L76) 函数导致**页溢出**。总体采用页喷射技术,首先利用 `user_key_payload` 弹性对象泄露 `msg_msg->next`,然后利用 `msg_msg` 来泄露 `seq_operations->start` 内核地址,最后利用 `msg_msg` 和 FUSE页错误处理构造任意写,来篡改 `modprobe_path` 提权。
#### 33. CVE-2022-32250
[writeup](https://bsauce.github.io/2022/11/03/CVE-2022-32250/) [reference](https://github.com/theori-io/CVE-2022-32250-exploit)
**Test version**: Linux-5.17.12
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: `nftables` 模块的 `net/netfilter/nf_tables_api.c` 采用 `NFT_MSG_NEWSET` 功能来添加 `nft_set` 时,处理 `lookup` 和 `dynset` expression 时,由于错误的 `NFT_EXPR_STATEFUL` 检查,`nft_expr` 对象释放后仍位于`nft_set->binding` 链表中,新加入 `nft_expr` 时导致**UAF写**(触发漏洞需要 `CAP_NET_ADMIN` 权限)。UAF写会往 `kmalloc-64` 的偏移 0x18 处写入另一个 `kmalloc-64` 堆块偏移 0x18 的地址值。利用方法,采用 **mqueue 中的 `msg_msg` 来泄露内核基址**,因为 mqueue 中的 `posix_msg_tree_node->msg_list` 偏移为 0x18(且位于`kmalloc-64`),恰好是UAF写的偏移;另外,**`posix_msg_tree_node->msg_list` 也能用来构造 Unlink 利用**来篡改 `modprobe_path`。利用`user_key_payload`泄露堆地址(便于构造unlink),老生常谈了。注意,需使用ubuntu21.04 以上的版本的libmnl 或 libnftnl才行。
#### 34. CVE-2022-34918
[writeup](https://bsauce.github.io/2022/07/26/CVE-2022-34918/) [reference](https://www.randorisec.fr/crack-linux-firewall/)
**Test version**: Linux-5.17.15
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: nftables模块中,[nft_set_elem_init()](https://elixir.bootlin.com/linux/v5.18.10/source/net/netfilter/nf_tables_api.c#L5459) 函数存在**堆溢出**,溢出长度可达 `64-16=48`字节,漏洞对象可以位于 `kmalloc-{64,96,128,192}`(本文利用时选取 kmalloc-64 漏洞对象)。漏洞利用——首先构造堆布局 `vul_obj -> user_key_payload -> percpu_ref_data`,溢出篡改 `user_key_payload->datalen` 为 0xffff,以泄露出 `percpu_ref_data->release` 内核基址和 `percpu_ref_data->ref` physmap基址;然后构造堆布局 `vul_obj -> simple_xattr`,溢出篡改 `simple_xattr->list` 链表,利用这个有限制的任意写将 `modprobe_path` 从 `/sbin/modprobe` 修改为 `/tmp/xxxxprobe` 来提权(从链表中移除xattr时触发该任意写)。该任意写的前提条件是需要泄露 physmap 地址,`percpu_ref_data` / `shm_file_data` 都既包含内核基址又包含physmap地址。
#### 35. CVE-2023-2598
[writeup](https://bsauce.github.io/2024/07/30/CVE-2023-2598/) [reference](https://anatomic.rip/cve-2023-2598/)
**Test version**: Linux-6.3.1
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: io_uring模块中的OOB写漏洞,可导致**越界读写物理内存**,漏洞位于目录 `io_uring/rsrc.c` 的 [io_sqe_buffer_register()](https://elixir.bootlin.com/linux/v6.3.1/source/io_uring/rsrc.c#L1230)函数,在检查所提交的待注册page是否属于同一复合页时,仅检查了所在复合页的首页是否一致,而没有检查所提交的page是否为同一page。可以注册同一个物理页(冒充多个物理页组成的复合页),构造物理页任意长度越界读写。
利用物理页任意长度越界读写,可以任意读写其后的sock对象,通过`sock->sk_data_ready`泄露内核基址,通过`sock.sk_error_queue.next`泄露sock对象的堆地址,通过伪造`sock.__sk_common.skc_prot->ioctl`函数指针指向[call_usermodehelper_exec()](https://elixir.bootlin.com/linux/v6.3.1/source/kernel/umh.c#L434)函数来**劫持控制流**,还需要伪造`subprocess_info`结构来完成利用,最终**执行`/bin/sh -c /bin/sh &>/dev/ttyS0 </dev/ttyS0` 来提权**。
#### 36. CVE-2024-1086
[writeup](https://bsauce.github.io/2024/05/10/CVE-2024-1086/) [reference](https://yanglingxi1993.github.io/dirty_pagetable/dirty_pagetable.html)
**Test version**: Linux-6.3.13
**Protection**: 开启KASLR/SMEP/SMAP。
**Vulnerability**: netfilter子系统nf_tables组件中存在**UAF漏洞**,[nft_verdict_init()](https://elixir.bootlin.com/linux/v6.3.13/source/net/netfilter/nf_tables_api.c#L10321)函数中,允许设置一个很大的verdict值(恶意值0xffff0000);[nf_hook_slow()](https://elixir.bootlin.com/linux/v6.3.13/source/net/netfilter/core.c#L607) 函数中,在处理`NF_DROP` (0)时,它会先释放skb数据包,并调用[NF_DROP_GETERR()](https://elixir.bootlin.com/linux/v6.3.13/source/include/linux/netfilter.h#L19)来修改返回值(根据verdict值设置为`NF_ACCEPT` - 正值1)。后续引用skb时触发UAF,[NF_HOOK()](https://elixir.bootlin.com/linux/v6.3.13/source/include/linux/netfilter.h#L407)会再次释放skb。利用方法,**构造重叠的PMD页和PTE页**,`PMD[0]`/`PMD[1]`会覆写`PTE[0]`/`PTE[1]`,通过往PTE页对应的用户虚拟地址写入,来伪造`PMD[0]`对应的PTE页(条目对应的是物理地址),这样就能通过往PMD对应的用户虚拟地址写入,**实现任意物理地址写**。
", Assign "at most 3 tags" to the expected json: {"id":"5686","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"