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

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(LKernelBase.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判断语句仍然存在,直接跳走了,估计正式版会放开.

该贴由koei转至本版2014-5-2 16:21:43




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