# 驱动安全编码&排查指南

本文介绍了驱动程序在物联网设备中的角色及其安全性的重要性。强调了驱动代码运行在内核态,潜在的安全风险可能导致系统崩溃甚至权限提升。列举了常见的驱动安全漏洞,如缓冲区溢出、任意内存读写等,并提供了安全开发原则,如严格校验用户态输入,使用安全拷贝函数。同时,讨论了安全测试的关键点,包括File_operations函数、内存映射和拷贝函数的使用。最后,提到了内核安全加固措施和攻击手段。
摘要由CSDN通过智能技术生成

驱动安全编码&排查指南

​ 作者: 魏来

什么是驱动

驱动程序是IoT设备能驱使外设的一种代码程序。不常接触底层开发的读者可能会有一个误区,认为驱动程序是运行在外设器件里的。但是,其实驱动程序是运行在IoT 设备主机侧,由主机操作系统内核执行的代码。

举一个常见的驱动执行流程为例:

用户态app 使用系统调用 打开 设备驱动程序,并发送读写数据请求到驱动进行执行。运行在内核态的外设驱动代码 将请求转发到主机控制器驱动的代码片段(同样运行在主机侧内核态里的驱动代码),最终当CPU执行到控制器驱动代码时,将指挥内嵌在SoC 里的控制器设备将请求途经总线转发到外设上。
在这里插入图片描述

上述是软件层面的视角,我们再从硬件的控制流视角看一下底层是怎么运作的。
在这里插入图片描述

内核驱动风险性

既然驱动代码运行在操作系统内核态,这也就意味着驱动代码是以内核的权限身份执行。一旦驱动存在可被用户程序触发的漏洞,轻则导致系统级复位,重则被攻击者诱导篡改其处在用户态进程的身份权限。这是因为用户进程的身份管理信息(cred) 是由内核进行管理的,内核态出现命令执行时即可修改用户权限。

下面给出一个提权的实例,建立一个直观感受:

在这里插入图片描述

在IOT设备上,提权攻击往往是在攻击者从外部攻破设备对外提供服务的业务进程,拿到业务进程shell权限后,进一步权限提升时发生的。

常见安全漏洞
缓冲区溢出/越界写

当内核面向用户态的接口中存在类似如下代码时,即可完成缓存区溢出。

memcpy(dest, src, bigLen); //从src 数组里拷贝bigLen字节到dest数组,bigLen大于dest数组的大小。

copy_from_user(dest, src, len); //len 大于dest 数组大小

...

需要严格校验拷贝字符数量是否大于源/目的缓冲区大小。

上述代码片段,对应如下内存操作

危害

我们知道,函数调用的时候会在栈上创建函数栈帧,如果在子函数中发生缓冲区溢出,则可以覆盖到调用者函数栈帧中保存的数据。如果调用者栈帧中保存的函数返回地址被篡改了,则可以发生ROP 任意代码地址跳转的攻击,或者至少导致内核crash。

下图是一个函数调用对应的 内存栈帧图

举一个典型的内核栈缓冲区溢出攻击的案例,用户进程通过驱动提供的系统调用拷贝数据进内核栈。由于没有严格校验拷贝字符数量,溢出覆盖了内存高地址函数栈帧中的数据。恶意构造了ROP 链,布局了恶意返回地址以及伪造的进程上下文。

引诱内核以高权限执行用户态的一段恶意代码(commit_creds(prepare_kernel_cred(0))) 将进程uid修改为0(root)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yghYg7Rp-1645085316793)(/Users/laiwei/Desktop/攻防训练营课程开发/图库/ret2user完整版.png)]

最后执行system("/bin/sh"), fork一个新的权限为root的shell进程控制系统。

任意内存读

当内核面向用户态的接口中存在类似如下代码时,即可完成任意内存读。

//src地址 用户入参可控,可以指定任意内核态地址,泄露内核数据
copy_from_user(dest, src, len); 
//不限于copy_xxx api, memcpy等都能达到类似效果

因此,一定要校验入参地址范围。

任意内存写
  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值