看流星社区

 找回密码
 注册账号
查看: 2117|回复: 0

解决vista.win7 32/64 session隔离 注入

[复制链接]

该用户从未签到

发表于 2013-4-17 19:48:36 | 显示全部楼层 |阅读模式
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判断语句仍然存在,直接跳走了,估计正式版会放开.
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-30 14:56

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表