任务段&任务门

TSS段用来权限切换的时候,替换原来寄存器的信息。
TSS段的结构,一共104个字节,里面存放了上一个进程中的寄存器,栈和其他的一些信息

任务门的描述符,也存放在IDT表中。其中的Reserved 都是保留位,不需要自己构造。

在这里插入图片描述
TSS段的描述符,存放在GDT表中。其中TYPE位为9(1001)的时候,说明这个TSS没有加载到TR寄存器中。当TYPE位为B(1011)的时候,说明这个TSS已经加载到了TR寄存器中。
在这里插入图片描述

TR寄存器
在这里插入图片描述

构造过程

观察当前的TSS段描述符在GDT表中的哪个位置。
在这里插入图片描述
可以到地址去观察该结构,发现全是0,只有esp和ss中存放的有数据。
在这里插入图片描述
在其他的位置构造一个TSS段的描述符
在这里插入图片描述
然后通过!process 0 0来获取CR3(页基地址)的值填入,然后就实现了成功的切换
在这里插入图片描述
代码

#include "stdafx.h"
#include <WINDOWS.H>
typedef struct _KTSS
{
    USHORT Backlink;                                                        //0x0
    USHORT Reserved0;                                                       //0x2
    ULONG Esp0;                                                             //0x4保存 0 环栈指针
    USHORT Ss0;                                                             //0x8保存 0 环栈段选择子
    USHORT Reserved1;                                                       //0xa
    ULONG NotUsed1[4];                                                      //0xc
    ULONG CR3;                                                              //0x1c
    ULONG Eip;                                                              //0x20
    ULONG EFlags;                                                           //0x24
    ULONG Eax;                                                              //0x28
    ULONG Ecx;                                                              //0x2c
    ULONG Edx;                                                              //0x30
    ULONG Ebx;                                                              //0x34
    ULONG Esp;                                                              //0x38
    ULONG Ebp;                                                              //0x3c
    ULONG Esi;                                                              //0x40
    ULONG Edi;                                                              //0x44
    USHORT Es;                                                              //0x48
    USHORT Reserved2;                                                       //0x4a
    USHORT Cs;                                                              //0x4c
    USHORT Reserved3;                                                       //0x4e
    USHORT Ss;                                                              //0x50
    USHORT Reserved4;                                                       //0x52
    USHORT Ds;                                                              //0x54
    USHORT Reserved5;                                                       //0x56
    USHORT Fs;                                                              //0x58
    USHORT Reserved6;                                                       //0x5a
    USHORT Gs;                                                              //0x5c
    USHORT Reserved7;                                                       //0x5e
    USHORT LDT;                                                             //0x60
    USHORT Reserved8;                                                       //0x62
    USHORT Flags;                                                           //0x64
    USHORT IoMapBase;                                                       //0x66
}KTSS,*PKTSS; 

KTSS tss = {0};
char esp[0x2000] = {0};
char esp0[0x2000] = {0};
char buf[] = {0,0,0,0,0x48,0x00};
char RET[] = {0,0,0,0,0x28,0x00};       

__declspec(naked) void test()
{
        __asm
        {
                int 3              
                iretd//先检查有无任务嵌套 EFL NT的NT位,然后找TSS的Blink替换寄存器返回    如果NT位为0则会查堆栈返回 所以这个最好先把NT位置1再返回
        }
}

int main()
{
        printf("%x\r\n",(DWORD)&tss);
		system("pause");
        memset(esp,0,sizeof(esp));
        memset(esp0,0,sizeof(esp0));

        tss.Eax = 0;
        tss.Ecx = 0;
        tss.Edx = 0;
        tss.Ebx = 0;

        tss.Ebp = 0;
        tss.Esi = 0;
        tss.Edi = 0;

        tss.Cs = 0x8;
        tss.Ss = 0x10;
        tss.Ds = 0x23;
        tss.Es = 0x23;
        tss.Fs = 0x30;

        tss.Esp = (DWORD)esp + 0x2000 - 4;
        tss.Esp0 = (DWORD)esp0 + 0x2000 - 4;
        tss.Ss0 = 0x10;
        tss.Eip = (DWORD)test;

        DWORD dwCR3 = 0;
        printf("CR3=");
        scanf("%x",&dwCR3);
        tss.CR3 = dwCR3;

        __asm
        {
                call fword ptr buf//也可以JUMP过去 再JUMP回来 JUMP会把原TSS置闲 而CALL不会把原TSS置闲
        }
        return 0;
}

