老表带你学Linux kernel pwn 入门(四)

本文是Linux kernel pwn系列的第四篇,讲解了如何利用内核态Use-After-Free (UAF)漏洞。内容包括ida中诡异变量的意义、目标驱动的逆向分析、内核堆块的申请与释放、漏洞分析以及exp的调试与编写。文中提到的堆喷射技术是利用漏洞的关键,并给出了参考资料。
摘要由CSDN通过智能技术生成

写在前面

​ 本篇是老表带你学linux kernel pwn系列的第四篇,这里用到的题目是内核态uaf漏洞。

第一章 基础知识

1.1 ida中诡异变量的意义

https://www.dazhuanlan.com/2019/12/30/5e094e9beea31/

第二章 目标分析与准备

2.1 逆向分析baby.ko

分析目标驱动文件,首先从init_module()入手,然后分析主功能函数的逻辑。

2.1.1init_moudle()

注册了一个misc设备``,

__int64 init_module()
{
   
  _fentry__();
  return misc_register(&off_200);
}

2.1.2 ioctl驱动文件分析

ioctl函数特别长我们慢慢来梳理一下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DVRujTtA-1605169406340)(C:\Users\Siamese\AppData\Roaming\Typora\typora-user-images\image-20201112144519051.png)]

  • ioctl的初始化部分

    __int64 __fastcall ioctl(__int64 fd, __int64 command)
    {
         
      __int64 args1; // rdx
      __int64 info; // r13
      __int64 chunks; // rbx
      __int64 i; // rax
      __int64 can_use_id; // r12
      __int64 chunk_addr; // rax
      __int64 v9; // rdx
      __int64 edit_idx; // rax
      __int64 edit_chunk_ptr; // rsi
      __int64 v12; // rax
      __int64 idx; // rax
      __int64 free_chunk_ptr; // rdi
    
      _fentry__(fd, command);
      info = args1;
      chunks = kmem_cache_alloc_trace(kmalloc_caches[4], 0x6000C0LL, 16LL);
      copy_from_user(chunks, info, 16LL);
    

    看的时候顺手函数名、便令名做修改,方便进行后面的分析

    上来ioctl的给参数设备描述符*fd,运行命令0x6008之类的

    第18行,申请内核chunk

    第19行,把info也就是ioctl中传进来的第三个变量进行copy_from_user做个拷贝。

    传进来的大小16个字节。

  • 内核堆块释放部分

        case 0x6008:                                // free  函数
          idx = *(signed int *)(chunks + 8);
          if ( (unsigned int)idx <= 31 )
          {
            free_chunk_ptr = buf[idx];
            if ( free_chunk_ptr )
              kfree(free_chunk_ptr);
          }
          break;
    

    第2行,说明传进来的结构体offset8处表示对块的索引,变量类型为__int64.

    buf是一个全局的指针数组,用来存申请的内核指针。

    第3-9行,当前索引不超过31时,寻找buf中idx处的指针,如果不为空,就释放掉。

  • 函数调用功能部分

        case 0x6009:
          edit_idx = *(signed int *)(chunks + 8);
          if ( (unsigned int)edit_idx <= 31 )
          {
         
            edit_chunk_ptr = buf[edit_idx];
            if ( edit_chunk_ptr )
            {
         
              rax_value = *(_QWORD *)(edit_chunk_ptr + 64);
              _x86_indirect_thunk_rax(*(_QWORD *)(edit_chunk_ptr + 0x38), edit_chunk_ptr, 0x48LL);
            }
          }
          break;
    

    __x86_indirect_thunk_rax直接jmprax相当于系统调用直接call。

    1-12功能为:根据chunks的id定位buf数组中需要使用的内核堆块地址edit_chunk_ptr然后把offset为0x40出的值传给eax,然后执行call eax

  • 内核堆块申请部分

        case 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值