回顾之前的知识,jmp 和ret retf 都不能通过调用门提权
jmp :在调用门只能在同权限跳转
ret:改变不了cs
retf:规定只能在同权限或者向低权限跳转【降权】
call:是同权限或者向高权限进行跳转【提权】

iretd:和retf 一样只能降权,但是更jb麻烦。

中断门: idt

image-20241119205151163

image-20241119224258980

我们看到是int 3 是e 所以它的DPL == 3 三环下可以调用 0008 是段选择值,是找的GDT
也就是:如下这个

image-20241119224451728

看看int 3

image-20241119224940141

调用int 3 FS会变成 30h,这些都是函数所定义的

image-20241119225133385

测试:

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
// IDT.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
void __declspec(naked) test()
{
__asm
{

int 3;
iretd;
}
}
#pragma pack(1) //不让结构体内存对齐,因为我们只需要6字节
typedef struct _DDTINFO
{
short limit;
ULONG table;
}DDTINFO;
#pragma pack(0) //只争对中间这一段
int _tmain(int argc, _TCHAR* argv[])
{
cahr bufgdt[6];
DDTINFO bufidt;
printf("%x,\r\n",test);
__asm
{
sgdt bufgdt; //sgdt 获取的GDT 是6个字节 IDT 一样
sidt bufidt;
push fs;
int 32; //会提权后去调用test函数,因为IDT中的offset是我们定义的
pop fs;
}
return 0;
}

image-20241119232224120

找到空白的地方,很梦想这个地方是 Int 32

来填充这个:0040ee00`00081000

image-20241119232915779

1
2
3
4
5
6
堆栈
esp
eip
cs
eflags
ss

这里用sidt来获取idt。创建了一个结构体
0x80b99400 和我们在windbg 上看到的一样

image-20241120170818127

#pragma pack(1)

为什么这里需要使用这个?

因为limit 是2字节,table是4字节,内存会自动对齐,变成8字节。会出现问题,所以需要使用宏。
这样获取到的结构体就是6字节而不是对齐后的8字节。

作业:
返回一定要用iretd吗?可以使用retf吗?

构建陷阱门自己调用玩。