关于进程间的访问权限等进程间控制资料收集

http://www.vckbase.com/

DUPLICATEHANDLE函数可以实现将同步内核对象被拷贝并且将原内核对象关闭, 从而达到可以自由控制内核对象的目的, 这可以实现使得只能单一启用的进程成为多启用的进程的目的。

实现方法:

只要用钩子WH_GETMESSAGE挂钩并实现如下代码即可

LRESULT HookProc(int code, WPARAM wParam, LPARAM lParam)    
{   
  STARTUPINFO startUpInfo;
 GetStartupInfo(&startUpInfo);

 char str[MAX_PATH];
 LPSTR lpStr = startUpInfo.lpTitle;
 if (!g_bFounded)
 {
  if (lpStr != NULL)
  {
   _splitpath(lpStr,NULL, NULL, str, NULL);

   DWORD iStrLen = MAX_PATH;
   DWORD dwRegType = 0;
   RegQueryValueExA(HKEY_CURRENT_USER, "PeHook//HookedProcessName", NULL, &dwRegType, (LPBYTE)g_strAppName, &iStrLen);
   if (strcmp(str,/*"wmplayer"*/g_strAppName) == 0)
   {
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    DWORD rl;
    BOOL Result = FALSE;

    //打开进程令牌环
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    //获得进程本地唯一ID
    if (LookupPrivilegeValueA(NULL, "SeDebugPrivilege", &tp.Privileges[0].Luid) )
    {
     tp.PrivilegeCount = 1;
     tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
     //调整权限
     Result = AdjustTokenPrivileges(hToken, false, &tp, sizeof(tp), NULL, &rl);
    }

    if (Result)
    {
     char  buffer[200];
     HANDLE hSrcProc = GetCurrentProcess();
     DWORD dwError = GetLastError();
     HANDLE hSrcHandle = (HANDLE)0x38;
     HANDLE hCurProc= GetCurrentProcess();
     HANDLE hTargetHandle = 0;
     BOOL bRet = DuplicateHandle(hSrcProc, hSrcHandle, hCurProc, &hTargetHandle, DUPLICATE_SAME_ACCESS, FALSE, DUPLICATE_CLOSE_SOURCE);
     
     if (bRet)
     {
      CloseHandle(hTargetHandle);
      g_bFounded = TRUE;
     }

}

}
 return CallNextHookEx(glhHook,code,wParam,lParam);
}
/

资料:

CSDN: http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece76310408a23450add306ac0d0622e95c51484642c1d1020fefa7a65505584d87f6001ad4356e8e4732f77552fa0edca9f3caaace22238f92123716c913164c46da5dc3624d651e14de8df0e97bfe74392b9a3a4c82520dd52756df1fa9c290a03bb1be76246&p=8e6ed55f86cc4bf30be2943848&user=baidu

CSDN:  http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c4224627003ab8f12422141980852d3d5aeb1e41eaf234762a0022aa98cb9549dcba902f2b8e3034074fc70358c75cf28b102a9660d007a9b81897adf74684afa2808e05048b12127bf0e78c2e1715ba39a7486ab4f08e48640252edb17225a2082068de&p=c933891985cc44f508e2937c505d&user=baidu

 

简单算法遍历PspCidTable句柄表

ULONG GetPspCidTable()
{
  ULONG PspCidTable=0;
  ULONG FuncAddr=NULL;
  UNICODE_STRING FuncName={0};
  
  RtlInitUnicodeString(&FuncName,L"PsLookupProcessByProcessId");
  FuncAddr=(ULONG)MmGetSystemRoutineAddress(&FuncName);
  for (;;FuncAddr++)
  {
    if ((0x35ff==(*(PUSHORT)FuncAddr)) && (0xe8==(*(PUCHAR)(FuncAddr+6))))
    {  
      PspCidTable=*(PULONG)(FuncAddr+2);
      break;
    }  
    
  }
  return PspCidTable;
}

#define OBJECT_BODY_TO_TYPE 0x10
//从3级表开始遍历
ULONG BrowseTableL3(ULONG TableAddr)
{
  ULONG Object=0;
  ULONG ItemCount=511;

  do 
  {
    TableAddr+=8;
    Object=*(PULONG)TableAddr;
    Object&=0xfffffff8;
    
    if (Object==0)
    {
      continue;
    }
    if ((*PsProcessType)==(*(PULONG)(Object-OBJECT_BODY_TO_TYPE)))
    {
      KdPrint(("%s",PsGetProcessImageFileName((PEPROCESS)Object)));
    }    
  } while (--ItemCount>0);
  
  return 0;
}

//从二级表开始遍历
ULONG BrowseTableL2(ULONG TableAddr)
{
  do 
  {
    BrowseTableL3(*(PULONG)TableAddr);
    TableAddr+=4;
  } while ((*(PULONG)TableAddr)!=0);

  return 0;
}

//从1级表开始遍历
ULONG BrowseTableL1(ULONG TableAddr)
{
  do 
  {
    BrowseTableL2(*(PULONG)TableAddr);
    TableAddr+=4;
  } while ((*(PULONG)TableAddr)!=0);

  return 0;
}

VOID RefreshProcessByPspCidTable()
{
  ULONG PspCidTable=0;
  ULONG HandleTable=0;
  ULONG TableCode=0;
  ULONG flag=0;

  PspCidTable=GetPspCidTable();
  HandleTable=*(PULONG)PspCidTable;
  TableCode=*(PULONG)HandleTable;
  flag=TableCode&3;
  TableCode&=0xfffffffc;  
  
  switch (flag)
  {
  case 0:
    BrowseTableL3(TableCode);
    break;
  case 1:
    BrowseTableL2(TableCode);
    break;
  case 2:
    BrowseTableL1(TableCode);
    break;    
  }
  
  
}

劫持内核句柄

2009-06-17 10:42:42  www.hackbase.com  来源: 看雪
  Sysnap 2009,6  为什么需要 句柄?   句柄只是对对像的引用,当我们进入 内核时,获取 对象显然是很简单,但为什么还需要 句柄  呢? 应该说我们需要 句柄做为参数调用API. 因为直接操作 对象,可能会涉及到许多的 ...
  Sysnap 2009,6
  为什么需要 句柄?
   句柄只是对对像的引用,当我们进入 内核时,获取 对象显然是很简单,但为什么还需要 句柄
  呢? 应该说我们需要 句柄做为参数调用API. 因为直接操作 对象,可能会涉及到许多的未导
  出的东西,如果自己实现的话是不大现实,而调用标准的 内核API又很多时候依赖于 句柄,但
  又很多时候因为种种原因,我们得不到 句柄,这里我们将探讨下怎样获取一个有用的 句柄.
  任何问题欢迎指正: http://hi.baidu.com/sysnap/blog
  1 句柄的创建
  ObpCreateHandle 这个函数会判断AccessMode,如果是用户态的,那PVOID ObjectTable;
  ObjectTable = PsGetCurrentProcess()->ObjectTable
  如果是在驱动中打开 句柄,则ObjectTable = ObpKernelHandleTable;
  ObpKernelHandleTable是一个指向HANDLE_TABLE的指针,在系统中并没有导出
  接着便会ATTACH 到SYSTEM进程..
  调用ObpIncrementHandleCount增添Object引用数,这个地方我们慢点再考虑有没必要做一
  些工作.
  调用ExCreateHandle 创建 句柄,ExCreateHandle中调用
   分配一个HANDLE_TABLE_ENTRY和一个 句柄,这个 句柄的值的产生是在
  ///ExpAllocateHandleTableEntry中完成的.
  ExpAllocateHandleTableEntry 是 句柄分配的核心,也涉及到了相关的数据结构.但这里我
  们可以不用管它.
  我们只需要知道ObpCreateHandle会给我们返回一和 句柄,并且会在ObjectTable新添加一
  个HANDLE_TABLE_ENTRY
  lkd> dt _HANDLE_TABLE_ENTRY
  nt!_HANDLE_TABLE_ENTRY
  +0x000 Object           : Ptr32 Void
  HANDLE_TABLE_ENTRY 就包含有我们的Object了.
  2 句柄到OBJECT的映射
  这里涉及到了 句柄表的格式,关于 句柄表,网上已经有相关的文章讨论了,这里将不再说
  typedef struct _EXHANDLE
  {
  union
  {
  struct
  {
  ULONG TagBits : 02;
  ULONG Index   : 30;
  };
  HANDLE GenericHandleOverlay;
  };
  } EXHANDLE, *PEXHANDLE;
  可以看出,一个类型为HANDLE的,其实分为俩部分,TagBits和Index,具体干什么,请看下面
  的函数
  PHANDLE_TABLE_ENTRY
  LookupHandleTableEntry(
  IN PXP_HANDLE_TABLE HandleTable,
  IN EXHANDLE         Handle
  )
  {
  ULONG i, j, k;
  PHANDLE_TABLE_ENTRY Entry = NULL;
  ULONG TableCode = HandleTable->TableCode& ~TABLE_LEVEL_MASK;
  i = (Handle.Index >> 17) &0x1FF;
  j = (Handle.Index >> 9)  &0x1FF;
  k = (Handle.Index)       &0x1FF;
  switch (HandleTable->TableCode &TABLE_LEVEL_MASK)
  {
  case 0 :
  Entry = &((PHANDLE_TABLE_ENTRY)TableCode)[k];
  break;
  case 1 :
  if (((PVOID *)TableCode)[j])
  {
  Entry = &((PHANDLE_TABLE_ENTRY *)TableCode)[j][k];
  }
  break;
  case 2 :
  if (((PVOID *)TableCode)[i])
  if (((PVOID **)TableCode)[i][j])
  {
  Entry = &((PHANDLE_TABLE_ENTRY **)TableCode)[i][j][k];
  }
  break;
  }
  return Entry;
  }
  这样的话我们就可以根据HANDLE..获取到HANDLE_TABLE_ENTRY从而得到Object
  上面的函数只适合XP和2003
  3 句柄的权限
  如果我们想修改某个 句柄的权限,可以通过HANDLE_TABLE_ENTRY::GrantedAccess
  4ObOpenObjectByPointer
  ObReferenceObjectByPointer添加计数
  ObpCreateHandle 句柄的创建
  5怎样伪造.
  比如我们想伪造一个XX.EXE进程的 句柄.
  1首先我们需要确定 ObpKernelHandleTable
  DWORD dwObpKernelHandleTable = 0;
  PVOID lpPsSystemObject = (PVOID)PsGetCurrentProcess();
  dwObpKernelHandleTable = *(DWORD*)((DWORD)lpPsSystemObject +
  gdwObjectTableOffset);
  2 ObOpenObjectByPointer 打开explorer.exe (这里随便找个没保护的进程就可以)
  获取 句柄 hProcess
  3 用某些办法获取XX.EXE 的进程 对象EPROCESS
  4 用hProcess为参数调用,LookupHandleTableEntry得到一个指向PHANDLE_TABLE_ENTRY的
  指针pEntry
  这个时候pEntry->Object应该就是 explorer.exe的EPRCESS
  5 修改pEntry->Object = XX.EXE的EPROCESS
  这样我们就完成了HANDLE和OBJECT的劫持..
  这都是主要步骤,其中有些细节问题需要注意,比如增加 对象句柄数啊等等.
  6 有效果吗?
  我们知道大部分 内核API都会以一个HANDLE做为参数的,其内部基本都是调用了
  ObReferenceObjectByHandle来定位 对象,我们分析下ObReferenceObjectByHandle就知道
  我们的劫持是否有用了.
  很显然ObReferenceObjectByHandle是根据 HANDLE_TABLE来把 句柄转化为 对象,过程简单
  为 handle--->> pEntry->Object
  所以劫持是成功的.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值