调用门学习

构造调用门

调用门描述符
根据上图我们可以看到调用门段描述符的结构,没有base和limit,变成了偏移地址和代码段的段选择子,根据代码段的段选择子可以查GDT表得到代码段的base,加上偏移就得到了需要被调用的地址。此时type的值为c表示32位的调用门,
param Count为参数个数,
P位是存在位,为1时有效。
DPL表示调用门的特权级,用于指定通过调用门访问特定过程所要求的特权级

接下来编写测试代码,

void test()
{

	printf("this is test's space\n");

}

int main(int argc, char* argv[])
{
	char buffer[]={0,0,0,0,0x4B,0};
    *(int *)buffer=(int)test;
	printf("%x\n",test);
	_asm{

		call fword ptr[buffer];
	}
	printf("success");
	return 0;
}

test地址
得到test函数地址为0x00401005,然后用windbg在空白地址构造响应的调用门构造调用门
调用1
测试调用成功。

提权测试

测试代码

int result=0;
__declspec (naked)void test1()
{
	_asm
	{
		pushad
		pushfd
		mov eax, dword ptr ds:[0x8003f008]
		mov result,eax
		popfd
		popad
		retf
	}
}

int main(int argc, char* argv[])
{
	char buffer[]={0,0,0,0,0x4B,0};
    *(int *)buffer=(int)test1;
	printf("%x\n",test);
	_asm{

		call fword ptr[buffer];
	}
	printf(%x”,result);
	printf("success");
	getchar();
	return 0;
}

对GDT表保持以上修改,则无法取出地址0x8003f008的值,报0xc0000005异常,说明我们权限不够,
用windbg将目标代码段描述符的DPL改为0,进行如下操作
提权操作
再次调试代码
测试
成功读取该地址的值。证明提权成功。

如果在代码中改用jmp 调用,则报0xc0000005异常,原因如下:
调用门权限检查规则
jmp在非一致代码段的权限检查规则为DPL=CPL,说明jmp只能在同权限下进行,无法进行提权操作。

含参调用门

上面提到在调用门段描述符中param Count存放参数个数,下面尝试构造含参调用门,

测试代码
测试2

int result=0;
__declspec (naked)void test2()
{
	_asm
	{
		int 3;
		retf 0x4;
		pushad
		pushfd
		mov eax, dword ptr ss:[esp+0x8+9*4];
		mov result,eax
		popfd
		popad
		retf 0x4
	}
}
int main(int argc, char* argv[])
{
	char buffer[]={0,0,0,0,0x48,0};
    *(int *)buffer=(int)test2;
	printf("%x\n",test2);
	_asm{
        push 0x12345678;
		call fword ptr[buffer];
	}
	printf("%x",result);
	printf("success");
	getchar();
	return 0;
}

观察堆栈堆栈
如果多个参数,则堆栈排布为
多参数堆栈排布
去掉 int 3;
retf 0x4;
后查看测试效果
测试3
成功调用。

结尾

萌新学习记录,如有错误,恳请指正。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值