linux内核泄露地址的方式

早些的时候可以利用dmesg通过缺页错误来泄露内核地址,但新一点的内核把这个修复了。最近看了下,遇到了目前常用的方式,详细分析下。

shmat

大部分搜到的记录是利用

struct shm_file_data {
    int id;
    struct ipc_namespace *ns;
    struct file *file;
    const struct vm_operations_struct *vm_ops;
};
#define shm_file_data(file) (*((struct shm_file_data **)&(file)->private_data))
使用方法:

 int shmid;
  if ((shmid = shmget(IPC_PRIVATE, 100, 0600)) == -1) {
    perror("shmget");
    return 1;
  }
  char *shmaddr = shmat(shmid, NULL, 0);
  if (shmaddr == (void*)-1) {
    perror("shmat");
    return 1;
  }

这个是进行了堆喷。
内核中在shmat操作后发生了如下内存分配:

struct shm_file_data {
int id;
struct ipc_namespace *ns;
struct file *file;
const struct vm_operations_struct *vm_ops;
};     //32

sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
sfd->id = shp->shm_perm.id;
sfd->ns = get_ipc_ns(ns);
sfd->file = base;
sfd->vm_ops = NULL;
file->private_data = sfd;

shm_file_data为一个32字节的数据结构,其中ns保存了init_ipc_ns指针。

为了得到这个堆喷的结构体中的数据,我们还需要利用uaf和任意地址读。强行读取0x4242424242424242类似地址的数据,获取堆喷数据。

msg_msg堆喷

https://bbs.pediy.com/thread-269311.htm
这里有篇文章记录了利用uaf修改 msg_msg内核数据的过程。
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
在这里插入图片描述
msgsnd 在内核中可以生成类似链表的结构来保存用户态数据。0x31-0x1000(kmalloc-64及以上)

在这里插入图片描述

int store_msg(void __user *dest, struct msg_msg *msg, size_t len)
{
    size_t alen;
    struct msg_msgseg *seg;
 
    alen = min(len, DATALEN_MSG);
  //首先拷贝alen长度
    if (copy_to_user(dest, msg + 1, alen))
        return -1;
    //如果有msg_msgseg,那么紧接着dest+alen放如果有msg_msgseg
    for (seg = msg->next; seg != NULL; seg = seg->next) {
        len -= alen;
        dest = (char __user *)dest + alen;
        alen = min(len, DATALEN_SEG);
        if (copy_to_user(dest, seg + 1, alen))
            return -1;
    }
    return 0;
}

msgrcv在 (MSG_COPY&msgflg)存在的时候会利用副本来回传 msg数据, 其中创建的副本大小可以受到用户态控制,当存在uaf时候,就有一定几率编辑这个可控大小的内核数据块。我们只需要修改msg 头部的指针,指向可能的 存在 shm_file_data的堆喷数据块,对其中的数据进行判断(地址随机化只进行基地址随机化,所以低32位可以作为判断依据),即可泄露init_ips_ns的地址。

任意地址写操作

在这里插入图片描述
这里作者利用suerfaultfd, 暂停了copyfromuser, 利用uaf造成的地址写能力,实现了伪造地址的数据修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值