Ejemplo n.º 1
0
        /// <summary>
        /// Loads all persisted Prison instances.
        /// <remarks>
        /// This method assumes that serialized Prison objects are stored in a folder named 'db', next to the assembly.
        /// </remarks>
        /// </summary>
        /// <returns>An array of Prison objects.</returns>
        public static Prison[] Load()
        {
            List <Prison> result = new List <Prison>();

            string dataLocation = Environment.GetFolderPath(Environment.SpecialFolder.System);
            string loadLocation = Path.GetFullPath(Path.Combine(dataLocation, Prison.databaseLocation));

            Logger.Debug("Loading prison database from {0}", loadLocation);

            Directory.CreateDirectory(loadLocation);

            string[] prisonFiles = Directory.GetFiles(loadLocation, "*.xml", SearchOption.TopDirectoryOnly);

            Logger.Debug("Found {0} prison entries", prisonFiles.Length);

            DataContractSerializer serializer = new DataContractSerializer(typeof(Prison));

            foreach (string prisonLocation in prisonFiles)
            {
                using (FileStream readStream = File.OpenRead(prisonLocation))
                {
                    Prison loadedPrison = (Prison)serializer.ReadObject(readStream);
                    result.Add(loadedPrison);
                }
            }

            return(result.ToArray());
        }
Ejemplo n.º 2
0
        public Process InitializeProcess(string filename, string arguments, bool interactive, Dictionary <string, string> extraEnvironmentVariables)
        {
            // C with Win32 API example to start a process under a different user: http://msdn.microsoft.com/en-us/library/aa379608%28VS.85%29.aspx

            if (!this.isLocked)
            {
                throw new InvalidOperationException("This prison has to be locked before you can use it.");
            }


            this.InitializeLogonToken();
            this.LoadUserProfileIfNotLoaded();

            var envs = GetDefaultEnvironmentVarialbes();

            // environmentVariables from the method parameters have precedence over the default envs
            if (extraEnvironmentVariables != null)
            {
                foreach (var env in extraEnvironmentVariables)
                {
                    envs[env.Key] = env.Value;
                }
            }

            string envBlock = extraEnvironmentVariables == null ? null : Prison.BuildEnvironmentVariable(envs);

            Logger.Debug("Starting process '{0}' with arguments '{1}' as user '{2}' in working dir '{3}'", filename, arguments, this.user.Username, this.prisonRules.PrisonHomePath);

            if (filename == string.Empty)
            {
                filename = null;
            }

            if (CellEnabled(RuleType.WindowStation))
            {
                new WindowStation().Apply(this);
            }

            Native.PROCESS_INFORMATION processInfo = NativeCreateProcessAsUser(interactive, filename, arguments, envBlock);

            var workerProcessPid = processInfo.dwProcessId;
            var workerProcess    = Process.GetProcessById(workerProcessPid);

            // AccessTokenHandle
            // workerProcess.RemovePrivilege(ProcessPrivileges.Privilege.ChangeNotify);
            // ProcessExtensions.RemovePrivilege(new AccessTokenHandle() , Privilege.ChangeNotify);

            // Tag the process with the Job Object before resuming the process.
            this.jobObject.AddProcess(workerProcess);

            // Add process in the second job object
            this.AddProcessToGuardJobObject(workerProcess);

            // This would allow the process to query the ExitCode. ref: http://msdn.microsoft.com/en-us/magazine/cc163900.aspx
            workerProcess.EnableRaisingEvents = true;

            return(workerProcess);
        }
