中断门
中断门与调用门类似,可以进行跨段和提权
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(); }