解决vista.win7 32/64 session隔离 注入_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 4696 | 回复: 0   主题: 解决vista.win7 32/64 session隔离 注入        下一篇 
jfl
注册用户
等级:少校
经验:1112
发帖:95
精华:0
注册:2012-8-10
状态:离线
发送短消息息给jfl 加好友    发送短消息息给jfl 发消息
发表于: IP:您无权察看 2012-8-29 15:06:48 | [全部帖] [楼主帖] 楼主

vista/7 以后的系统都存在session隔离,

CreateRemoteThread的流程
vista下 Kernel32!CreateRemoteThread
win7下 Kernel32!CreateRemoteThread->..一些中转..->KernelBase->CreateRemoteThreadEx

在vista/7上,kernel32/或者KernelBase里存在一个全局变量BaseRunningInServerProcess
在进程创建的时候就被初始化了,表示本进程是否是一个服务进程,服务的session是0

由CreateRemoteThread流程的最尾端的函数处理了这个标志,发现不是从服务进程发起的调用,就跳转了,

由于这个判断是在应用层而且是本进程做的,所以很没有意义,可以直接修改.

一般的修改办法是修改判断跳转,其实在某些条件下比如win7/32/64可以更简单的方式绕过.

原理是一样的,只是vista下没有导出这个全局变量,不好定位,只想到用特征码搜索的方式.

但在win7下就方便多了,由于kernelBase!KernelBaseGlobalData 导出,所以直接调用这个函数就可以获得这个全局结构体的地址,\
虽然这个结构体没有文档,但是加上一个偏移就是我们要的标志.

kernelBase!KernelBaseGlobalData的函数原形

typedef void* (__stdcall *LPFN_KernelBaseGetGlobalData)(void);


win7 32下 BaseRunningInServerProcess 位于 KERNELBASE!KernelBaseGlobalData+0x30
win7 64 下, BaseRunningInServerProcess 位于 KERNELBASE!KernelBaseGlobalData+0x5c

原理说完了,贴段可以自适应的代码.

代码:

//创建远程线程,处理session隔离
//xSpy 2012.07.26
//xp ~ 7 /x86 ~ x64 自适应

typedef void* (__stdcall *LPFN_KernelBaseGetGlobalData)(void);

HANDLE LibCreateRemoteThread
(
 __in HANDLE hProcess, 
 __in LPTHREAD_START_ROUTINE lpStartAddress,
 __in_opt LPVOID lpParameter, 
 __in DWORD dwCreationFlags,
 __out_opt LPDWORD lpThreadId
)

 OSVERSIONINFOEX stOSVersionInfoEx={0};
       LPFN_CreateRemoteThreadEx pCreateRemoteThreadEx=NULL;
       LPFN_KernelBaseGetGlobalData pKernelBaseGetGlobalData=NULL;
       UCHAR* pCreateRemoteThread=NULL;
       UCHAR* pGlobalData=NULL;
       UCHAR* pMisc=NULL;
       HMODULE hKernelBase=NULL;
       HMODULE hKernel32=NULL;
       HANDLE hNewThread=NULL;
       ULONG ulIndex=0;
       WORD wCode=0;

       do 
       {
             stOSVersionInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
             if (!GetVersionEx((OSVERSIONINFO*)&stOSVersionInfoEx))
             {
                   break;
             }

             //vista以前的系统不存在这个问题
             if ( (stOSVersionInfoEx.dwMajorVersion < 6) || (NtCurrentProcess() == hProcess) )
             {
                   hNewThread = CreateRemoteThread(hProcess,NULL,0,lpStartAddress,lpParameter,dwCreationFlags,lpThreadId);
                   break;
             }

             if ( (stOSVersionInfoEx.dwMajorVersion == 6) && (0 == stOSVersionInfoEx.dwMinorVersion) )
             {
                   //vista
                   hKernel32 = LoadLibraryA("Kernel32.dll");
                   pCreateRemoteThread = (UCHAR*)GetProcAddress(hKernel32,"CreateRemoteThread");

                   for (ulIndex=0; ulIndex < 0x300;ulIndex += 1)
                   {
                         wCode = *((USHORT*)(pCreateRemoteThread + ulIndex));

                         #ifdef _WIN64
                         if (0x3D80 == wCode )
                         {
                               pMisc = (*((ULONG*)(pCreateRemoteThread + ulIndex + 2))) + (pCreateRemoteThread + ulIndex + 7);
                               break;
                         }
                         #else
                         if (0x1D38 == wCode )
                         {
                               pMisc = (UCHAR*)(*((ULONG*)(pCreateRemoteThread + ulIndex + 2)));
                               break;
                         }
                         #endif
                   }
             }
             else if ( (stOSVersionInfoEx.dwMajorVersion == 6) && (1 == stOSVersionInfoEx.dwMinorVersion) )
             {
                   //win7
                   hKernelBase = LoadLibraryW(L"KernelBase.dll");
                   if (NULL == hKernelBase)
                   {
                         break;
                   }
                   pKernelBaseGetGlobalData = (LPFN_KernelBaseGetGlobalData)GetProcAddress(hKernelBase,"KernelBaseGetGlobalData");
                   if (NULL == pKernelBaseGetGlobalData)
                   {
                         break;
                   }

                   pGlobalData = (UCHAR*)pKernelBaseGetGlobalData();
                   if (NULL == pGlobalData)
                   {
                         break;
                   }

                   #ifdef _WIN64
                   pMisc = pGlobalData + 0x5C;
                   #else
                   pMisc = pGlobalData + 0x30;
                   #endif
             }
             else
             {
                   //手上的win8 Build 8250 没有session 隔离
             }

             //////////////////////////////////////////////////////////////////////////
             if (NULL == pMisc)
             {
                   break;
             }

             //Patch
             *pMisc = 1;

             //xx
             hNewThread = CreateRemoteThread(hProcess,NULL,0,lpStartAddress,lpParameter,dwCreationFlags,lpThreadId);

             //UnPatch
             *pMisc = 0;

       } while (FALSE);

       if (NULL != hKernelBase)
       {
             FreeLibrary(hKernelBase);
             hKernelBase = NULL;
       }

       return hNewThread;
}

在vista 32/64 win7 32/64 下测试通过.

手上的win8 Build 8250 因为是测试版的原因,没有session 隔离,可以任意注入.
但是session判断语句仍然存在,直接跳走了,估计正式版会放开.




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论