首页
社区
课程
招聘
[原创]借鉴CVE-2017-0213思路,挖掘到另外一种方法成功获取到System的Token,新的0day
发表于: 2018-3-16 19:01 5478

[原创]借鉴CVE-2017-0213思路,挖掘到另外一种方法成功获取到System的Token,新的0day

王cb 活跃值
11
2018-3-16 19:01
5478

我讲一下我的实现思路, 在打满所有补丁的server2008或win7下情况下IBackgroundCopyJob->SetNotifyInterface根据CVE-2017-0213的原理会加载一个指定com组件的typelib(以sysytem权限),可以指定任意typlelib然后bits服务调用loadregtypelib这个ole32下函数,然后loadregtypelib会把com组件的typelib中指定的文件名作为一个filemoniker解析(调用),因为文件被锁定了(见使用方法),所以它loadregtypelib调用mkpaersedisplayname来createfilemoniker失败,同时我在poc中实现了一个和这个filemoniker相同displaynmame的moniker并在Running Object Table注册一个自定义的typelib,所以mkpaersedisplayname失败后会把在Running Object Table注册的moniker指定的typlelib对象(可以是任意对象)作为filemoniker应该调用bindtoobject返回的对象(也就是替换),然后bits服务会调用这个指定的typlelib对象上的一些方法,这个时候在我的typlelib上调用coimpersonateclient返回的token就是system的,和截图一样,但是这个token模拟级别是SecurityIdentification类型的无法创建新进程无法操作文件(返回1346错误),另外说一点,我分析到是,通过修改注册表中typelib对于的文件名路径,如果bits服务调用loadregtypelib对应typelib指定的文件名是一个scrptletmoniker是可以直接启动一个system的cmd.exe,问题是注册表非管理员无法修改,这个只是验证说明调用方确实是system的bits服务,暂时得出的结论是如果bits服务调用loadregtypelib返回的scrptletmoniker是在他自己本身内部实现的所以启动cmd.exe是可行的,

,我认识到了SecurityIdentification模拟等级的token利用的相关知识,另外一种利用方式是在调用方发起一个导致代码执行的反序列化,我通过逆向ole32的代码发现确实有类似回调对象的东西,有关微软官方文档https://msdn.microsoft.com/en-us/library/windows/desktop/ms686628(v=vs.85).aspx其中说到If riid is set to IID_IEnterActivityWithNoLock, the function is executed without an activity lock.是否意味着只要是unmarshal 的objref中可以序列还出来这种类型iid的回调就可以绕过com代理不同套间(apartment)的限制,以下我是逆向ole32的结果,不知道是否有可行性:

HRESULT __stdcall UnmarshalObjRef(tagOBJREF *objref, void **ppv, int fBypassActLock, CStdMarshal **ppStdMarshal)

{

  HRESULT v4; // eax

  CObjectContext *v5; // eax

  tagOBJREF *v7; // edi

  HRESULT v8; // esi

  CStdMarshal *v9; // esi

  CStdIdentity *v10; // eax

  void **v11; // edi

  tagStdUnmarshalData StdData; // [esp+Ch] [ebp-1Ch]

  int fLightNAProxy; // [esp+24h] [ebp-4h]

  v7 = objref;

  fLightNAProxy = CrossAptRefToNA(objref);

  v8 = FindStdMarshal(v7, 0, (CStdMarshal **)&objref, fLightNAProxy);

  if ( v8 < 0 )

  {

    if ( v7->u_objref.u_standard.std.cPublicRefs )

      ReleaseMarshalObjRef(v7);

  }

  else

  {

    v9 = (CStdMarshal *)objref;

    v10 = *(CStdIdentity **)objref->iid.Data4;

    StdData.pobjref = v7;

    v11 = ppv;

    StdData.pStdID = v10;

    StdData.ppv = ppv;

    StdData.pClientCtx = GetCurrentContext();

    if ( ppStdMarshal )

    {

      *ppStdMarshal = v9;

      v9->vfptr->AddRef((IUnknown *)&v9->vfptr);

    }

    v5 = CStdMarshal::ServerObjectCallable(v9);

    if ( v5 )

    {

      StdData.fCreateWrapper = v11 != 0;

      if ( fBypassActLock )

        v4 = PerformCallback(v5, UnmarshalSwitch, &StdData, &IID_IEnterActivityWithNoLock, 2u, 0);

      else

        v4 = PerformCallback(v5, UnmarshalSwitch, &StdData, &IID_IMarshal, 6u, 0);

    }

    else

    {

      StdData.fCreateWrapper = fLightNAProxy;

      v4 = UnmarshalSwitch(&StdData);

    }

    v8 = v4;

  }

  return v8;

}

这个有一个fBypassActLock是安全主体的构造验证

UnmarshalSwitch是可以序列化出来的回掉函数

具体序列还方式 是:

HRESULT __stdcall UnmarshalSwitch(void *pv)

{

  void **v1; // eax

  int v2; // edi


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2018-3-29 13:33 被王cb编辑 ,原因:
上传的附件:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//