Linux kernel漏洞学习

不可视境界线最后变动于:2023年6月25日 下午

syzkaller环境 |

CVE-2022-0435: Remote Stack Overflow

看到好多熟悉的词汇, 算了当个练手吧.

原始blog | 更早的local bug:CVE-2021-43267,已写在下面 | TIPC Guide |

Summary

  • Appgate Threat Advisory Services (CANVAS) discovered a stack overflow vulnerability in the TIPC module of the Linux Kernel
  • Local or remote exploitation can lead to denial of service and code execution
  • Exploitation requires the TIPC module to be loaded on the target
  • Affected versions include 4.8 through 5.17-rc3
  • Patch released on February 10, 2022

Vulnerability

具体TIPC见上方Guide.

简单来说就是有这么一个结构体

1
2
3
4
5
6
7
8
9
10
11
struct tipc_peer {
u32 addr;
struct tipc_mon_domain *domain;
struct hlist_node hash;
struct list_head list;
u8 applied;
u8 down_cnt;
bool is_up;
bool is_head;
bool is_local;
};

其中tipc_mon_domain为:

1
2
3
4
5
6
7
8
9
#define MAX_MON_DOMAIN 64
struct tipc_mon_domain {
u16 len;
u16 gen;
u16 ack_gen;
u16 member_cnt;
u64 up_map;
u32 members[MAX_MON_DOMAIN];
};

在tipc_mon_rcv函数里使用到了

  • dlen:header中定义的domain record长度
  • new_dlen:使用member_cnt算出的data length
  • arrv_dlen:使用len直接得到的长度.

但是合法性检查(sanity check)的时候只要求了: dlen == new_dlen && arrv_dlen == new_dlen && dlen > minimum

前两个就会没有一样, 更多的只是在检查是不是真domain record. 而后者…万一dlen超过了MAX_MON_DOMAIN呢? 一点也没管, 所以会导致cache的时候发生栈溢出. 最大值不超过MTU或者bearer media type的限制.

修复也很简单, 在这里

Exploitation

Blog : 作者作为新员工打算整点少见的remote exploitation出来而不仅是LPE, 所以写了这一篇. 还分享了一点远程攻击技巧

We also need to factor in the execution context we’ll be hijacking if we successfully overwrite the return address with our remote stack overflow and gain control of execution. Unlike most local exploit scenarios, we won’t be operating in the process context, but instead we will find ourselves in the interrupt context.

remote KASLR leaks, let alone canary leaks, is fairly sparse. recent paper: https://arxiv.org/pdf/1906.10478.pdf

总结起来就是挺难的, 直接先假设KASLR + HARDEN_STACK都不存在.

为了能够干净的返回(?), We need to:

  • Analyze the stack pre/post overflow; which function’s stack frames are we clobbering?
  • Determine what is the closest unclobbered stack frame we can return to
  • Determine if any locks are released in the functions we skip returning to. If so, we need to release these ourselves
  • After we pick a return address, make sure $RSP, $RBP and any other required registers are correct

这样就能够多次执行. 几次之后就可以直接设置rsp以缩短shellcode长度.

接下来就是syscall hooking来pivot到user space进行一个pwn:

  • 我们的计划是用我们自己的代码覆盖sys_call_table中的一个函数指针,这样下次运行sycall时,它就会运行我们的代码
  • 我们需要kmalloc一些内存来让我们的hook和usermode有效负载存活;
  • 然后我们需要set_memory_x()我们的钩子接下来,我们需要set_memory_w() sys_call_table
  • 还需要禁用$CR0中的写保护位现在我们能够覆盖sys_call_table中的一个函数指针

Overall, our hook will look something like this: HOOK

  • getuid() to make sure we’re hooking a root processes call; ignore if not root
  • mmap() and executable region in userspace for our payload
  • copy_to_user() our userspace payload
  • Adjust struct pt_regs so that pt_regs->ip points to our userspace payload
  • Cleanup hook on success
  • Return execution back to the original handle

Mitigations

Before we wrap-up, I’d be remiss if I didn’t touch on existing mitigations for bugs like CVE-2022-0435. So, here’s a small glossary of relevant mitigations, including some we’ve already touched on:

  • KASLR & CONFIG_STACKPROTECTOR are enabled by default on modern systems and both impose strict information leak requirements for remote attackers, given the limited surface
  • CONFIG_FORTIFY_SRC: Since summer 2021 [6], adds strict memcpy() bounds checking to the Linux kernel. Essentially, this mitigation will trigger a fortify_panic() if we try to memcpy(dst, src, size), when we know that size > sizeof(dst/src) [7]
  • CONFIG_FG_KASLR: as we’ve touched on KASLR, it’s worth noting that Function Granular KASLR takes things a step further by randomizing the location of the kernel at a per-function level, rather than a single KASLR-slide
  • There are several architecture/compiler specific implementations that seek to provide control flow integrity (CFI) by protecting forward-edges (think function pointers) and/or backward-edges (think return addresses). These aim to mitigate control flow hijacking techniques, such as the ROP techniques we saw in this post.

CVE-2021-43267: Heap Overflow of TIPC

Blog | Finder’s Blog |

CVE-2022-0185

  1. 一个kmalloc-4k内核堆溢出, 覆盖msg_msg的m_ts, 然后使用MSG_COPY造成OOB read, 泄露出seq_operation结构体中的指针, 绕过KASLR.

CVE-2022-29582