【HUST】网络攻防实践|6_物联网设备固件安全实验|实验三 FreeRTOS-MPU 保护绕过
文章目录
写在最前:一定要先将task3.sct
文件链接到项目中,具体操作后文有写,而且我在附加内容里解释了sct文件的含义。
终于可以告别这个实践了。大家在心得里可以加一句“任务量较大,建议减少任务量”吗?
实验三 FreeRTOS-MPU 保护绕过
实验要求
MPU预设置:
a) 编写 C 代码实现基于 FreeRTOS-MPU v10.4 的提权代码和指定函数查找
b) 利用溢出漏洞实现在 FreeRTOS MPU V10.4 版本的系统提权和 Flag 函数打印
子任务1
首先,和上一个实验相似地,也是看一下.c
文件的结构。
main
函数:
① 定义无符号整型变量id
,赋值为学号末4位;
② 调用prvSetupHardware()
,硬件初始化;
③ 调用StartFreeRTOS(id, vTask3)
;
④ 使用for(;;)
让程序不退出。
vTask3
的内容,只有for(;;)
。
头文件和lib文件的作用与上一个实验差不多。
因此,所有任务要求都集中在StartFreeRTOS
里了,我们需要进行进一步的逆向分析。
逆向分析StartFreeRTOS
IDA Pro打开并反编译StartFreeRTOS
如下:
可以看到,该函数大致有如下几个操作:
① 将byte_7714
的地址指向的内容拷贝给任务参数xTask3Parameters
;
② 设置任务参数xTask3Parameters
的函数指针为vTask3
;
③ val *= id;
④ 调用xTaskCreateRetricted
,结合任务参数xTask3Parameters
创建被约束的任务;
⑤ 调用vTaskStartScheduler()
启动任务序列。
我们要做的是在vTask3
中调用提权函数,然后再调用打印flag的函数。
打印flag的函数好找,直接在IDA Pro的字符串窗口找就行,找到后双击点开,再查看引用:
总之能找到一个叫vTaskRemove
的函数,它是无参数函数,能够打印flag。
找提权函数,我一开始完全不知道怎么找。
直到看了下实验讲解的PPT,看到了下面这张图:
可见,如果普通任务要使用内核API,不能直接使用,而是要添加MPU_
,添加了这个的函数,其中包含提权操作。而且,提权操作应该是利用SVC
中断。
因此,我们不妨在IDA Pro中随便打开一个MPU_
的函数逆向分析一下,找到其中的提权操作。我以MPU_vTaskDelete
为例。IDA Pro中分析如下:
上图中我框出来的就是提权操作。可以看到,就是先做了些进入函数的压栈操作,随后把要提权的Task
传入R4
,如果R4
不为0就跳转提权函数(如果为0那么本身就是特权级)。然后再常规地执行xTaskDelete
这个内核API。
很明显,提权函数就是xPortRaisePrivilege
,而且利用寄存器R4
传参,所以它也是个无参数的函数。
先不急着把地址填入,因为这个地址在修改了vTask3
内容之后会发生改变。先假装已经找到了地址,并在vTask3
中使用地址调用这些函数,这样,找到之后就只需要修改成对应的地址。添加代码如下:
注意,随便填的地址不得为全零、不得相同,最好是填得像一点,否则二度修改后,地址又会变化。
void (*pPrivilege)();
void (*pFunc)();
pPrivilege=(void(*)())0x00001051;
pFunc=(void(*)())0x000029AD;
pPrivilege();
pFunc();
Rebuild后,去IDA Pro中查找函数地址。在使用地址调用函数的时候,需要加一。
需要注意的是,当函数地址已经添加正确,但
log.txt
中却连vTask3
都没有的时候,很可能是项目的配置出了问题,如内存地址分布,出问题的log.txt
如下:
此时必须要导入老师发的
task3.srt
,导入方式如下:
导入完成后,重新构建项目,并重新逆向分析地址。(我导入后重新截了一遍图)
sct具体的作用见下文的附加内容1。
打印 Flag 函数名称和地址
名称:vTaskRemove
;
地址:0x000005F4
。
内容如下图所示:
用于提权的函数名称和地址
名称:xPortRaisePrivilege
;
地址:0x00008EDC
。
内容如下图所示:
填写的代码
注意,需要将上述找到的地址加1后再调用。填写的代码如下图所示:
模拟运行截图
运行并打印flag的结果如下:
log.txt如下:
之所以要把log.txt
也截图出来,是因为之前分析的时候,可以看到xPortRaisePrivilege
函数提权的任务是R4
寄存器,而我们只是简单地调用了该函数,并未对R4
寄存器做处理。可是也成功了。
查看log.txt
会发现,并没有明显的对R4寄存器处理的内容,最近一次赋值是prvSVCHandler的pop。我猜测有可能只需要执行svc 2
中断即可提权,具体情况尚未明确,不过对本实验无任何影响。
后来写flag5报告的时候,意识到当R4为0时,提权的应该就是本任务;或者,不论R4的取值,都会对本任务提权。
附加内容1:sct文件的作用
下图左是老师发的sct文件,下图右是软件自动生成的sct文件。
sct文件也就是内存映射布局文件。
一般情况,编译的时候,只是让所有的函数(如上图中的.ANY (+R0)
)按照函数名称排序放进内存里,并没有所谓特权访问还是用户访问的访问控制。
在我们设置了MPU之后,编译并不会跟着受影响。因此,非特权函数可能就放入了我们自己规定的MPU中特权函数的那个区域,非特权函数保存在了特权函数的地址范围,MPU就不会允许执行了。
而老师修改后的sct文件,对API的位置重新布局,把特权函数privileged_functions
放到了第一段(就是MPU中只允许特权执行的那个位置ER_IROM1
),把其他的放到了ER_IROM2
。并把特权数据privileged_data
放到了MPU中只允许特权可读写的段RW_IRAM1
,把其他的放到了RW_IRAM2
。
这样,就会让内存映射与MPU设置一致了。
子任务2
逆向分析StartFreeRTOS
该任务逆向分析函数地址与上一个任务相似,在此不做赘述。
打印 Flag 函数名称和地址
名称:vTaskDelayBackup
;
地址:0x00001C7C
。
内容如下:
用于提权的函数名称和地址
名称:xPortRaisePrivilege
;
地址:0x000086E2
。
内容如下:
分析过程
该文件的main
函数超长,不过很简单,如下图所示:
暂时只能看到,最后输入的字符串InputBuffer
长度最大为0x63。
再点开StartFreeRTOS:
只是运行了受约束的vTask3
任务,其他啥也没干。
由于这是传参传进来的,不能直接点开,所以先返回上一级,然后再点开vTask3
任务:
vTask3
调用了Function()
,根据经验,这就是出问题的代码了。
找到存在在溢出的缓冲区
点开Function
:
发现居然Function
传进来了参数,更重要的是出现了length
和InputBuffer
,而且赋值给HelperBuffer
,并且HelperBuffer
的大小只有12,说明HelperBuffer
可能就是溢出的缓冲区。
以汇编形式显示Function
函数如下:
对PUSH和POP的解释:ARM架构的栈是递减栈,PUSH的时候从右至左,POP的时候从左至右。
查看汇编之后,会发现其实严格来说,压根就没有什么溢出缓冲区。Function
函数,它先push
了4个寄存器,然后在函数的最开始使用mov buffer, sp
,直接改变栈顶指针sp,接下来立马用InputBuffer
的内容逐一填充buffer
(在我的IDA中该变量名被解析成HelpBuffer
)。最后pop
的时候,pop
的内容不就是HelpBuffer[0]
、HelpBuffer[1]
、HelpBuffer[2]
等吗?
覆盖寄存器的值,就是Function
的目的,也是设置buffer
的作用,它就是想往栈上写、往寄存器上写。
既然,该缓冲区的每一个比特,目的都是向不应该写的寄存器或栈上写数据,它就压根没有与正常功能有关的部分。就像拿一张纸画画,正常操作画在纸上,但是涂多了就溢出到桌上了,这张纸叫做溢出缓冲区;而这个代码就是连纸都没有。
综上,我认为这并不是一个典型的缓冲区溢出代码。如果非要说有个溢出缓冲区,那就是故意构造的这个HelpBuffer
,而且该溢出缓冲区的长度为0,没有正常功能。
栈示意图
点开Function的bp,可以看到IDA Pro中的栈帧。
不过,这并不能很好地解释栈中的内容。我重新绘制了栈示意图。
当执行mov buffer, sp
前后的栈示意图如下:
LR(Function)需要覆盖成提权函数,而调用提权函数之后,还需要调用打印flag的函数,所以还要构造溢出提权调用的返回地址的栈结构。完全构造完毕的栈示意图在后续“溢出提权”中会画出。
溢出提权
溢出提权调用xPortRaisePrivilege
,地址是0x000086E2
。该函数第一行是PUSH {xRunningPrivileged,LR}
。如果执行这一句,就会改变我们已经构造好的栈帧结构,也会导致返回地址无法被覆盖,因此需要跳过这一句,从地址0x000086E4
开始。再加上基地址是1,因此LR(Function)
需要被覆盖成0x000086E5
。
顺利进入并执行提权函数后,还要继续执行打印flag的函数。返回时执行了POP {xRunningPrivileged,LR}
因此需要构造8个HelpBuffer
字节,完整的栈示意图如下:
覆盖返回地址的解析过程
在Function
中返回值被覆盖成xPortRaisePrivilege
第二行地址加1,即0x000086E5
,因此它返回时会从xPortRaisePrivilege
的第二行代码开始执行,并完成提权;
在xPortRaisePrivilege
中返回值被覆盖成vTaskDelayBackup
地址加1,即0x00001C7C
,因此它返回时会从vTaskDelayBackup
的第一行代码执行,并完成flag打印。
模拟运行截图
完结撒花!!!
【HUST】网络攻防实践|6_物联网设备固件安全实验|实验三 FreeRTOS-MPU 保护绕过的更多相关文章
- <网络攻防实践> 课程总结20169216
课程总结20169216 每周作业链接汇总 第一周作业:Linux基础入门(1-5).基本概念及操作 第二周作业:linux基础入门(6-11).网络攻防技术概述网络攻防试验环境搭构.Kali教学视频 ...
- 20169214 2016-2017-2 《网络攻防实践》第十一周实验 SQL注入
20169214 2016-2017-2 <网络攻防实践>SQL注入实验 SQL注入技术是利用web应用程序和数据库服务器之间的接口来篡改网站内容的攻击技术.通过把SQL命令插入到Web表 ...
- 2017-2018-2 20179204《网络攻防实践》第十一周学习总结 SQL注入攻击与实践
第1节 研究缓冲区溢出的原理,至少针对两种数据库进行差异化研究 1.1 原理 在计算机内部,输入数据通常被存放在一个临时空间内,这个临时存放的空间就被称为缓冲区,缓冲区的长度事先已经被程序或者操作系统 ...
- 2017-2018-2 20179204《网络攻防实践》linux基础
我在实验楼中学习了Linux基础入门课程,这里做一个学习小结. 第一节 linux系统简介 本节主要介绍了linux是什么.发展历史.重要人物.linux与window的区别以及如何学习linux. ...
- 2017-2018-2 20179215《网络攻防实践》seed缓冲区溢出实验
seed缓冲区溢出实验 有漏洞的程序: /* stack.c */ /* This program has a buffer overflow vulnerability. */ /* Our tas ...
- 20169206 2016-2017-2 《网络攻防实践》 nmap的使用
Part I 使用nmap扫描ubuntu靶机 先给出nmap的官方中文操作手册https://nmap.org/man/zh/,其实并不太好用,而且有时候会打不开,但至少是官方手册. 探查操作系统 ...
- 2017-2018-2 20179204《网络攻防实践》第十三周学习总结 python实现国密算法
国密商用算法是指国密SM系列算法,包括基于椭圆曲线的非对称公钥密码SM2算法.密码杂凑SM3算法.分组密码SM4算法,还有只以IP核形式提供的非公开算法流程的对称密码SM1算法等. 第1节 SM2非对 ...
- 20155334 《网络攻防》 Exp9 Web安全基础
<网络攻防> Exp9 Web安全基础 一.实验后回答问题 SQL注入攻击原理,如何防御: 原理: 就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服 ...
- 20155334 《网络攻防》Exp4 恶意代码分析
<网络攻防>Exp4 恶意代码分析 一.实验问题回答 如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法来监 ...
- 20145335郝昊《网络攻防》Exp4 Adobe阅读器漏洞攻击
20145335郝昊<网络攻防>Exp4 Adobe阅读器漏洞攻击 实验内容 初步掌握平台matesploit的使用 有了初步完成渗透操作的思路 本次攻击对象为:windows xp sp ...
随机推荐
- CentOS7安装RabbitMQ (安装包安装)
环境: CentOS7 需要安装:erlang 22.2 rabbitmq 3.8.3 参考: rabbit官网地址:http://www.rabbitmq.com/which-erlang.htm ...
- Javascript Object对象转Map
1. Object对象 const data = { "banana": [ { "color": "yellow", "coun ...
- BloomFilter详解
目录 BloomFilter 原理: 问题引入:黑名单管理程序 哈希.哈希函数 BloomFilter : 3.4 BloomFilter 的缺陷.改进: 代码实现 黑名单blacklist.py: ...
- 数据挖掘 | 数据隐私(3) | 差分隐私 | 差分隐私概论(上)(Intro to Differential Privacy 1)
L3-Intro to Differential Privacy 从这节课开始就要介绍差分隐私算法了. 随机响应(Randomized Response) 场景提出 假若你是某一门课的教授,你希望统计 ...
- 探秘Transformer系列之(10)--- 自注意力
探秘Transformer系列之(10)--- 自注意力 目录 探秘Transformer系列之(10)--- 自注意力 0x00 概述 0x01 原理 1.1 设计思路 1.2 输入 1.3 QKV ...
- 【自荐】一款简洁、开源的在线白板工具 Drawnix
在线白板工具 Drawnix -- 名字源于绘画(Draw)与凤凰(Phoenix)的灵感交织. Drawnix 的定位是一个开箱即用.开源.免费的在线白板工具产品, 集思维导图.流程图.画笔于一体, ...
- 前端跨域方案-跨域请求代理(asp.net handler)
现在技术开发偏向于使用统一的接口处理浏览器或者app的http请求. 大家都知道因为浏览器的同源策略的原因 js直接请求webapi 接口会有一些问题,即使做好服务器端的配置 同样会有不少的 问题 ...
- C/C++显示类型转换的位拓展方式
最近用verilator写模块的tb,在这里卡了好久(测半天都是C++写的问题) 要点 变量从小位宽到大位宽显示类型转换(explicit cast)时的位拓展方式,取决于转换前变量的符号性. 倘若转 ...
- yolov5 train报错:TypeError: expected np.ndarray (got numpy.ndarray)
前言 mac intel 机器上,使用 yolov5 物体检测训练时报错:TypeError: expected np.ndarray (got numpy.ndarray) 这个错误信息 TypeE ...
- Linux指令详解之:ctl相关命令大礼包
目录 6.4 服务管理命令(ctl大礼包) 6.4.1 systemctl 6.5.2 systemctl小结 6.5.3 timedatectl 6.5.4 localectl 6.5.5 netw ...