【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权限,才能访问。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值