抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

任务段

前置准备

  • 在程序中获取到tss的地址, 例如: 00407030;
  • 拼接段描述符: 0000e940`703020ac;
  • 修改GDTR中段描述符;

知识点

_KTSS结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// _KTSS 结构原形
ntdll!_KTSS
+0x000 Backlink : Uint2B
+0x002 Reserved0 : Uint2B
+0x004 Esp0 : Uint4B
+0x008 Ss0 : Uint2B
+0x00a Reserved1 : Uint2B
+0x00c NotUsed1 : [4] Uint4B
+0x01c CR3 : Uint4B
+0x020 Eip : Uint4B
+0x024 EFlags : Uint4B
+0x028 Eax : Uint4B
+0x02c Ecx : Uint4B
+0x030 Edx : Uint4B
+0x034 Ebx : Uint4B
+0x038 Esp : Uint4B
+0x03c Ebp : Uint4B
+0x040 Esi : Uint4B
+0x044 Edi : Uint4B
+0x048 Es : Uint2B
+0x04a Reserved2 : Uint2B
+0x04c Cs : Uint2B
+0x04e Reserved3 : Uint2B
+0x050 Ss : Uint2B
+0x052 Reserved4 : Uint2B
+0x054 Ds : Uint2B
+0x056 Reserved5 : Uint2B
+0x058 Fs : Uint2B
+0x05a Reserved6 : Uint2B
+0x05c Gs : Uint2B
+0x05e Reserved7 : Uint2B
+0x060 LDT : Uint2B
+0x062 Reserved8 : Uint2B
+0x064 Flags : Uint2B
+0x066 IoMapBase : Uint2B
+0x068 IoMaps : [1] _KiIoAccessMap
+0x208c IntDirectionMap : [32] UChar

代码实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// 当输入CR3后进入0环断点后的各种情况
kd> r tr
tr=00000048 // 当前tr寄存器已改变为0x48, 之前为0x28
kd> dg 28
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0028 80b98c00 000020ab TSS32 Busy 0 Nb By P Nl 0000008b
kd> dt _KTSS 80b98c00
ntdll!_KTSS
+0x000 Backlink : 0
+0x002 Reserved0 : 0
+0x004 Esp0 : 0xad01fcb0
+0x008 Ss0 : 0x10
+0x00a Reserved1 : 0
+0x00c NotUsed1 : [4] 0
+0x01c CR3 : 0
+0x020 Eip : 0x401364
+0x024 EFlags : 0x246
+0x028 Eax : 0
+0x02c Ecx : 0xfde7b46e
+0x030 Edx : 0x270178
+0x034 Ebx : 0x7ffd6000
+0x038 Esp : 0x12fe04
+0x03c Ebp : 0x12ff08
+0x040 Esi : 0x12fe04
+0x044 Edi : 0x12ff08
+0x048 Es : 0x23
+0x04a Reserved2 : 0
+0x04c Cs : 0x1b
+0x04e Reserved3 : 0
+0x050 Ss : 0x23
+0x052 Reserved4 : 0
+0x054 Ds : 0x23
+0x056 Reserved5 : 0
+0x058 Fs : 0x3b
+0x05a Reserved6 : 0
+0x05c Gs : 0
+0x05e Reserved7 : 0
+0x060 LDT : 0
+0x062 Reserved8 : 0
+0x064 Flags : 0
+0x066 IoMapBase : 0x20ac
+0x068 IoMaps : [1] _KiIoAccessMap
+0x208c IntDirectionMap : [32] "???"
kd> u 0x401364
00401364 cc int 3
00401365 c0528bcd rcl byte ptr [edx-75h],0CDh
00401369 50 push eax
0040136a 8d1598134000 lea edx,ds:[401398h]
00401370 e87b020000 call 004015f0
00401375 58 pop eax
00401376 5a pop edx
00401377 5f pop edi
kd> dg 48
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0048 00407030 00000100 TSS32 Busy 3 Nb By P Nl 000000eb
kd> dt _KTSS 00407030
ntdll!_KTSS
+0x000 Backlink : 0x28 // 上一个段的
+0x002 Reserved0 : 0
+0x004 Esp0 : 0x40b0d0
+0x008 Ss0 : 0x10
+0x00a Reserved1 : 0
+0x00c NotUsed1 : [4] 0
+0x01c CR3 : 0x3f31e640
+0x020 Eip : 0x401080
+0x024 EFlags : 2
+0x028 Eax : 0
+0x02c Ecx : 0
+0x030 Edx : 0
+0x034 Ebx : 0
+0x038 Esp : 0x40d0d0
+0x03c Ebp : 0
+0x040 Esi : 0
+0x044 Edi : 0
+0x048 Es : 0x23
+0x04a Reserved2 : 0
+0x04c Cs : 8
+0x04e Reserved3 : 0
+0x050 Ss : 0x10
+0x052 Reserved4 : 0
+0x054 Ds : 0x23
+0x056 Reserved5 : 0
+0x058 Fs : 0x30
+0x05a Reserved6 : 0
+0x05c Gs : 0
+0x05e Reserved7 : 0
+0x060 LDT : 0
+0x062 Reserved8 : 0
+0x064 Flags : 0
+0x066 IoMapBase : 0x20ac
+0x068 IoMaps : [1] _KiIoAccessMap
+0x208c IntDirectionMap : [32] ""
kd> r
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eip=00401080 esp=0040d0d0 ebp=00000000 iopl=0 nv up di pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00004002 // 0100 0000 0000 0010 NT
kd> r esp
esp=0040d0d0 // 上面结构体中的esp
kd> dg 48
P Si Gr Pr Lo
Sel Base Limit Type l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0048 00407030 00000100 TSS32 Busy 3 Nb By P Nl 000000eb
kd> r gdtr
gdtr=80b98800
kd> dq 80b98800
ReadVirtual: 80b98800 not properly sign extended
80b98800 00000000`00000000 00cf9b00`0000ffff
80b98810 00cf9300`0000ffff 00cffb00`0000ffff
80b98820 00cff300`0000ffff 80008bb9`8c0020ab
80b98830 804093b9`b0004fff 7f40f3fd`f0000fff
80b98840 0000f200`0400ffff 0000eb40`70300100 // 段描述符中的eb和48中的一致
80b98850 800089b9`ad200067 800089b9`acb00067
80b98860 00000000`00000000 00000000`00000000
80b98870 800092b9`880003ff 00000000`00000000
kd> r esp
esp=0040d0d0
kd> dds 0040d0d0 // 使用call跨段跳转时会保存cs、esp、ss、eip
0040d0d0 00000000
0040d0d4 00000000
0040d0d8 00000000
0040d0dc 00000000
0040d0e0 00000004
0040d0e4 00000000
0040d0e8 00000002
0040d0ec 00000000
0040d0f0 00000001
0040d0f4 00000000
0040d0f8 00000000
0040d0fc 00000000
0040d100 00000000
0040d104 00000000
0040d108 00000000
0040d10c 00000000
0040d110 00000000
0040d114 00000000
0040d118 00000000
0040d11c 00000000
0040d120 00000000
0040d124 00000000
0040d128 00000000
0040d12c 00000000
0040d130 00000000
0040d134 00000000
0040d138 00000000
0040d13c 00000000
0040d140 00000000
0040d144 00000000
0040d148 00000000
0040d14c 00000000

通过jmp指令提权

  • jmp可以通过任务段提权, 同时替换CS和SS寄存器

怎样返回3环

使用call跨段跳转时会保存cs、esp、ss、eip, 使用任务门时没保存这些值, 怎么返回?

1
2
3
4
5
6
7
8
9
void __declspec(naked) test()
{
__asm
{
int 3; // <-- 导致系统奔溃的主要原因, 清空了NT位

iretd;
}
}

问题剖析

  • 恢复运行后将导致系统崩溃, 中断门会修改VM、NT、IF、TF位, 并按照堆栈返回, 当NT位置0后再根据堆栈返回时将出现系统崩溃;
  • iretd指令首先检测eflag.NT位, 如果NT位等于0, 就按照堆栈返回; 如果NT位等于1, 就按照Backlink找到要返回的上下文环境返回;
  • 解决方式
  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void __declspec(naked) test()
    {
    __asm
    {
    int 3;
    pushfd;
    pop eax;
    or eax, 0x4000;
    push eax;
    popfd;
    iretd;
    }
    }
  2. 需要手动修复dg 28中_KTSS结构的CR3
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    kd> !process 0 0
    **** NT ACTIVE PROCESS DUMP ****
    ...
    PROCESS 85b021a8 SessionId: 1 Cid: 0e60 Peb: 7ffde000 ParentCid: 0e4c
    DirBase: 3f344640 ObjectTable: 959357d8 HandleCount: 7.
    Image: 09_27_TaskSegments(ÈÎÎñ¶Î).exe
    kd> dg 28
    P Si Gr Pr Lo
    Sel Base Limit Type l ze an es ng Flags
    ---- -------- -------- ---------- - -- -- -- -- --------
    0028 80b98c00 000020ab TSS32 Busy 0 Nb By P Nl 0000008b
    kd> dt _KTSS 80b98c00
    ntdll!_KTSS
    +0x000 Backlink : 0
    +0x002 Reserved0 : 0
    +0x004 Esp0 : 0x83f75cb0
    +0x008 Ss0 : 0x10
    +0x00a Reserved1 : 0
    +0x00c NotUsed1 : [4] 0
    +0x01c CR3 : 0 // <-- 需要手动修复成该程序的CR3
    +0x020 Eip : 0
    +0x024 EFlags : 0
    +0x028 Eax : 0
    +0x02c Ecx : 0
    +0x030 Edx : 0
    +0x034 Ebx : 0
    +0x038 Esp : 0
    +0x03c Ebp : 0
    +0x040 Esi : 0
    +0x044 Edi : 0
    +0x048 Es : 0
    +0x04a Reserved2 : 0
    +0x04c Cs : 0
    +0x04e Reserved3 : 0
    +0x050 Ss : 0
    +0x052 Reserved4 : 0
    +0x054 Ds : 0
    +0x056 Reserved5 : 0
    +0x058 Fs : 0
    +0x05a Reserved6 : 0
    +0x05c Gs : 0
    +0x05e Reserved7 : 0
    +0x060 LDT : 0
    +0x062 Reserved8 : 0
    +0x064 Flags : 0
    +0x066 IoMapBase : 0x20ac
    +0x068 IoMaps : [1] _KiIoAccessMap
    +0x208c IntDirectionMap : [32] "???"
    kd> eq 80b98c00+1c 3f344640
    WriteVirtual: 80b98c1c not properly sign extended
    kd> dt _KTSS 80b98c00
    ntdll!_KTSS
    +0x000 Backlink : 0
    +0x002 Reserved0 : 0
    +0x004 Esp0 : 0x83f75cb0
    +0x008 Ss0 : 0x10
    +0x00a Reserved1 : 0
    +0x00c NotUsed1 : [4] 0
    +0x01c CR3 : 0x3f344640 // <-- 修复后
    +0x020 Eip : 0
    +0x024 EFlags : 0
    +0x028 Eax : 0
    +0x02c Ecx : 0
    +0x030 Edx : 0
    +0x034 Ebx : 0
    +0x038 Esp : 0
    +0x03c Ebp : 0
    +0x040 Esi : 0
    +0x044 Edi : 0
    +0x048 Es : 0
    +0x04a Reserved2 : 0
    +0x04c Cs : 0
    +0x04e Reserved3 : 0
    +0x050 Ss : 0
    +0x052 Reserved4 : 0
    +0x054 Ds : 0
    +0x056 Reserved5 : 0
    +0x058 Fs : 0
    +0x05a Reserved6 : 0
    +0x05c Gs : 0
    +0x05e Reserved7 : 0
    +0x060 LDT : 0
    +0x062 Reserved8 : 0
    +0x064 Flags : 0
    +0x066 IoMapBase : 0x20ac
    +0x068 IoMaps : [1] _KiIoAccessMap
    +0x208c IntDirectionMap : [32] "???"

完整代码

包含使用jmp指令实现任务切换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// 09_27_TaskSegments(任务段).cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

// 任务段

#include <iostream>
#include <Windows.h>

// _KTSS 结构原形
/*
ntdll!_KTSS
+0x000 Backlink : Uint2B
+0x002 Reserved0 : Uint2B
+0x004 Esp0 : Uint4B
+0x008 Ss0 : Uint2B
+0x00a Reserved1 : Uint2B
+0x00c NotUsed1 : [4] Uint4B
+0x01c CR3 : Uint4B
+0x020 Eip : Uint4B
+0x024 EFlags : Uint4B
+0x028 Eax : Uint4B
+0x02c Ecx : Uint4B
+0x030 Edx : Uint4B
+0x034 Ebx : Uint4B
+0x038 Esp : Uint4B
+0x03c Ebp : Uint4B
+0x040 Esi : Uint4B
+0x044 Edi : Uint4B
+0x048 Es : Uint2B
+0x04a Reserved2 : Uint2B
+0x04c Cs : Uint2B
+0x04e Reserved3 : Uint2B
+0x050 Ss : Uint2B
+0x052 Reserved4 : Uint2B
+0x054 Ds : Uint2B
+0x056 Reserved5 : Uint2B
+0x058 Fs : Uint2B
+0x05a Reserved6 : Uint2B
+0x05c Gs : Uint2B
+0x05e Reserved7 : Uint2B
+0x060 LDT : Uint2B
+0x062 Reserved8 : Uint2B
+0x064 Flags : Uint2B
+0x066 IoMapBase : Uint2B
+0x068 IoMaps : [1] _KiIoAccessMap
+0x208c IntDirectionMap : [32] UChar
*/

char szRet[6] = { 0 }; // jmp 任务切换跳回

//0x2024 bytes (sizeof)
struct _KiIoAccessMap
{
UCHAR DirectionMap[32]; //0x0
UCHAR IoMap[8196]; //0x20
};

//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;

KTSS tss = { 0 };
char bufEsp0[0x2000] = { 0 };
char bufEsp3[0x2000] = { 0 };

void __declspec(naked) test()
{
#if 0
__asm
{
int 3;
pushfd;
pop eax;
or eax, 0x4000;
push eax;
popfd;
iretd;
}
#else
__asm
{
int 3;
jmp fword ptr szRet;
}
#endif // 0

}

int main()
{
WORD tr = 0;
__asm
{
str tr;
}
*(WORD*)&szRet[4] = tr; // 保存旧的tr值
memset(bufEsp0, 0, 0x2000);
memset(bufEsp3, 0, 0x2000);
tss.Esp0 = (ULONG)bufEsp0 + 0x1FF0;
tss.Esp = (ULONG)bufEsp3 + 0x1FF0;
tss.Eax = 0x1111;
tss.Ss0 = 0x10;
tss.Ss = 0x10;
tss.Cs = 0x8;
tss.Ds = 0x23;
tss.Es = 0x23;
tss.Fs = 0x30;
tss.EFlags = 2;
tss.Eip = (ULONG)test;
tss.IoMapBase = 0x20ac;

printf("请输入你的CR3: ");
DWORD dwCr3 = 0;
ULONG ulCr3 = 0;
ULONG pCr3 = 0;
scanf("%x", &dwCr3);

tss.CR3 = dwCr3;
printf("%p\r\n", &tss);
system("pause");

char bufCode[6] = { 0,0,0,0,0x48,0 };

__asm
{
// call fword ptr bufCode;
jmp fword ptr bufCode; // jmp实现任务切换
}

return 0;
}

评论