首页
社区
课程
招聘
[原创]任务门进1环
发表于: 2020-4-30 16:44 8479

[原创]任务门进1环

2020-4-30 16:44
8479

0x1:

准备工作:

(需要了解 段任务段, 任务门,  权限)

打开windbg 输入下面指令

  • 构造一系列需要的段描述与符

  • 任务门 eq 8003f500 0000e500`00C30000

  • 任务段 eq 8003f0c0 0000a912`FDCC0068

  • cs: eq 8003f090 00cfbb00`0000ffff

  • ds: eq 8003f0b0 00cfb300`0000fff

0x2:

  • 代码:

#include <STDIO.H>
#include <WINDOWS.H>
DWORD dwOK;
DWORD dwESP;
DWORD dwCS;
void __declspec(naked) func()
{
	dwOK = 1;
	__asm
	{
		//int 3
	    mov eax,esp
            mov dwESP,eax
            mov ax,cs
            mov word ptr [dwCS],ax
            iretd
	}
}

int main(int argc, char* argv[])
{
	char bu[0x10];  //12ff70
	//char esp0[0x10];  //0012FF60
	int iCr3;
	
	printf("input CR3:\n");
	scanf("%x", &iCr3);
	
	//0x0012FDCC
	DWORD iTss[0x68] = {
		        0x00000000,		//link
			0x00000000,		//esp0		//(DWORD)bu
			0x00000000,		//ss0
			(DWORD)bu+4,		//esp1
			0x000000B1,		//ss1
			0x00000000,		//esp2
			0x00000000,		//ss2
			(DWORD)iCr3,	//cr3
			(DWORD)func,	//eip
			0x00000000,		//eflags
			0x00000000,		//eax
			0x00000000,		//ecx
			0x00000000,		//edx
			0x00000000,		//ebx
			(DWORD)bu,		//esp
			0x00000000,		//ebp
			0x00000000,		//esi
			0x00000000,		//edi
			0x00000023,		//es
			0x00000091,		//cs		0x0000001B //0huan 0x00000008
			0x000000B1,		//ss		0x00000023 //0huan 0x00000010
			0x00000023,		//ds
			0x000000b9,		//fs
			0x00000000,		//gs
			0x00000000,		//dit
			0x20ac0000};
		
	char buff[6];
		
	*(DWORD*)&buff[0] = 0x12345678;
	*(WORD*)&buff[4] = 0xC0;
		
	__asm
	{
	    int 0x20
	}
		
	printf("ok=%d \t ESP=%x \t CS=%x \n", dwOK, dwESP, dwCS);
		
	//getchar();
	return 0;
}

0x3:

  • 运行你得程序 (停留在等待输入CR3那里), 然后记住自己程序的名字 比如 1.exe

  • 打开windbg 输入: !process 0 0 找到对应的CR3 (红线部分)

  • 在windbg image 那栏找到你自己程序的名字 

  • 看控制台输出内容是不是自己构造的1环 段选择子, 是就说名成功了


0x4:

Tss:

  • 总结:

  1. 上图中 使用任务门进入一环时候 esp 012 和 ss 012 不需要赋值,程序直接取得就是 esp 和 ss (经过测验得出结论, 不知道原因)

  2. fs:三环一环都可以正常运行

  3. cs:代码段描述符 (dpl = 1)

  4. ss:数据段描述符就可以 (dpl = 1)

  5. 其他值都是我做测试用的,  无视掉就可以

  6. 总结下:  修改 cs ss esp 就可以成功进入一环

  7. 其他门 可以直接修改 esp 0,1,2 and ss 0,1,2 (不得原因 = = 有兴趣得大家可以测试下)

  8. 蓝蓝(你懂的)更健康 哈哈





[课程]FART 脱壳王!加量不加价!FART作者讲授!

