【2021.03.16】代码跨段跳转实验
作者:互联网
本节内容
通过 JMP FAR 指令修改CS段寄存器
要点回顾
前文以 JMP 0x20:0x004183D7 为例,提到了代码跨段跳转的五个步骤,分别是:
- 拆分段选择子:确认RPL、TI、索引。
- 查询GDT表得到段描述符。
- 权限检查:一致代码段与非一致代码段检查方式不一样。
- 加载段描述符:加载段描述符至段寄存器,真正修改CS段寄存器。
- 代码执行:修改EIP(新CS.BASE + EIP),赋值给EIP寄存器并且执行。
构造段描述符
如何区分是否为数据段/代码段?
如 00cf9b00`0000ffff :
- 通过观察段描述符的高4字节的第五位(9或f),能确定是代码段还是数据段。
- 通过观察段描述符的高4字节的第六位(b),b是大于8的,在TYPE域表格中查找发现大于等于8的就是代码段。
找一个非一致代码段描述符,复制一份并写入GDT表中:
将 00cffb00`0000ffff 数据写入某个P位为0的位置。
8003f040 0000f200`0400ffff 00000000`00000000
kd> eq 8003f048 00cffb00`0000ffff(注意要使用Windbg查看新增是否成功)
OD中进行测试
在OD中,执行跨段跳转 JMP FAR 004B:0041B840D。
执行成功,实现了对CS段寄存器和EIP的同时修改。
修改段描述符的权限级别
将 00cffb00`0000ffff 修改为 00cf9b00`0000ffff(非一致代码段,且DPL为0)。
在OD中,执行跨段跳转 JMP FAR 004B:0041840D。
跳转到了ntdll,进入了异常模块,当前CPL为3,权限检查未通过,失败了。
非一致代码段要求CPL与DPL必须一致,才可以跳过去执行,否则无法加载。
将段描述符的属性修改为一致代码段
一致代码段允许低权限访问高权限。
将 00cffb00`0000ffff 修改为 00cf9f00`0000ffff。
kd> eq 8003f048 00cf9f00`0000ffff
修改为9后,DPL已经变成了0。
将b修改为f后,就变成了一致代码段。
在OD中,执行跨段跳转 JMP FAR 004B:0041840D。
从低权限跳转至DPL为0的高权限已经成功了。
为什么可以跳转?因为这个代码段是一致代码段。
总结
- 为了对数据进行保护,普通代码段是进制不同级别进行访问的。用户态的代码不能访问内核的数据。同样,内核态的代码也不能访问用户态的数据。
- 如果想提供一些通用的功能,而且这些功能并不会破坏内核数据,那么可以选择一致代码段。这样,低权限的程序可以在不提升CPL权限等级的情况下访问。
- 如果想访问普通代码段,只有通过调用门等提升CPL权限,才能访问。
标签:0000ffff,2021.03,16,代码段,描述符,一致,跳转,权限 来源: https://blog.csdn.net/qq_18120361/article/details/114903080