其他分享
首页 > 其他分享> > 【2021.03.16】代码跨段跳转实验

【2021.03.16】代码跨段跳转实验

作者:互联网

本节内容

通过 JMP FAR 指令修改CS段寄存器

要点回顾

前文以 JMP 0x20:0x004183D7 为例,提到了代码跨段跳转的五个步骤,分别是:

  1. 拆分段选择子:确认RPL、TI、索引。
  2. 查询GDT表得到段描述符。
  3. 权限检查:一致代码段与非一致代码段检查方式不一样。
  4. 加载段描述符:加载段描述符至段寄存器,真正修改CS段寄存器。
  5. 代码执行:修改EIP(新CS.BASE + EIP),赋值给EIP寄存器并且执行。

构造段描述符

如何区分是否为数据段/代码段?

如 00cf9b00`0000ffff :

  1. 通过观察段描述符的高4字节的第五位(9或f),能确定是代码段还是数据段。
  2. 通过观察段描述符的高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的高权限已经成功了。

为什么可以跳转?因为这个代码段是一致代码段。

总结

  1. 为了对数据进行保护,普通代码段是进制不同级别进行访问的。用户态的代码不能访问内核的数据。同样,内核态的代码也不能访问用户态的数据。
  2. 如果想提供一些通用的功能,而且这些功能并不会破坏内核数据,那么可以选择一致代码段。这样,低权限的程序可以在不提升CPL权限等级的情况下访问。
  3. 如果想访问普通代码段,只有通过调用门等提升CPL权限,才能访问。

标签:0000ffff,2021.03,16,代码段,描述符,一致,跳转,权限
来源: https://blog.csdn.net/qq_18120361/article/details/114903080