mardi 23 février 2016

Restrict permissions to Drivers and Applications WinForms C#

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