背景
之前发布过一篇关于procexp的利用,但是最近有brother说,最新的版本不能利用了,然后就去下载了最新版本的。
发现判断了是不是受保护进程,不是就拒绝。
这里简单看一下这个函数,发现对比的是_PS_PROTECTION,其实就是Windows Vista之后引进的ppl保护机制,对应的msdn。
PsIsProtectedProcess proc near test byte ptr [rcx+87Ah], 7mov eax, 0setnbe alretnPsIsProtectedProcess endptypedef enum _PS_PROTECTED_TYPE {PsProtectedTypeNone = 0,PsProtectedTypeProtectedLight = 1,PsProtectedTypeProtected = 2
} PS_PROTECTED_TYPE, *PPS_PROTECTED_TYPE;
好了,现在想办法怎么让过。
1、找能够清零PsIsProtectedProcess_180005238全局变量的漏洞;
2、找能利用的ppl进程;
上面两个都找了,第一种找了几个驱动,没找到能够控制传入参数赋值为0的,第二个创建的ppl(CREATE_PROTECTED_PROCESS)的父进程的句柄也是没有修改的权限的。
利用
由于之前分析过某个驱动,于是找到了某个不愿意透露姓名的驱动,能够打开进程(xxx-base),但是没有复制进程句柄和写内存的接口(只有读)。
然后顺利打开system,和其他进程并且是操作进程的所有权限,起初是想以system句柄创建一个ppl进程的傀儡进程,但是呢,父进程只有受限制的查询权限(可以再次内核打开这不是问题),最主要的是没有主线程的权限,灰色代表的是挂起。
ULONG createProc(ULONG dupHandle)
{ULONG pid = NULL;STARTUPINFOEX si;PROCESS_INFORMATION pi;RtlSecureZeroMemory(&pi, sizeof(pi));RtlSecureZeroMemory(&si, sizeof(si));SIZE_T size = 0x30;si.StartupInfo.cb = sizeof(STARTUPINFOEX);si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)malloc(0x30);if (si.lpAttributeList) {if (InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size)) {if (UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &dupHandle, sizeof(HANDLE), 0, 0)) {if (CreateProcess("C:\\Windows\\System32\\svchost.exe",NULL,NULL,NULL,FALSE,CREATE_PROTECTED_PROCESS| CREATE_SUSPENDED | EXTENDED_STARTUPINFO_PRESENT,NULL,NULL,&si,&pi)){pid = pi.dwProcessId;//CloseHandle(pi.hThread);//CloseHandle(pi.hProcess);PROCESS_INFORMATION ProcessInfomation = { 0 };CONTEXT Context = { 0 };Context.ContextFlags = CONTEXT_ALL;if (!GetThreadContext(pi.hThread, &Context)){printf("GetThreadContext fail LastError:%d\n", GetLastError());}else{printf("Context.Eax 0x%x", Context.Eax);}}else {printf("create failed GetLastError %d\n", GetLastError());}}else {printf("UpdateProcThreadAttribute failed\n");}}}if (si.lpAttributeList)DeleteProcThreadAttributeList(si.lpAttributeList); //dumb empty routinefree(si.lpAttributeList);return pid;
}
后来测试ZwCreateThreadEx也会失败,毕竟创建线程会走回调,失败也很正常0xc0000022(STATUS_ACCESS_DENIED),但是VirtualAllocEx和VirtualProtectEx可以正常使用,只需要劫持NtContinue就可以了(这个函数调用和频繁,劫持写个shellcode注入dll应该不难吧。我没写---有懒人)。
真正的问题
看下当前受保护的进程,我选择MsMpEng.exe,打开之后,申请内存发现失败了。
接着对比了smss和MsMpEng的acg保护,发现有点不一样,左smss。
MsMpEng没有动态代码保护,但多了dll和extension pointer保护,于是写点代码把这两个保护给自己加上
PROCESS_MITIGATION_IMAGE_LOAD_POLICY policy;ZeroMemory(&policy, sizeof(policy));policy.NoRemoteImages = 1;SetProcessMitigationPolicy(ProcessImageLoadPolicy, &policy, sizeof(policy))PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy2;ZeroMemory(&policy, sizeof(policy2));policy2.DisableExtensionPoints = 1;SetProcessMitigationPolicy(ProcessExtensionPointDisablePolicy, &policy2, sizeof(policy2))
开测,一样成功申请到了内存。
屮
那只有动态调试一下了,对指定进程的NtAllocateVirtualMemory下断电,发现在MiAllocateVirtualMemoryPrepare返回了STATUS_ACCESS_DENIED,进去之后在看看ObpReferenceObjectByHandleWithTag返回了STATUS_ACCESS_DENIED,此时感觉到莫名其妙,ObpReferenceObjectByHandleWithTag怎么会拒绝呢,于是打印了下对应的句柄
屮,权限不足,原来最开始打开的权限就是受限制的,因为打开system和smss(ppl进程)成功就没有注意看句柄权限了,这里的MsMpEng权限还是受限制的(应该是在ob回调中限制了打开windows防火墙进程的权限)。
啰嗦一下如果要劫持ppl进程的NtContinue,还是需要注意一下acg保护。