Ejemplo n.º 3
0
        public static Prison LoadPrisonNoAttach(Guid prisonId)
        {
            Prison loadedPrison = Prison.Load().First(p => p.ID == prisonId);

            if (loadedPrison != null)
            {
                return(loadedPrison);
            }
            else
            {
                return(null);
            }
        }
        private static void AllowReadOfBaseMSSQLInstance(string path, Prison prison)
        {
            DirectoryInfo dirInfo = new DirectoryInfo(path);
            DirectorySecurity dirSecurity = dirInfo.GetAccessControl();

            dirSecurity.SetAccessRule(
                new FileSystemAccessRule(
                    prison.User.Username,
                    FileSystemRights.Read | FileSystemRights.ListDirectory | FileSystemRights.ReadAttributes | FileSystemRights.ReadData | FileSystemRights.Synchronize,
                    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
                    PropagationFlags.None,
                    AccessControlType.Allow));

            using (new ProcessPrivileges.PrivilegeEnabler(Process.GetCurrentProcess(), ProcessPrivileges.Privilege.Restore))
            {
                dirInfo.SetAccessControl(dirSecurity);
            }
        }
        private static void AllowReadOfBaseMSSQLInstance(string path, Prison prison)
        {
            DirectoryInfo     dirInfo     = new DirectoryInfo(path);
            DirectorySecurity dirSecurity = dirInfo.GetAccessControl();

            dirSecurity.SetAccessRule(
                new FileSystemAccessRule(
                    prison.User.Username,
                    FileSystemRights.Read | FileSystemRights.ListDirectory | FileSystemRights.ReadAttributes | FileSystemRights.ReadData | FileSystemRights.Synchronize,
                    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
                    PropagationFlags.None,
                    AccessControlType.Allow));

            using (new ProcessPrivileges.PrivilegeEnabler(Process.GetCurrentProcess(), ProcessPrivileges.Privilege.Restore))
            {
                dirInfo.SetAccessControl(dirSecurity);
            }
        }
        private static void GrantRegistryAccess(string key, Prison prison)
        {
            NTAccount account = new NTAccount(null, prison.User.Username);
            var       hklm    = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);

            using (RegistryKey rk = hklm.OpenSubKey(key, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl))
            {
                RegistrySecurity   rs  = rk.GetAccessControl();
                RegistryAccessRule rar = new RegistryAccessRule(
                    account.ToString(),
                    RegistryRights.FullControl,
                    InheritanceFlags.ContainerInherit,
                    PropagationFlags.None,
                    AccessControlType.Allow);

                rs.AddAccessRule(rar);
                rk.SetAccessControl(rs);
            }
        }
        /// <summary>
        /// Give access to read the default SQL Server instance files and write to the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\
        /// </summary>
        /// <param name="prison">prison object associated to the gear</param>
        /// <param name="instanceType">MsSql server instance type MSSQL10_50/MSSQL11</param>
        /// <param name="defaultInstanceName">MsSql default instance MSSQLSERVER/MSSQLSERVER2012</param>
        public static void ConfigureMsSqlInstanceRegistry(Prison prison, string instanceType, string defaultInstanceName)
        {
            try
            {
                var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);

                string sqlPath = hklm.OpenSubKey(string.Format(@"SOFTWARE\Microsoft\Microsoft SQL Server\{0}.{1}\Setup", instanceType, defaultInstanceName), true).GetValue("SQLPath", string.Empty).ToString();

                if (!string.IsNullOrWhiteSpace(sqlPath) && Directory.Exists(sqlPath))
                {
                    AllowReadOfBaseMSSQLInstance(sqlPath, prison);

                    string instanceName = string.Format("Instance{0}", prison.Rules.UrlPortAccess);

                    hklm.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL", true).SetValue(instanceName, string.Format("{0}.{1}", instanceType, instanceName), RegistryValueKind.String);

                    string instanceRegistryKey1 = string.Format(@"SOFTWARE\Microsoft\Microsoft SQL Server\{0}", instanceName);
                    hklm.CreateSubKey(instanceRegistryKey1);

                    string instanceRegistryKey2 = string.Format(@"SOFTWARE\Microsoft\Microsoft SQL Server\{0}.{1}", instanceType, instanceName);
                    hklm.CreateSubKey(instanceRegistryKey2);

                    string instanceRegistryKey3 = string.Format(@"SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server\{0}", instanceName);
                    hklm.CreateSubKey(instanceRegistryKey3);


                    // Give registry access
                    GrantRegistryAccess(instanceRegistryKey1, prison);
                    GrantRegistryAccess(instanceRegistryKey2, prison);
                    GrantRegistryAccess(instanceRegistryKey3, prison);
                    GrantRegistryAccess(@"SYSTEM\CurrentControlSet\Services\WinSock2\Parameters", prison);
                }

            }
            catch (Exception ex)
            {
                Logger.Error("There was an error while applying MsSqlInstance Prison Rule: {0} - {1}", ex.Message, ex.StackTrace);
                throw;
            }
        }
        /// <summary>
        /// Give access to read the default SQL Server instance files and write to the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\
        /// </summary>
        /// <param name="prison">prison object associated to the gear</param>
        /// <param name="instanceType">MsSql server instance type MSSQL10_50/MSSQL11</param>
        /// <param name="defaultInstanceName">MsSql default instance MSSQLSERVER/MSSQLSERVER2012</param>
        public static void ConfigureMsSqlInstanceRegistry(Prison prison, string instanceType, string defaultInstanceName)
        {
            try
            {
                var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);

                string sqlPath = hklm.OpenSubKey(string.Format(@"SOFTWARE\Microsoft\Microsoft SQL Server\{0}.{1}\Setup", instanceType, defaultInstanceName), true).GetValue("SQLPath", string.Empty).ToString();

                if (!string.IsNullOrWhiteSpace(sqlPath) && Directory.Exists(sqlPath))
                {
                    AllowReadOfBaseMSSQLInstance(sqlPath, prison);

                    string instanceName = string.Format("Instance{0}", prison.Rules.UrlPortAccess);

                    hklm.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL", true).SetValue(instanceName, string.Format("{0}.{1}", instanceType, instanceName), RegistryValueKind.String);

                    string instanceRegistryKey1 = string.Format(@"SOFTWARE\Microsoft\Microsoft SQL Server\{0}", instanceName);
                    hklm.CreateSubKey(instanceRegistryKey1);

                    string instanceRegistryKey2 = string.Format(@"SOFTWARE\Microsoft\Microsoft SQL Server\{0}.{1}", instanceType, instanceName);
                    hklm.CreateSubKey(instanceRegistryKey2);

                    string instanceRegistryKey3 = string.Format(@"SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server\{0}", instanceName);
                    hklm.CreateSubKey(instanceRegistryKey3);


                    // Give registry access
                    GrantRegistryAccess(instanceRegistryKey1, prison);
                    GrantRegistryAccess(instanceRegistryKey2, prison);
                    GrantRegistryAccess(instanceRegistryKey3, prison);
                    GrantRegistryAccess(@"SYSTEM\CurrentControlSet\Services\WinSock2\Parameters", prison);
                }
            }
            catch (Exception ex)
            {
                Logger.Error("There was an error while applying MsSqlInstance Prison Rule: {0} - {1}", ex.Message, ex.StackTrace);
                throw;
            }
        }