最后于 2020-4-30 16:49 被清风qfccc编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (10)
雪    币: 3102
活跃值: (3623)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
esp 0 1 2的作用是用来指定    你使用任务门进1环后如果再发生由中断,调用门,陷阱门产生的权限切换的堆栈;使用任务段任务门本身过程中堆栈是由ESP和SS来决定的,和ESP 0 1 2没关系
2020-5-2 19:40
0
雪    币: 305
活跃值: (403)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
Mr.hack esp 0 1 2的作用是用来指定 你使用任务门进1环后如果再发生由中断,调用门,陷阱门产生的权限切换的堆栈;使用任务段任务门本身过程中堆栈是由ESP和SS来决定的,和ESP 0 1 2没关系
原来是这样, 感谢老哥解答啊,  我之前就一直纳闷来着
2020-5-6 10:50
0
雪    币: 9
活跃值: (314)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
兄弟,为什么有任务段这种东西了还要提供一下任务门呢?
2020-5-28 20:27
0
雪    币: 399
活跃值: (68)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
请问一下,这代码直接崩了吧,能进入到func()这里,只是返回的时候无法返回吧。请问你的过了吗?还执行了什么?谢谢
2020-5-28 21:42
0
雪    币: 259
活跃值: (283)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
666
2020-5-28 22:00
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
老哥,代码跑起来蓝了,看了下有个地方不解  0x000000b9,     //fs  gdt表里的index:17项好像没改哇?
2020-7-4 23:24
0
雪    币: 167
活跃值: (876)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
任务段 eq 8003f0c0 0000a912`FDCC0068,大兄弟,如果我没记错的化是E9吧
2020-7-25 23:26
0
雪    币: 50
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
印度硬汉 兄弟,为什么有任务段这种东西了还要提供一下任务门呢?
TSS(Task State Segment)任务状态段
一、如果你用jmp跳到TSS段,你还得自己jmp回到之前的TR寄存所保存的TSS段,
二、如果是call的话你还得修改下EFLAG寄存器的NT位,之后用iret返回。
       还不如直接用状态门,只需要搞一个任务门,之后直接iret返回,不需要修改EFLAG和不需要自己jmp回来这也许就是任务门的优点吧
2021-8-13 19:15
0
雪    币: 50
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
#include <iostream>
#include <windows.h>




typedef struct TSS {
	DWORD link; // 保存前一个 TSS 段选择子,使用 call 指令切换寄存器的时候由CPU填写。
	// 这 6 个值是固定不变的,用于提权,CPU 切换栈的时候用
	DWORD esp0; // 保存 0 环栈指针
	DWORD ss0;  // 保存 0 环栈段选择子
	DWORD esp1; // 保存 1 环栈指针
	DWORD ss1;  // 保存 1 环栈段选择子
	DWORD esp2; // 保存 2 环栈指针
	DWORD ss2;  // 保存 2 环栈段选择子
	// 下面这些都是用来做切换寄存器值用的,切换寄存器的时候由CPU自动填写。
	DWORD cr3;
	DWORD eip;
	DWORD eflags;
	DWORD eax;
	DWORD ecx;
	DWORD edx;
	DWORD ebx;
	DWORD esp;
	DWORD ebp;
	DWORD esi;
	DWORD edi;
	DWORD es;
	DWORD cs;
	DWORD ss;
	DWORD ds;
	DWORD fs;
	DWORD gs;
	DWORD ldt;
	// I/O 位图基地址域
	DWORD io_map;
} TSS;

DWORD st; 

DWORD g_esp;
DWORD g_cs;
//_declspec(naked)
_declspec(naked) void func() {
	__asm {
		mov g_esp, esp;
		mov eax,0;
		mov ax, cs;
		mov g_cs, eax;
		iret;
	}
}

TSS tss = {
		0x00000000,//link
	    0x00000000,//esp0
		0x00000010,//ss0
		0x00000000,//esp1
		0x00000000,//ss1
		0x00000000,//esp2
		0x00000000,//ss2
		0x00000000,//cr3
		(DWORD)func,//eip
		0x00000000,//eflags
		0x00000000,//eax
		0x00000000,//ecx
		0x00000000,//edx
		0x00000000,//ebx
		0x00000000,//esp
		0x00000000,//ebp
		0x00000000,//esi
		0x00000000,//edi
		0x00000023,//es  
		0x000000B1,//cs  
		0x000000C1,//ss
		0x00000023,//ds
		0x000000D1,//fs  进一环,我把FS也改了,因为进0环的时候FS为30,DLP为0
		0x00000000,//gs
		0x00000000,//ldt
		0
};

int main(int argc, char* argv[])
{
	/*
	TSS(GDT)
	eq 8003f090 0000E941`e0a00068
	Task-Gate(IDT)
	eq 8003f500 0000E500`00930000
	CS
	eq 8003f0b0 00cfBb00`0000ffff   
    SS
	eq 8003f0c0 00cfB300`0000ffff
	FS
	eq 8003f0d0 ffc0B3df`f0000001
	*/
	st = (DWORD)VirtualAlloc((void*)0,0x1000,MEM_RESERVE | MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	tss.esp = st + 0x800;
	tss.esp0 = st + 0x800;
	printf("TSS:%x\n", &tss);
	printf("func:%x\n", tss.eip);
	printf("please input cr3:\n");
	scanf("%x", &tss.cr3);
	
	__asm 
	{
		int 0x20;
	}
	VirtualFree((LPVOID)st,0x1000,MEM_RELEASE);
	printf("g_cs = %08x\ng_esp = %08x\n", g_cs, g_esp);
	getchar();
	return 0;
}


最后于 2021-8-13 19:30 被wx_大可爱编辑 ,原因:
2021-8-13 19:25
0
雪    币: 50
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
taolaoda 任务段 eq 8003f0c0 0000a912`FDCC0068,大兄弟,如果我没记错的化是E9吧
经过测试,A9和E9都能跑
2021-8-13 19:26
0
游客
登录 | 注册 方可回帖
返回
//