好吧,我终于设法让一个程序爆炸,这是继承请求失败的直接原因。
您需要一个包含三个项目的vs解决方案。
首先是基本类:
using System;
using System.IO;
using System.Security;
using System.Security.Permissions;
namespace BaseClass
{
public abstract class IniPrinterBase
{
[FileIOPermission(SecurityAction.Deny, AllFiles = FileIOPermissionAccess.Read)]
//[RegistryPermission(SecurityAction.InheritanceDemand,Unrestricted = true)]
public virtual void PrintIniFile()
{
ProtectedPrint();
}
protected void ProtectedPrint()
{
try
{
var lines = File.ReadAllLines(@"G:\test.ini");
foreach (var line in lines)
{
Console.WriteLine(line);
}
}
catch (SecurityException e)
{
Console.WriteLine("PRINT OF INI FILE FAILED!");
Console.WriteLine(e.Message);
}
}
}
}
然后是另一个项目中的派生类:
using System.Security.Permissions;
using BaseClass;
[assembly:RegistryPermission(SecurityAction.RequestRefuse,Unrestricted = true)]
namespace DerivedClasses
{
public class FileIOPermissionExceptionThrower : IniPrinterBase
{
public override void PrintIniFile()
{
base.PrintIniFile();
}
}
public class InheritanceDemandExceptionThrower : IniPrinterBase
{
public override void PrintIniFile()
{
ProtectedPrint();
}
}
}
最后是第三个项目的主要项目:
using System;
using DerivedClasses;
namespace MethodSecuritySpike
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Printing ini file from security enforced method:");
var printer1 = new FileIOPermissionExceptionThrower();
printer1.PrintIniFile();
Console.WriteLine();
Console.WriteLine("Bypassing security:");
var printer2 = new InheritanceDemandExceptionThrower();
printer2.PrintIniFile();
Console.ReadLine();
}
}
}
要使示例工作,必须引用派生类程序集中的基类程序集,以及方法SecuritySpike程序集中的基类程序集和派生类程序集。
此外,在C:\根目录以外的任何其他位置创建一个适当的test.ini文件(否则,Windows安全可能会对您起作用)。
运行程序(methodsecurityspike.exe)。您将首先看到在尝试读取ini文件时捕获到异常,然后仍然显示ini文件的内容。
接下来,删除基类命名空间中RegistryPermissionAttribute之前的注释斜杠。运行程序:它完全拒绝运行!
属性说明:
Baseclass:
[文件IOPermission(securityAction.deny,allfiles=fileIOPermissionAccess.read)]
调用printinifile时将导致异常
在基类中
(模拟代码访问安全性试图阻止访问ini文件的情况)
InheritanceDemandExceptionThrower类通过重写printinifile方法并直接调用ProtectedPrint方法来绕过此安全声明。(模拟安全漏洞)
[注册表类型终止(securityAction.inheritanceDemand,unrestricted=true)]
继承自iniprinterbase的类具有上述权限的条件(由于需要高信任级别而随意选择)
由于DerivedClasses.dll被明确拒绝此权限,因此当取消对该属性的注释时,程序将无法运行。
在派生类中:
[程序集:RegistryPermission(SecurityAction.RequestReject,Unrestricted=true)]
指定应拒绝对注册表访问的请求(模拟部分信任环境)。通常,这不会引发异常,因为derivedclasses.dll中的类不访问注册表。
但是,当InheritanceDemand处于活动状态时,derivedclasses.dll需要RegistryPermission能够实例化它的两个类并爆炸。
容易的!;-)