Ejemplo n.º 9
0
 public abstract void Recover(Prison prison);
Ejemplo n.º 10
0
 public abstract void Destroy(Prison prison);
Ejemplo n.º 11
0
 public abstract void Apply(Prison prison);
Ejemplo n.º 12
0
        public Process Execute(string filename, string arguments, bool interactive, Dictionary <string, string> extraEnvironmentVariables)
        {
            // C with Win32 API example to start a process under a different user: http://msdn.microsoft.com/en-us/library/aa379608%28VS.85%29.aspx

            if (!this.isLocked)
            {
                throw new InvalidOperationException("This prison has to be locked before you can use it.");
            }

            var startupInfo = new Native.STARTUPINFO();
            var processInfo = new Native.PROCESS_INFORMATION();

            startupInfo = new Native.STARTUPINFO();

            if (CellEnabled(RuleType.WindowStation))
            {
                new WindowStation().Apply(this);
                startupInfo.lpDesktop = this.desktopName;
            }


            Native.ProcessCreationFlags creationFlags = Native.ProcessCreationFlags.ZERO_FLAG;

            // Exclude flags
            creationFlags &=
                ~Native.ProcessCreationFlags.CREATE_PRESERVE_CODE_AUTHZ_LEVEL &
                ~Native.ProcessCreationFlags.CREATE_BREAKAWAY_FROM_JOB;

            // Include flags
            creationFlags |=
                Native.ProcessCreationFlags.CREATE_DEFAULT_ERROR_MODE |
                Native.ProcessCreationFlags.CREATE_NEW_PROCESS_GROUP |
                Native.ProcessCreationFlags.CREATE_SUSPENDED |
                Native.ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT;

            // TODO: extra steps for interactive to work:
            // http://blogs.msdn.com/b/winsdk/archive/2013/05/01/how-to-launch-a-process-interactively-from-a-windows-service.aspx
            if (interactive)
            {
                creationFlags        |= Native.ProcessCreationFlags.CREATE_NEW_CONSOLE;
                startupInfo.lpDesktop = "";
            }
            else
            {
                //     creationFlags |= Native.ProcessCreationFlags.CREATE_NO_WINDOW;

                // startupInfo.dwFlags |= 0x00000100; // STARTF_USESTDHANDLES
                startupInfo.hStdInput  = Native.GetStdHandle(Native.STD_INPUT_HANDLE);
                startupInfo.hStdOutput = Native.GetStdHandle(Native.STD_OUTPUT_HANDLE);
                startupInfo.hStdError  = Native.GetStdHandle(Native.STD_ERROR_HANDLE);
            }


            this.InitializeLogonToken();
            this.LoadUserProfileIfNotLoaded();

            var envs = GetDefaultEnvironmentVarialbes();

            // environmentVariables from the method parameters have precedence over the default envs
            if (extraEnvironmentVariables != null)
            {
                foreach (var env in extraEnvironmentVariables)
                {
                    envs[env.Key] = env.Value;
                }
            }

            string envBlock = extraEnvironmentVariables == null ? null : Prison.BuildEnvironmentVariable(envs);

            Native.SECURITY_ATTRIBUTES processAttributes = new Native.SECURITY_ATTRIBUTES();
            Native.SECURITY_ATTRIBUTES threadAttributes  = new Native.SECURITY_ATTRIBUTES();
            processAttributes.nLength = Marshal.SizeOf(processAttributes);
            threadAttributes.nLength  = Marshal.SizeOf(threadAttributes);

            Logger.Debug("Starting process '{0}' with arguments '{1}' as user '{2}' in working dir '{3}'", filename, arguments, this.user.Username, this.prisonRules.PrisonHomePath);

            if (filename == string.Empty)
            {
                filename = null;
            }

            var createProcessSuc = Native.CreateProcessAsUser(
                hToken: logonToken.DangerousGetHandle(),
                lpApplicationName: filename,
                lpCommandLine: arguments,
                lpProcessAttributes: ref processAttributes,
                lpThreadAttributes: ref threadAttributes,
                bInheritHandles: false,
                dwCreationFlags: creationFlags,
                lpEnvironment: envBlock,
                lpCurrentDirectory: this.prisonRules.PrisonHomePath,
                lpStartupInfo: ref startupInfo,
                lpProcessInformation: out processInfo);

            if (createProcessSuc == false)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            var workerProcessPid = processInfo.dwProcessId;
            var workerProcess    = Process.GetProcessById(workerProcessPid);


            // AccessTokenHandle
            // workerProcess.RemovePrivilege(ProcessPrivileges.Privilege.ChangeNotify);
            // ProcessExtensions.RemovePrivilege(new AccessTokenHandle() , Privilege.ChangeNotify);

            // Tag the process with the Job Object before resuming the process.
            this.jobObject.AddProcess(workerProcess);

            // Add process in the second job object
            this.AddProcessToGuardJobObject(workerProcess);

            // This would allow the process to query the ExitCode. ref: http://msdn.microsoft.com/en-us/magazine/cc163900.aspx
            workerProcess.EnableRaisingEvents = true;

            // Now that the process is tagged with the Job Object so we can resume the thread.
            IntPtr threadHandler = Native.OpenThread(Native.ThreadAccess.SUSPEND_RESUME, false, processInfo.dwThreadId);

            uint resumeResult = Native.ResumeThread(threadHandler);

            Native.CloseHandle(threadHandler);

            if (resumeResult != 1)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            return(workerProcess);
        }
Ejemplo n.º 13
0
 public abstract void Recover(Prison prison);
Ejemplo n.º 14
0
 public abstract void Destroy(Prison prison);
Ejemplo n.º 15
0
 public abstract void Apply(Prison prison);
Ejemplo n.º 16
0
        private static void GrantRegistryAccess(string key, Prison prison)
        {
            NTAccount account = new NTAccount(null, prison.User.Username);
            var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);

            using (RegistryKey rk = hklm.OpenSubKey(key, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl))
            {
                RegistrySecurity rs = rk.GetAccessControl();
                RegistryAccessRule rar = new RegistryAccessRule(
                    account.ToString(),
                    RegistryRights.FullControl,
                    InheritanceFlags.ContainerInherit,
                    PropagationFlags.None,
                    AccessControlType.Allow);

                rs.AddAccessRule(rar);
                rk.SetAccessControl(rs);
            }
        }