同样也可以通过双重错误,从IDT表跳到任务段中。

// door.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <WINDOWS.H>

//0x20ac bytes (sizeof)
typedef struct _KTSS
{
    USHORT Backlink;                                                        //0x0
    USHORT Reserved0;                                                       //0x2
    ULONG Esp0;                                                             //0x4
    USHORT Ss0;                                                             //0x8
    USHORT Reserved1;                                                       //0xa
    ULONG NotUsed1[4];                                                      //0xc
    ULONG CR3;                                                              //0x1c
    ULONG Eip;                                                              //0x20
    ULONG EFlags;                                                           //0x24
    ULONG Eax;                                                              //0x28
    ULONG Ecx;                                                              //0x2c
    ULONG Edx;                                                              //0x30
    ULONG Ebx;                                                              //0x34
    ULONG Esp;                                                              //0x38
    ULONG Ebp;                                                              //0x3c
    ULONG Esi;                                                              //0x40
    ULONG Edi;                                                              //0x44
    USHORT Es;                                                              //0x48
    USHORT Reserved2;                                                       //0x4a
    USHORT Cs;                                                              //0x4c
    USHORT Reserved3;                                                       //0x4e
    USHORT Ss;                                                              //0x50
    USHORT Reserved4;                                                       //0x52
    USHORT Ds;                                                              //0x54
    USHORT Reserved5;                                                       //0x56
    USHORT Fs;                                                              //0x58
    USHORT Reserved6;                                                       //0x5a
    USHORT Gs;                                                              //0x5c
    USHORT Reserved7;                                                       //0x5e
    USHORT LDT;                                                             //0x60
    USHORT Reserved8;                                                       //0x62
    USHORT Flags;                                                           //0x64
    USHORT IoMapBase;                                                       //0x66
    //struct _KiIoAccessMap IoMaps[1];                                        //0x68
    //UCHAR IntDirectionMap[32];                                              //0x208c
}KTSS,*PKTSS; 


KTSS tss = {0};

char esp[0x2000] = {0};
char esp0[0x2000] = {0};

char buf[] = {0,0,0,0,0x48,0x00};
char RET[] = {0,0,0,0,0x28,0x00};       

__declspec(naked) void test()
{
        __asm
        {
                int 3              
                iretd
        }
}

int main()
{
		printf("%x\r\n",(DWORD)&test);
        printf("%x\r\n",(DWORD)&tss);
		system("pause");
        memset(esp,0xcc,sizeof(esp));
        memset(esp0,0xcc,sizeof(esp0));

        tss.Eax = 0;
        tss.Ecx = 0;
        tss.Edx = 0;
        tss.Ebx = 0;

        tss.Ebp = 0;
        tss.Esi = 0;
        tss.Edi = 0;

        tss.Cs = 0x8;
        tss.Ss = 0x10;
        tss.Ds = 0x23;
        tss.Es = 0x23;
        tss.Fs = 0x30;

        tss.Esp = (DWORD)esp + 0x2000 - 4;
        tss.Esp0 = (DWORD)esp0 + 0x2000 - 4;
        tss.Ss0 = 0x10;
        tss.Eip = (DWORD)test;

        DWORD dwCR3 = 0;
        printf("CR3=");
        scanf("%x",&dwCR3);
        tss.CR3 = dwCR3;

        _asm{
            int 0x20;
        }
        return 0;
}

修改IDT表,让报错之后能再报一次错转入任务段中
在这里插入图片描述
修改GDT表
在这里插入图片描述
输入CR3的页基址,实现提权
在这里插入图片描述

TIPS

int 3 断下时,如果不恢复eflags寄存器,其就会卡死。
因为当进行TSS跳转时,其会将老的TSS保存在新的TSS头部(上面我们看到),当我们使用iretd返回时,其不是像中断那样根据返回地址,而是根据TSS段选择子找旧的TSS段内存,然后将里面的寄存器全部加载进去。
而INT 3 会清空 VM、NT、IF、TF四个位,其中NT表示嵌套任务段(nested task),如果清空,其就认为不存在任务段嵌套,直接像常规那样,根据返回地址返回,此时就会出错。
因此就会存在下面一段代码来修改elfags寄存器中的NT位。

    pushfd;
    pop eax;
    or eax,0x4000;
    push eax;
   popfd;
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值