当前位置: 首页 > 图文教程 > 网络安全 > 安全基础 > CLR 中代码访问安全检测实现原理(2)

安全基础
揭开DDoS攻防的神秘面纱
用端口截听实现隐藏嗅探与攻击
教你穿透ADSL路由入侵内网
防范非法用户侵入系统七绝招
警惕黑客4种手段攻击无线局域网
Foxmail账户入侵原理及防范方法
怀疑PC安装木马?学学网络安全小命令
解除安全隐患—让“命令提示符”不再危险
菜鸟必读之邮箱及IE安全技巧全精通
冲浪安全更安全 禁用Cookie功能的几种方法
网上保障隐私十大秘技
顺藤摸瓜 利用IIS日志追查网站入侵者
如何有效防范自己的IP地址泄漏
用Windows自带工具打造“免检”木马
隐藏IP就这么简单
新人快速上手指南 电脑木马查杀大全
触目惊心!小心index.dat泄露你上网痕迹
当心软件泄密 彻底清理应用软件的运行痕迹
网管宝典 终端入侵防护系统七大纪律
巧妙解救被“绑架”的浏览器

安全基础 中的 CLR 中代码访问安全检测实现原理(2)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-28   浏览: 57 ::
收藏到网摘: n/a

  虽然权限种类众多,但各种子类只负责定义自身权限的特性以及如何对自身权限验证,而所有的调用链遍历和验证工作,都是由 CodeAccessPermission.Demand() 方法完成的:

以下内容为程序代码:

public void CodeAccessPermission.Demand()
{
  CodeAccessSecurityEngine engine = SecurityManager.GetCodeAccessSecurityEngine();

  if ((engine != null) && !this.IsSubsetOf(null))
  {
    StackCrawlMark mark = StackCrawlMark.LookForMyCallersCaller;
    engine.Check(this, ref mark);
  }
}

  可以看到 CodeAccessPermission.Demand 方法,实际上是将验证操作转发给安全管理器 SecurityManager 的代码访问安全引擎 CodeAccessSecurityEngine 类型的 Check 方法完成的。

以下内容为程序代码:

internal class CodeAccessSecurityEngine
{
 internal virtual void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark)
 {
  if (!PreCheck(cap, null, 1, ref stackMark, PermissionType.DefaultFlag))
  {
   Check(PermissionToken.GetToken(cap), cap, ref stackMark, -1, ((cap is IUnrestrictedPermission) ? 1 : 0));
  }
 }

 internal virtual void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark, PermissionType permType)
 {
  int num1 = 0;
  if (CodeAccessSecurityEngine.GetResult(permType, out num1))
  {
   return;
  }
  if (this.PreCheck(cap, null, 1, ref stackMark, permType))
  {
   CodeAccessSecurityEngine.SetResult(permType, num1);
   return;
  }
  this.Check(PermissionToken.GetToken(cap), cap, ref stackMark, -1, ((cap is IUnrestrictedPermission) ? 1 : 0));
 }

 [MethodImpl(MethodImplOptions.InternalCall)]
 private void Check(PermissionToken permToken, CodeAccessPermission demand, ref StackCrawlMark stackMark, int checkFrames, int unrestrictedOverride);
}


  CodeAccessSecurityEngine 内部类的 Check 方法,将最终调用通过 Unmanaged 代码实现的内部方法进行安全检测。rotor 中的 COMCodeAccessSecurityEngine 类型 (ComCodeAccessSecurityEngine.cpp) 实现了这个检测逻辑。
  COMCodeAccessSecurityEngine::Check 函数 (ComCodeAccessSecurityEngine.cpp:683) 通过调用 COMCodeAccessSecurityEngine::CheckInternal 函数 (ComCodeAccessSecurityEngine.cpp:697) 填充一个堆栈遍历请求结构 CasCheckWalkData 的内容,最终将请求转发给 StandardCodeAccessCheck 函数 (ComCodeAccessSecurityEngine.cpp:563) 完成检测。此结构的指针将作为堆栈遍历回调函数的参数传递给回调函数进行实际权限验证,而 StandardCodeAccessCheck 只是负责调用全局堆栈遍历支持 StackWalkFunctions 函数(StackWalk.cpp:512),以 CodeAccessCheckStackWalkCB 函数 (ComCodeAccessSecurityEngine.cpp:449) 为回调函数,以 CheckInternal 函数填充的 CasCheckWalkData 结构为参数,通过现成的堆栈遍历支持 Thread::StackWalkFrames 完成堆栈遍历。

  通过堆栈遍历实现代码访问安全检测调用流程如下:

以下为引用:

CodeAccessSecurityEngine::Check 内部调用定义,由下面的函数实现
 COMCodeAccessSecurityEngine::Check 转发检测请求 (ComCodeAccessSecurityEngine.cpp:683)
  COMCodeAccessSecurityEngine::CheckInternal 填充 CasCheckWalkData 结构 (ComCodeAccessSecurityEngine.cpp:697)
   StandardCodeAccessCheck 执行堆栈遍历
    Thread::StackWalkFrames 遍历当前线程堆栈
     CodeAccessCheckStackWalkCB 检测当前组件权限 (ComCodeAccessSecurityEngine.cpp:449)


  因此现在 CAS 检测的问题被分为两个部分:如何遍历调用堆栈;如何检测某个组件是否拥有权限。