首页
社区
课程
招聘
CVE-2021-26708 利用四字节释放特定地址,修改内存
发表于: 2021-9-17 16:50 22801

CVE-2021-26708 利用四字节释放特定地址,修改内存

2021-9-17 16:50
22801


```c

vsock_stream_etssockopt()  {

struct sock *sk;

    struct vsock_sock *vsk;

    const struct vsock_transport *transport;


    /* ... */


    sk = sock->sk;

    vsk = vsock_sk(sk);

    transport = vsk->transport;

    lock_sock(sk);      //  内核sock锁


}

```


vsk 存在本地变量,当sock被条件竞争释放后,这个本地保存的变量将会实现一个四字节的地址写漏洞。


类似这样,setsockopt触发vsock_stream_etssockopt. 但被第二个进程connect竞争等待,这里vsock_stream_connect有一定的几率先于vsock_stream_setsockopt操作释放vsock_sock, 但vsock_stream_setsockopt保存了备份,所以出现了uaf。


为了在释放后执行virtio_transport_notify_buffer_size, 需要对setsockopt 参数size进行随机变化,绕过参数检查


```c

 if (val != vsk->buffer_size &&

      transport && transport->notify_buffer_size)

        transport->notify_buffer_size(vsk, &val);

```


利用msg_msg机制堆喷占位,实现kmalloc-64内存占用。这时vsock_sock->buf_alloc的位置,也就是msg_msg->security的位置前四字节将会被修改。


为了泄露地址,这里利用内核报警   virto_transport_send_pkt_info()。作者gdb分析了崩溃地址的的寄存器地址,分析得出了RCX,  RBX 分别包含了virto_vsock_sock  和  vsock_sock。这个方式还是有点怪,不过应该也可以算可行。



目前我们可以提前释放这两个指针。  


再往后的操作有点杀脑细胞了。


```c

/* one msg_msg structure for each message */

struct msg_msg {

    struct list_head m_list;

    long m_type;

    size_t m_ts;        /* message text size */

    struct msg_msgseg *next;

    void *security;    //无SELinux,这里为NULL

    /* the actual message follows immediately */

};

```

m2的地址是知道的,利用msg_msg占用,二次强制释放。那么这个时候m2可以有两个指针操作,vsock_sock,  msg_msg两个数据结构,再往后 setxattr() & userfaultfd() 精确堆喷占位m2, 伪造m2出的msg->next指针为     vsock_sock地址, 就可以读到m2没有被破坏的数据。



void (*sk_write_space)(struct sock *)函数指针在vsock_sock.sk偏移量688处,被设置为sock_def_write_space()内核函数的地址。它可以用来计算KASLR偏移量。通过这个可以绕过kaslr.


作者制造了sk_buff的uaf.

这里首先  


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//