中断门与调用门类似,可以进行跨段和提权

  1、INT INDEX; 中断门指令,INDEX作为查询IDT表时的索引

  2、type域位置如果(已知为中断门)其最高位为1表示这是32位的中断门描述符(0xE),为0表示16位的中断门描述符(0x6),32保护模式下不存在为0情况

  3、提权跨段和跨段的堆栈相比调用门多了一个EFLAG寄存器

    只跨段堆栈:返回地址,EFLAGE,CS  c3 b4 40 00 (ret address) 16 02 00 00 (eflage) 1b 00 00 00(cs) 

    提权堆栈:返回地址,CS,EFLAG,ESP,SS c3 b4 40 00 (ret address) 1b 00 00 00(cs) 16 02 00 00(eflage) 30 ff 12 00(esp)  23 00 00 00(ss)

  4、通过中断门提权或跨段不能再通过RETF返回(因中断门与调用门堆栈结构不同),需使用IRET/IRETD

  5、中断门因为不是通过段选择子去IDT表查询,所以没有RPL.权限检测时只检测CPL <= DPL

  6、中断门高4字节的0:3位是弃用,也就表明中断门是无法使用参数

   

 

执行流程:

  1、构造中断门,写入到IDT表

    0040EE00`00081005  //提权的中断门

  2、执行INT 4中断指令,根据4作为索引前往IDT表查询中断门段描述符(4*8+IDT表基址即查询的段描述符地址)

  3、判断从IDT表内查出的段描述符p位,是否为1(可用),判断s位是否为0(系统段描述符),权限检测:判断CPL是否<=DPL

  4、根据SegmentSelector作为段选择子前往GDT表查询代码段描述符

  5、判断从GDT表内查出的代码段描述符p位,是否为1(可用),判断s位是否为1(数据代码段),type域最高位是否为1(代码段)权限检测:判断cpl<=dpl(跨段)还是cpl>=dpl(提权)

  5、修改CS,SS,ESP,EFLAGE,EIP

  6、PUSH SS,PUSH ESP,PUSH ELFAGE,PUSH CS,PUSH 返回地址

  7、使用IRETD返回,IRETD依次出栈到相应寄存器

  

#include <windows.h>
DWORD CSS1 = 0;
DWORD CSS2 = 0;
void __declspec(naked) cc()
{
    __asm
    {
        mov word ptr ds:[CSS1],cs
        IRETD
    }
}
void __declspec(naked) FUN()
{
    __asm
    {
        mov word ptr ds:[CSS2],cs
        INT 32
        IRETD
    }
}

int main(int argc, char* argv[])
{
    printf("Fun Address:%X\r\n",FUN);
    printf("Fun Address:%X\r\n",cc);
    getchar();
    __asm
    {
        INT 4
    }
    printf("cs1:%X\r\n",CSS1);
    printf("cs2:%X\r\n",CSS2);
    getchar();
}

 

版权声明:本文为Hookcc原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/Hookcc/p/12704089.html