中断门
中断门与调用门类似,可以进行跨段和提权
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(); }
在调用门中实现使用IRETD返回 在中断门中实现用RETF返回.
#include <windows.h>
void __declspec(naked) tym()
{
//调用门使用IRETD返回
__asm
{
IRETD
}
}
//中断使用RETF返回
void __declspec(naked) zdm()
{
__asm
{
sub esp,0x4
mov eax,dword ptr ds:[esp+0xC] //取ELFAGE
mov dword ptr ds:[esp],eax
popfd //修改ELFAGE寄存器
//重组堆栈,按照调用门堆栈的格式,这样就可以使用RETF返回
mov eax,dword ptr ds:[esp+0xC] //esp
mov edx,dword ptr ds:[esp+0x10] //ss
mov dword ptr ds:[esp+0x8],eax
mov dword ptr ds:[esp+0xc],edx
RETF
}
}
int main(int argc, char* argv[])
{
//在调用门中实现使用IRETD返回 在中断门中实现用RETF返回.
printf("tym:%X\r\n",tym);
printf("zdm:%X\r\n",zdm);
getchar();
BYTE CodeBuff[6] = {0};
*(WORD*)&CodeBuff[4] = 0X93;
__asm
{
pushfd //将标志位寄存器压入堆栈,作为调用门参数,而调用门参数刚刚好就从第3个位置分配,与中断门的EFLAGE寄存器位置相同
call fword ptr ds:[CodeBuff]
add esp,0x4
}
printf("调用门返回成功\r\n");
getchar();
__asm
{
INT 32
}
printf("中断门返回成功\r\n");
getchar();
}

浙公网安备 33010602011771号