I am currently creating a Sandbox Tool in WinForms to restrict access to certain permissions like FileIOPermission etc.. I have implemented what I think should work, but when running the Sandbox tool it does not produce any errors, it just opens the program without any exception errors which I am expecting!
I have included all Classes and code as this has me totally lost and any help / pointers would be greatly received!
Class Form1:
namespace SandboxACW
{
public partial class Form1 : Form
{
List<String> listofDrives = new List<String>();
List<String> listofPermissions = new List<String>();
Sandbox sandbox = new Sandbox();
Permissions permissions = new Permissions();
private string pathToUntrusted;
string[] allPermissions;
List<String> CommandAgrs = new List<String>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
driverLoad();
permissionLoad();
}
public void driverLoad() {
foreach (var Drives in Environment.GetLogicalDrives())
{
DriveInfo DriveInf = new DriveInfo(Drives);
if (DriveInf.IsReady == true)
{
clstboxDrives.Items.Add(DriveInf.Name);
}
}
}
public void GetArguments()
{
foreach (var arg in txtBoxArguments.Text.Split(new string[] {"\r\n","\n"}, StringSplitOptions.None))
{
CommandAgrs.Add(arg);
}
}
public void RestrictDrive()
{
PermissionSet permSet = new PermissionSet(PermissionState.None);
if(listofDrives.Count != 0){
foreach(string SelectedDrive in listofDrives){
permSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.NoAccess, SelectedDrive));
}
}
}
public void permissionLoad() {
var interfaceType = typeof(IPermission);
allPermissions = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(x => interfaceType.IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract && x.Name != "PrincipalPermission" && x.Name != "SiteIdentityPermission" && x.Name != "StrongNameIdentityPermission"
&& x.Name != "UrlIdentityPermission" && x.Name != "ZoneIdentityPermission" && x.Name != "GacIdentityPermission" && x.Name != "PublisherIdentityPermission" && x.Name != "SqlClientPermission"
&& x.Name != "OleDbPermission" && x.Name != "OdbcPermission" && x.Name != "HostProtectionPermission")
.Select(x => x.Name).ToArray();
clstboxPermission.Items.AddRange(allPermissions);
}
private void clstboxDrives_SelectedIndexChanged(object sender, ItemCheckEventArgs e)
{
if (e.NewValue == CheckState.Checked)
{
listofDrives.Add(clstboxDrives.Items[clstboxDrives.SelectedIndex].ToString());
}
if (e.NewValue == CheckState.Unchecked)
{
listofDrives.Remove(clstboxDrives.Items[clstboxDrives.SelectedIndex].ToString());
}
RestrictDrive();
}
private void clstboxPermission_SelectedIndexChanged(object sender, ItemCheckEventArgs e)
{
if (e.NewValue == CheckState.Checked)
{
listofPermissions.Add(clstboxPermission.Items[clstboxPermission.SelectedIndex].ToString());
}
if (e.NewValue == CheckState.Unchecked)
{
listofPermissions.Remove(clstboxPermission.Items[clstboxPermission.SelectedIndex].ToString());
}
}
private void btnOpen_Click(object sender, EventArgs e)
{
OpenFileDialog open = new OpenFileDialog();
try
{
open.Filter = "exe files (*.exe)|*.exe|All files (*.*)|*.*";
if (open.ShowDialog(this) == DialogResult.OK)
{
txtboxFilepath.Text = open.FileName;
pathToUntrusted = open.FileName;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Form1", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnRun_Click(object sender, EventArgs e)
{
if (pathToUntrusted != null){
GetArguments();
sandbox.SetupDomain(pathToUntrusted, listofDrives, listofPermissions);
}
else
{
MessageBox.Show("Please enter an .EXE file to be tested!","Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
}
}
}
Class Sandbox:
namespace SandboxACW
{
public class Sandbox : MarshalByRefObject
{
public void SetupDomain(string pathToUntrusted, List<String> listofDrives, List<String> listofPermissions, params string [] Commandargs)
{
try
{
Object[] Parameters = { Commandargs };
string untrustedClass = "";
//PermissionSet ps = new PermissionSet(PermissionState.None);
int index = pathToUntrusted.LastIndexOf('\\');
//Setting the permissions for the AppDomain. We give the permission to execute and to
//read/discover the location where the untrusted code is loaded.
PermissionSet permSet = Permissions.SetupPermissions(listofPermissions);
if (listofDrives.Count != 0)
{
foreach (var drive in listofDrives)
{
permSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.NoAccess, drive));
}
}
//Setting the AppDomainSetup. It is very important to set the ApplicationBase to a folder
//other than the one in which the sandboxer resides.
AppDomainSetup adSetup = new AppDomainSetup();
adSetup.ApplicationBase = Path.GetFullPath( pathToUntrusted.Substring(0, index));
//We want the sandboxer assembly's strong name, so that we can add it to the full trust list.
StrongName fullTrustAssembly = typeof(Sandbox).Assembly.Evidence.GetHostEvidence<StrongName>();
//Now we have everything we need to create the AppDomain, so let's create it.
AppDomain newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly);
AssemblyName selectedFilesAssemblyName = AssemblyName.GetAssemblyName(pathToUntrusted);
string untrustedAssembly = selectedFilesAssemblyName.Name;
Assembly selectedFileAssembly = Assembly.LoadFrom(pathToUntrusted);
// needs fixing to GetTypes() array out of bounds!
foreach (Type type in selectedFileAssembly.GetTypes()) {
untrustedClass = type.FullName;
}
// Type type = selectedFileAssembly.GetTypes()[2];
string entryPoint = selectedFileAssembly.EntryPoint.Name;
//Use CreateInstanceFrom to load an instance of the Sandboxer class into the
//new AppDomain.
ObjectHandle handle = Activator.CreateInstanceFrom(
newDomain, typeof(Sandbox).Assembly.ManifestModule.FullyQualifiedName,
typeof(Sandbox).FullName
);
//Unwrap the new domain instance into a reference in this domain and use it to execute the
//untrusted code.
Sandbox newDomainInstance = (Sandbox)handle.Unwrap();
newDomainInstance.ExecuteUntrustedCode(untrustedAssembly, untrustedClass, entryPoint, Parameters);
}
catch (Exception exp)
{
MessageBox.Show(exp.Message, "Sandboxer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void ExecuteUntrustedCode(string assemblyName, string typeName, string entrypoint, object[] parameters)
{
//Load the MethodInfo for a method in the new Assembly. This might be a method you know, or
//you can use Assembly.EntryPoint to get to the main function in an executable.
MethodInfo target = Assembly.Load(assemblyName).EntryPoint;
//MethodInfo target = Assembly.Load(assemblyName).GetType(typeName).GetMethod(entrypoint);
try
{
//Now invoke the method.
//bool retVal = (bool)target.Invoke(null, new object[] {parameters});
target.Invoke(null, null);
}
catch (Exception ex)
{
// When we print informations from a SecurityException extra information can be printed if we are
//calling it with a full-trust stack.
(new PermissionSet(PermissionState.Unrestricted)).Assert();
MessageBox.Show(ex.Message, "Sandboxer", MessageBoxButtons.OK, MessageBoxIcon.Error);
//Console.WriteLine("SecurityException caught:\n{0}", ex.ToString());
CodeAccessPermission.RevertAssert();
//Console.ReadLine();
}
}
}
}
Class Permissions:
namespace SandboxACW
{
public class Permissions
{
public string[] selectedItem;
public static PermissionSet SetupPermissions(List<string> checkedPermission)
{
PermissionSet permSet = new PermissionSet(PermissionState.Unrestricted);
try
{
foreach (var test in checkedPermission)
{
switch (test)
{
case "EnvironmentPermission":
permSet.AddPermission(new EnvironmentPermission(PermissionState.None));
break;
case "FileDialogPermission":
permSet.AddPermission(new FileDialogPermission(PermissionState.None));
break;
case "FileIOPermission":
permSet.AddPermission(new FileIOPermission(PermissionState.None));
break;
case "IsolatedStorageFilePermission":
permSet.AddPermission(new IsolatedStorageFilePermission(PermissionState.None));
break;
case "ReflectionPermission":
permSet.AddPermission(new ReflectionPermission(PermissionState.None));
break;
case "SecurityPermission":
permSet.AddPermission(new SecurityPermission(PermissionState.None));
break;
case "UIPermission":
permSet.AddPermission(new UIPermission(PermissionState.None));
break;
case "KeyContainerPermission":
permSet.AddPermission(new KeyContainerPermission(PermissionState.None));
break;
case "RegistryPermission":
permSet.AddPermission(new RegistryPermission(PermissionState.None));
break;
case "AspNetHostingPermission":
permSet.AddPermission(new AspNetHostingPermission(PermissionState.None));
break;
case "DnsPermission":
permSet.AddPermission(new DnsPermission(PermissionState.None));
break;
case "SocketPermission":
permSet.AddPermission(new SocketPermission(PermissionState.None));
break;
case "WebPermission":
permSet.AddPermission(new WebPermission(PermissionState.None));
break;
case "SmtpPermission":
permSet.AddPermission(new SmtpPermission(PermissionState.None));
break;
case "NetworkInformationPermission":
permSet.AddPermission(new NetworkInformationPermission(PermissionState.None));
break;
case "StorePermission":
permSet.AddPermission(new StorePermission(PermissionState.None));
break;
case "TypeDescriptorPermission":
permSet.AddPermission(new TypeDescriptorPermission(PermissionState.None));
break;
case "EventLogPermission":
permSet.AddPermission(new EventLogPermission(PermissionState.None));
break;
case "PerformanceCounterPermission":
permSet.AddPermission(new PerformanceCounterPermission(PermissionState.None));
break;
case "PrintingPermission":
permSet.AddPermission(new PrintingPermission(PermissionState.None));
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Sandboxer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return permSet;
}
}
}
Apologies in advance if the code isn't clear enough, hopefully someone could give me some helpful advice. Thank you in advance.
Aucun commentaire:
Enregistrer un commentaire