public void DenyExcesiveDiskUsage() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.Disk; prisonRules.DiskQuotaBytes = 50 * 1024 * 1024; prisonRules.PrisonHomeRootPath = @"C:\Workspace\dea_security\PrisonHome"; prison.Lockdown(prisonRules); // Act string exe = Utilities.CreateExeForPrison( @" for (int size = 1; size < 100; size++) {{ byte[] content = new byte[1024 * 1024]; File.AppendAllText(Guid.NewGuid().ToString(""N""), ASCIIEncoding.ASCII.GetString(content)); }}", prison); Process process = prison.Execute(exe); process.WaitForExit(); // Assert Assert.AreNotEqual(0, process.ExitCode); }
public void LoadPrison() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.PrisonHomeRootPath = @"c:\prison_tests\p1"; prisonRules.Rules = RuleTypes.WindowStation; prison.Lockdown(prisonRules); // Act var prisonLoaded = PrisonManager.LoadPrisonAndAttach(prison.Id); Process process = prison.Execute( @"c:\windows\system32\cmd.exe", @"/c exit 667"); process.WaitForExit(); // Assert Process process2 = prisonLoaded.Execute( @"c:\windows\system32\cmd.exe", @"/c exit 667"); process2.WaitForExit(); // Assert Assert.AreEqual(667, process.ExitCode); }
public void DenyExcesiveMemory() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.Memory; prisonRules.TotalPrivateMemoryLimitBytes = 50 * 1024 * 1024; prisonRules.PrisonHomeRootPath = @"C:\Workspace\dea_security\PrisonHome"; prison.Lockdown(prisonRules); // Act string exe = Utilities.CreateExeForPrison( @" byte[] memory = new byte[100 * 1024 * 1024]; Random rnd = new Random(); rnd.NextBytes(memory); ", prison); Process process = prison.Execute(exe); process.WaitForExit(); // Assert Assert.AreNotEqual(0, process.ExitCode); }
public void StopForkBombs() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.Memory; prisonRules.CPUPercentageLimit = 2; prisonRules.TotalPrivateMemoryLimitBytes = 50 * 1024 * 1024; prisonRules.PrisonHomeRootPath = @"c:\prison_tests\p7"; prisonRules.ActiveProcessesLimit = 5; prison.Lockdown(prisonRules); // Act Process process = prison.Execute("", "cmd /c for /L %n in (1,0,10) do ( start cmd /k echo 32 )"); // Wait for the bomb to explode while (true) { if (prison.JobObject.ActiveProcesses >= 4) { break; } Thread.Sleep(100); } Thread.Sleep(500); // Assert Assert.IsTrue(prison.JobObject.ActiveProcesses < 6); }
public void Lockdown() { PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.None; prisonRules.PrisonHomeRootPath = this.HomePath; prisonRules.Rules |= RuleTypes.WindowStation; if (this.MemoryLimitBytes > 0) { prisonRules.Rules |= RuleTypes.Memory; prisonRules.TotalPrivateMemoryLimitBytes = this.MemoryLimitBytes; } if (this.DiskLimitBytes > 0) { prisonRules.Rules |= RuleTypes.Disk; prisonRules.DiskQuotaBytes = this.DiskLimitBytes; } if (this.NetworkPort > 0) { prisonRules.Rules |= RuleTypes.Httpsys; prisonRules.UrlPortAccess = this.NetworkPort; } prison.Lockdown(prisonRules); }
public void AssignNewDesktop() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.WindowStation; prisonRules.PrisonHomeRootPath = String.Format(@"c:\prison_tests\{0}", prison.Id); prison.Lockdown(prisonRules); // Act string exe = Utilities.CreateExeForPrison( string.Format(@" byte[] name = new byte[1024]; uint actualLength; GetUserObjectInformation(GetProcessWindowStation(), UOI_NAME, name, 1024, out actualLength); string workstationName = ASCIIEncoding.ASCII.GetString(name, 0, (int)actualLength - 1); if (workstationName != ""{0}"") {{ return 1; }} return 0; }} [DllImport(""user32.dll"", SetLastError = true)] public static extern bool GetUserObjectInformation(IntPtr hObj, int nIndex, [Out] byte[] pvInfo, uint nLength, out uint lpnLengthNeeded); [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] [DllImport(""user32"", CharSet = CharSet.Unicode, SetLastError = true)] internal static extern IntPtr GetProcessWindowStation(); public const int UOI_FLAGS = 1; public const int UOI_NAME = 2; public const int UOI_TYPE = 3; public const int UOI_USER_SID = 4; public const int UOI_HEAPSIZE = 5; //Windows Server 2003 and Windows XP/2000: This value is not supported. public const int UOI_IO = 6; private static int Dummy() {{ ", prison.User.UserName), prison); Process process = prison.Execute(exe, "", false); process.WaitForExit(); // Assert Assert.AreEqual(0, process.ExitCode); }
public void SavePrison() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.PrisonHomeRootPath = @"c:\prison_tests\p1"; prisonRules.Rules = RuleTypes.None; // Act prison.Lockdown(prisonRules); // Assert Assert.IsTrue(PrisonManager.ReadAllPrisonsNoAttach().Any(p => p.Id == prison.Id)); }
public void LoadedPrisonIsLocked() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.PrisonHomeRootPath = @"c:\prison_tests\p1"; prisonRules.Rules = RuleTypes.WindowStation; prison.Lockdown(prisonRules); // Act var prisonLoaded = PrisonManager.LoadPrisonAndAttach(prison.Id); // Assert Assert.IsTrue(prisonLoaded.IsLocked); }
public void TestSimpleEcho() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.None; prisonRules.PrisonHomeRootPath = @"c:\prison_tests\p9"; prison.Lockdown(prisonRules); // Act Process process = prison.Execute( @"c:\windows\system32\cmd.exe", @"/c echo test"); // Assert Assert.AreNotEqual(0, process.Id); }
public void TestExitCode() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.None; prisonRules.Rules |= RuleTypes.WindowStation; prisonRules.PrisonHomeRootPath = String.Format(@"c:\prison_tests\{0}", prison.Id); prison.Lockdown(prisonRules); // Act Process process = prison.Execute( @"c:\windows\system32\cmd.exe", @"/c exit 667"); process.WaitForExit(); // Assert Assert.AreEqual(667, process.ExitCode); }
public void AllowAccessInHomeDir() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.FileSystem; prisonRules.PrisonHomeRootPath = Path.Combine(@"C:\Workspace\dea_security\PrisonHome"); prison.Lockdown(prisonRules); // Act string exe = Utilities.CreateExeForPrison( @" File.WriteAllText(Guid.NewGuid().ToString(""N""), Guid.NewGuid().ToString()); ", prison); Process process = prison.Execute(exe); process.WaitForExit(); // Assert Assert.AreEqual(0, process.ExitCode); }
public void TestMultipleEcho() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.None; prisonRules.PrisonHomeRootPath = String.Format(@"c:\prison_tests\{0}", prison.Id); prison.Lockdown(prisonRules); // Act Process process1 = prison.Execute( @"c:\windows\system32\cmd.exe", @"/c echo test"); Process process2 = prison.Execute( @"c:\windows\system32\cmd.exe", @"/c echo test"); // Assert Assert.AreNotEqual(0, process1.Id); Assert.AreNotEqual(0, process2.Id); }
public void TestPowerShell() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.None; prisonRules.Rules |= RuleTypes.WindowStation; prisonRules.Rules |= RuleTypes.IISGroup; prisonRules.PrisonHomeRootPath = String.Format(@"c:\prison_tests\{0}", prison.Id); prison.Lockdown(prisonRules); // Act Process process = prison.Execute( @"c:\windows\system32\cmd.exe", @" /c powershell.exe -Command Get-NetIPAddress"); process.WaitForExit(); // Assert Assert.AreEqual(0, process.ExitCode); }
public void DisallowAccessEverywhereElse() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.FileSystem; prisonRules.PrisonHomeRootPath = @"C:\Workspace\dea_security\PrisonHome"; prison.Lockdown(prisonRules); // Act string exe = Utilities.CreateExeForPrison( @" return WalkDirectoryTree(new DirectoryInfo(@""c:\"")); } static int WalkDirectoryTree(System.IO.DirectoryInfo root) { System.IO.DirectoryInfo[] subDirs = null; // First, process all the files directly under this folder try { string adir = Guid.NewGuid().ToString(""N""); Directory.CreateDirectory(Path.Combine(root.FullName, adir)); Directory.Delete(Path.Combine(root.FullName, adir)); return 1; } catch { } try { string adir = Guid.NewGuid().ToString(""N""); File.WriteAllText(Path.Combine(root.FullName, adir), ""test""); File.Delete(Path.Combine(root.FullName, adir)); return 1; } catch { } try { subDirs = root.GetDirectories(); foreach (System.IO.DirectoryInfo dirInfo in subDirs) { // Resursive call for each subdirectory. return WalkDirectoryTree(dirInfo); } } catch { } return 0; } static int Dummy() { ", prison); Process process = prison.Execute(exe); process.WaitForExit(); // Assert Assert.AreEqual(0, process.ExitCode); }
public void StopForkBombs() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.Memory; prisonRules.CPUPercentageLimit = 2; prisonRules.TotalPrivateMemoryLimitBytes = 50 * 1024 * 1024; prisonRules.PrisonHomeRootPath = @"c:\prison_tests\p7"; prisonRules.ActiveProcessesLimit = 5; prison.Lockdown(prisonRules); // Act Process process = prison.Execute("", "cmd /c for /L %n in (1,0,10) do ( start cmd /k echo 32 )"); // Wait for the bomb to explode while (true) { if (prison.JobObject.ActiveProcesses >= 4) break; Thread.Sleep(100); } Thread.Sleep(500); // Assert Assert.IsTrue(prison.JobObject.ActiveProcesses < 6); }
public void AllowLargerUploadSpeedOnSecondPort() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.Httpsys | RuleTypes.Network; prisonRules.NetworkOutboundRateLimitBitsPerSecond = 8 * 1024 * 100; prisonRules.AppPortOutboundRateLimitBitsPerSecond = 8 * 1024 * 200; prisonRules.UrlPortAccess = 56444; prisonRules.PrisonHomeRootPath = @"C:\Workspace\dea_security\PrisonHome"; prison.Lockdown(prisonRules); // Act string exe = Utilities.CreateExeForPrison( @" HttpListener actualServer = null; int port = 56444; int actualServerPort = port; actualServer = new HttpListener(); actualServer.Prefixes.Add(string.Format(""http://*:{0}/"", port)); actualServer.Start(); byte[] reply = new byte[1024 * 1024]; Random rnd = new Random(); rnd.NextBytes(reply); Console.WriteLine(""Done loading""); int requests = 0; while (requests < 2) { HttpListenerContext context = actualServer.GetContext(); context.Response.StatusCode = 200; if (requests == 0) { context.Response.OutputStream.Write(reply, 0, reply.Length); } context.Response.OutputStream.Close(); requests++; } if (actualServer != null) { actualServer.Stop(); } FtpWebRequest request = (FtpWebRequest)WebRequest.Create(""ftp://127.0.0.1/prisontests/uploadtest.txt""); request.ConnectionGroupName = ""MyGroupName""; request.UseBinary = true; request.KeepAlive = true; request.Method = WebRequestMethods.Ftp.UploadFile; // This example assumes the FTP site uses anonymous logon. request.Credentials = new NetworkCredential(""user"", ""password""); request.ContentLength = 1024 * 1024; Stream requestStream = request.GetRequestStream(); Stopwatch timer = Stopwatch.StartNew(); for (int i = 0; i < request.ContentLength / 256; i++) { timer.Stop(); byte[] data = new byte[256]; Random random = new Random(); random.NextBytes(data); timer.Start(); requestStream.Write(data, 0, data.Length); } requestStream.Close(); FtpWebResponse response = (FtpWebResponse)request.GetResponse(); response.Close(); timer.Stop(); if ((1024 / timer.Elapsed.TotalSeconds) > 110) { return 1; } ", prison); Process process = prison.Execute(exe); // Wait a bit for everything to be setup. Thread.Sleep(5000); Stopwatch timer = Stopwatch.StartNew(); WebClient client = new WebClient(); client.Proxy = new WebProxy("http://192.168.1.119:8080"); byte[] data = client.DownloadData("http://10.0.0.10:56444/"); timer.Stop(); Assert.IsTrue( ((1024 / timer.Elapsed.TotalSeconds) < 210) && ((1024 / timer.Elapsed.TotalSeconds) > 110), string.Format("Downloaded {0} bytes in {1} seconds, at a rate of {2} KB/s", data.Length, timer.Elapsed.TotalSeconds, 1024 / timer.Elapsed.TotalSeconds)); client.DownloadData("http://localhost:56444/"); process.WaitForExit(); // Assert Assert.AreEqual(0, process.ExitCode); }
// Currently not working public void LimitPagedPool() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.Memory; prisonRules.TotalPrivateMemoryLimitBytes = 50 * 1024 * 1024; prisonRules.PrisonHomeRootPath = @"c:\prison_tests\p9"; prisonRules.ActiveProcessesLimit = 5; prison.Lockdown(prisonRules); // Act string exe = Utilities.CreateExeForPrison( @" string MailslotName = @""\\.\mailslot\sterssmailslot""; var hMailslotA = CreateMailslot(MailslotName, 0, MAILSLOT_WAIT_FOREVER, IntPtr.Zero); var hMailslot = CreateFile(MailslotName, FileDesiredAccess.GENERIC_WRITE, FileShareMode.FILE_SHARE_READ, IntPtr.Zero, FileCreationDisposition.OPEN_EXISTING, 0, IntPtr.Zero); int cbBytesWritten; byte[] bMessage = Encoding.Unicode.GetBytes(""Hello mailslot! Still alive?""); while (true) { WriteFile(hMailslot, bMessage, bMessage.Length, out cbBytesWritten, IntPtr.Zero); } return 0; } [Flags] enum FileDesiredAccess : uint { GENERIC_READ = 0x80000000, GENERIC_WRITE = 0x40000000, GENERIC_EXECUTE = 0x20000000, GENERIC_ALL = 0x10000000 } [Flags] enum FileShareMode : uint { Zero = 0x00000000, // No sharing FILE_SHARE_DELETE = 0x00000004, FILE_SHARE_READ = 0x00000001, FILE_SHARE_WRITE = 0x00000002 } enum FileCreationDisposition : uint { CREATE_NEW = 1, CREATE_ALWAYS = 2, OPEN_EXISTING = 3, OPEN_ALWAYS = 4, TRUNCATE_EXISTING = 5 } const int MAILSLOT_WAIT_FOREVER = -1; const int MAILSLOT_NO_MESSAGE = -1; [DllImport(""kernel32.dll"", CharSet = CharSet.Auto, SetLastError = true)] static extern IntPtr CreateMailslot(string mailslotName, uint nMaxMessageSize, int lReadTimeout, IntPtr securityAttributes); [DllImport(""kernel32.dll"", CharSet = CharSet.Auto, SetLastError = true)] static extern IntPtr CreateFile(string fileName, FileDesiredAccess desiredAccess, FileShareMode shareMode, IntPtr securityAttributes, FileCreationDisposition creationDisposition, int flagsAndAttributes, IntPtr hTemplateFile); [DllImport(""kernel32.dll"", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool WriteFile(IntPtr handle, byte[] bytes, int numBytesToWrite, out int numBytesWritten, IntPtr overlapped); private static int Dummy() { ", prison); Process process = prison.Execute(exe); long lastVal = 0; // Assert // Wait for the bomb to explode while (prison.JobObject.PagedSystemMemory > lastVal) { lastVal = prison.JobObject.PagedSystemMemory; Assert.IsTrue(prison.JobObject.PagedSystemMemory < prisonRules.TotalPrivateMemoryLimitBytes); Thread.Sleep(300); } }
public void LimitUploadSpeed() { // Arrange PrisonConfiguration prisonRules = new PrisonConfiguration(); prisonRules.Rules = RuleTypes.Network; prisonRules.NetworkOutboundRateLimitBitsPerSecond = 8 * 1024 * 100; prisonRules.PrisonHomeRootPath = @"C:\Workspace\dea_security\PrisonHome"; prison.Lockdown(prisonRules); // Wait a bit for the rule to take effect. Thread.Sleep(5000); // Act string exe = Utilities.CreateExeForPrison( @" FtpWebRequest request = (FtpWebRequest)WebRequest.Create(""ftp://127.0.0.1/prisontests/uploadtest.txt""); request.ConnectionGroupName = ""MyGroupName""; request.UseBinary = true; request.KeepAlive = true; request.Method = WebRequestMethods.Ftp.UploadFile; // This example assumes the FTP site uses anonymous logon. request.Credentials = new NetworkCredential(""user"", ""password""); request.ContentLength = 1024 * 1024; Stream requestStream = request.GetRequestStream(); Stopwatch timer = Stopwatch.StartNew(); for (int i = 0; i < request.ContentLength / 256; i++) { timer.Stop(); byte[] data = new byte[256]; Random random = new Random(); random.NextBytes(data); timer.Start(); requestStream.Write(data, 0, data.Length); } requestStream.Close(); FtpWebResponse response = (FtpWebResponse)request.GetResponse(); response.Close(); timer.Stop(); if ((1024 / timer.Elapsed.TotalSeconds) > 110) { return 1; } ", prison); Process process = prison.Execute(exe); process.WaitForExit(); // Assert Assert.AreEqual(0, process.ExitCode); }