public void TestSingle()
 {
     using (var ctx = new Context())
     {
         int                 localPort     = 80;
         IPAddress           remoteAddress = IPAddress.Parse("192.168.1.1");
         int                 remotePort    = 128;
         int                 protocol      = 6;
         string              record        = $"X\tYes\tAllow\t{localPort}\t{remoteAddress}\t{remotePort}\t{protocol}";
         WindowsFirewallRule rule          = WindowsFirewallRuleParser.ParseRecord(
             WindowsFirewallRuleParserTest.HeaderIndex,
             record,
             '\t');
         var    packetVars = new WindowsFirewallPacketVariables(ctx);
         Solver s          = ctx.MkSolver();
         s.Assert(rule.Matches(ctx, packetVars));
         Status result = s.Check();
         Assert.AreEqual(Status.SATISFIABLE, result);
         var packet = new WindowsFirewallPacket(s.Model);
         Assert.AreEqual(remoteAddress, packet.SourceAddress);
         Assert.AreEqual(remotePort, packet.SourcePort);
         Assert.AreEqual(localPort, packet.DestinationPort);
         Assert.AreEqual(protocol, packet.Protocol);
     }
 }
        public void TestAllowByDefault()
        {
            using (var ctx = new Context())
            {
                IPAddress allowed    = IPAddress.Parse("128.0.0.1");
                string    lowerBlock = "X\tYes\tBlock\tAny\t0.0.0.0-128.0.0.0\tAny\tAny";
                string    upperBlock = "Y\tYes\tBlock\tAny\t128.0.0.2-255.255.255.255\tAny\tAny";
                string    text       = $"{WindowsFirewallRuleParserTest.HeaderText}\n{lowerBlock}\n{upperBlock}";
                var       firewall   = new WindowsFirewall
                {
                    BlockByDefault = false,
                    Rules          = WindowsFirewallRuleParser.Parse(text, '\t').ToList()
                };

                var    packetVars = new WindowsFirewallPacketVariables(ctx);
                Solver s          = ctx.MkSolver();
                s.Assert(firewall.Allows(ctx, packetVars));
                Status result = s.Check();
                Assert.AreEqual(Status.SATISFIABLE, result);
                var packet = new WindowsFirewallPacket(s.Model);
                Assert.AreEqual(allowed, packet.SourceAddress);
                Assert.AreEqual(null, packet.SourcePort);
                Assert.AreEqual(null, packet.DestinationPort);
                Assert.AreEqual(null, packet.Protocol);
            }
        }
        public void TestAllowSingle()
        {
            using (var ctx = new Context())
            {
                int       localPort     = 80;
                IPAddress remoteAddress = IPAddress.Parse("192.168.1.1");
                int       remotePort    = 128;
                int       protocol      = 6;
                string    record        = $"X\tYes\tAllow\t{localPort}\t{remoteAddress}\t{remotePort}\t{protocol}";
                string    text          = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}";
                var       firewall      = new WindowsFirewall
                {
                    BlockByDefault = true,
                    Rules          = WindowsFirewallRuleParser.Parse(text, '\t').ToList()
                };

                var    packetVars = new WindowsFirewallPacketVariables(ctx);
                Solver s          = ctx.MkSolver();
                s.Assert(firewall.Allows(ctx, packetVars));
                Status result = s.Check();
                Assert.AreEqual(Status.SATISFIABLE, result);
                var packet = new WindowsFirewallPacket(s.Model);
                Assert.AreEqual(remoteAddress, packet.SourceAddress);
                Assert.AreEqual(remotePort, packet.SourcePort);
                Assert.AreEqual(localPort, packet.DestinationPort);
                Assert.AreEqual(protocol, packet.Protocol);
            }
        }
Exemplo n.º 4
0
        public void TestMultipleDifferences()
        {
            int    localPort  = 8080;
            int    remotePort = 256;
            int    protocol   = 17;
            string record     = $"X\tYes\tAllow\t{localPort}\t255.255.255.0-255.255.255.15\t{remotePort}\t{protocol}";
            string text       = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}";
            var    f1         = new WindowsFirewall
            {
                Name           = "1",
                BlockByDefault = true,
                Rules          = WindowsFirewallRuleParser.Parse(text, '\t').ToList()
            };

            record = $"X\tYes\tAllow\t{localPort}\t255.255.255.0-255.255.255.2\t{remotePort}\t{protocol}";
            string record2 = $"Y\tYes\tAllow\t{localPort}\t255.255.255.4-255.255.255.6\t{remotePort}\t{protocol}";
            string record3 = $"Y\tYes\tAllow\t{localPort}\t255.255.255.8-255.255.255.10\t{remotePort}\t{protocol}";
            string record4 = $"Y\tYes\tAllow\t{localPort}\t255.255.255.12-255.255.255.15\t{remotePort}\t{protocol}";

            text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}\n{record2}\n{record3}\n{record4}";
            var f2 = new WindowsFirewall
            {
                Name           = "2",
                BlockByDefault = true,
                Rules          = WindowsFirewallRuleParser.Parse(text, '\t').ToList()
            };

            var inconsistencies = WindowsFirewallEquivalenceCheck.CheckEquivalence(f1, f2).ToList();
            var expected        = new HashSet <IPAddress>
            {
                IPAddress.Parse("255.255.255.3"),
                IPAddress.Parse("255.255.255.7"),
                IPAddress.Parse("255.255.255.11")
            };

            Assert.AreEqual(3, inconsistencies.Count);
            foreach (var inconsistency in inconsistencies)
            {
                Assert.AreEqual("1", inconsistency.Firewalls.Item1.Name);
                Assert.IsTrue(inconsistency.Allowed.Item1);
                Assert.AreEqual("2", inconsistency.Firewalls.Item2.Name);
                Assert.IsFalse(inconsistency.Allowed.Item2);
                Assert.AreEqual(1, inconsistency.RuleMatches.Item1.Count);
                Assert.AreEqual("X", inconsistency.RuleMatches.Item1.Single().Name);
                Assert.AreEqual(0, inconsistency.RuleMatches.Item2.Count);
                Assert.AreEqual(remotePort, inconsistency.Packet.SourcePort);
                Assert.AreEqual(localPort, inconsistency.Packet.DestinationPort);
                Assert.AreEqual(protocol, inconsistency.Packet.Protocol);
                Assert.IsTrue(expected.Contains(inconsistency.Packet.SourceAddress));
                expected.Remove(inconsistency.Packet.SourceAddress);
            }

            Assert.IsFalse(expected.Any());
        }
Exemplo n.º 5
0
        public void TestSameFirewall()
        {
            string record   = "X\tYes\tAllow\t80\t192.168.1.1\t128\t6";
            string record2  = "Y\tYes\tAllow\t8080\t127.0.0.1\t256\t6";
            string text     = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}\n{record2}";
            var    firewall = new WindowsFirewall
            {
                BlockByDefault = true,
                Rules          = WindowsFirewallRuleParser.Parse(text, '\t').ToList()
            };

            var inconsistencies = WindowsFirewallEquivalenceCheck.CheckEquivalence(firewall, firewall);

            Assert.IsFalse(inconsistencies.Any());
        }
Exemplo n.º 6
0
        /// <summary>
        /// Returns a list of inconsistencies between two firewall files.
        /// </summary>
        /// <param name="options">Options controlling the check.</param>
        /// <returns>A list of firewall inconsistencies.</returns>
        public static List <WindowsFirewallInconsistency> CheckFirewalls(Options options)
        {
            Console.WriteLine("Parsing first firewall...");
            WindowsFirewall f1 = new WindowsFirewall
            {
                BlockByDefault = options.Firewall1BlockByDefault,
                Rules          = WindowsFirewallRuleParser.Parse(File.ReadAllText(options.Firewall1Filepath), '\t').ToList()
            };

            Console.WriteLine("Parsing second firewall...");
            WindowsFirewall f2 = new WindowsFirewall
            {
                BlockByDefault = options.Firewall2BlockByDefault,
                Rules          = WindowsFirewallRuleParser.Parse(File.ReadAllText(options.Firewall2Filepath), '\t').ToList()
            };

            Console.WriteLine("Running equivalence check...");
            return(WindowsFirewallEquivalenceCheck.CheckEquivalence(f1, f2).Take(options.InconsistencyCount).ToList());
        }
Exemplo n.º 7
0
        public void TestSingleDifference()
        {
            int    localPort  = 80;
            int    remotePort = 128;
            int    protocol   = 6;
            string record     = $"X\tYes\tAllow\t{localPort}\t192.168.1.0-192.168.1.10\t{remotePort}\t{protocol}";
            string text       = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}";
            var    f1         = new WindowsFirewall
            {
                Name           = "1",
                BlockByDefault = true,
                Rules          = WindowsFirewallRuleParser.Parse(text, '\t').ToList()
            };

            record = $"X\tYes\tAllow\t{localPort}\t192.168.1.0-192.168.1.4\t{remotePort}\t{protocol}";
            string record2 = $"Y\tYes\tAllow\t{localPort}\t192.168.1.6-192.168.1.10\t{remotePort}\t{protocol}";

            text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}\n{record2}";
            var f2 = new WindowsFirewall
            {
                Name           = "2",
                BlockByDefault = true,
                Rules          = WindowsFirewallRuleParser.Parse(text, '\t').ToList()
            };

            var inconstistencies = WindowsFirewallEquivalenceCheck.CheckEquivalence(f1, f2).ToList();

            Assert.AreEqual(1, inconstistencies.Count);
            WindowsFirewallInconsistency inconsistency = inconstistencies.Single();

            Assert.AreEqual("1", inconsistency.Firewalls.Item1.Name);
            Assert.IsTrue(inconsistency.Allowed.Item1);
            Assert.AreEqual("2", inconsistency.Firewalls.Item2.Name);
            Assert.IsFalse(inconsistency.Allowed.Item2);
            Assert.AreEqual(1, inconsistency.RuleMatches.Item1.Count);
            Assert.AreEqual("X", inconsistency.RuleMatches.Item1.Single().Name);
            Assert.AreEqual(0, inconsistency.RuleMatches.Item2.Count);
            Assert.AreEqual(IPAddress.Parse("192.168.1.5"), inconsistency.Packet.SourceAddress);
            Assert.AreEqual(remotePort, inconsistency.Packet.SourcePort);
            Assert.AreEqual(localPort, inconsistency.Packet.DestinationPort);
            Assert.AreEqual(protocol, inconsistency.Packet.Protocol);
        }
        public void TestConflict()
        {
            using (var ctx = new Context())
            {
                int       localPort     = 80;
                IPAddress remoteAddress = IPAddress.Parse("192.168.1.1");
                int       remotePort    = 128;
                int       protocol      = 6;
                string    allowRecord   = $"X\tYes\tAllow\t{localPort}\t{remoteAddress}\t{remotePort}\t{protocol}";
                string    blockRecord   = $"Y\tYes\tBlock\t{localPort}\t{remoteAddress}\t{remotePort}\t{protocol}";
                string    text          = $"{WindowsFirewallRuleParserTest.HeaderText}\n{allowRecord}\n{blockRecord}";
                var       firewall      = new WindowsFirewall
                {
                    BlockByDefault = true,
                    Rules          = WindowsFirewallRuleParser.Parse(text, '\t').ToList()
                };

                var    packetVars = new WindowsFirewallPacketVariables(ctx);
                Solver s          = ctx.MkSolver();
                s.Assert(firewall.Allows(ctx, packetVars));
                Status result = s.Check();
                Assert.AreEqual(Status.UNSATISFIABLE, result);
            }
        }
Exemplo n.º 9
0
        public void TestEquivalentFirewalls()
        {
            string record = "X\tYes\tAllow\t80\t192.168.1.0-192.168.1.10\t128\t6";
            string text   = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}";
            var    f1     = new WindowsFirewall
            {
                BlockByDefault = true,
                Rules          = WindowsFirewallRuleParser.Parse(text, '\t').ToList()
            };

            record = "X\tYes\tAllow\t80\t192.168.1.0-192.168.1.5\t128\t6";
            string record2 = "Y\tYes\tAllow\t80\t192.168.1.6-192.168.1.10\t128\t6";

            text = $"{WindowsFirewallRuleParserTest.HeaderText}\n{record}\n{record2}";
            var f2 = new WindowsFirewall
            {
                BlockByDefault = true,
                Rules          = WindowsFirewallRuleParser.Parse(text, '\t').ToList()
            };

            var inconstistencies = WindowsFirewallEquivalenceCheck.CheckEquivalence(f1, f2);

            Assert.IsFalse(inconstistencies.Any());
        }
Exemplo n.º 10
0
        public static void TestPacket(Options options)
        {
            Console.WriteLine("Parsing firewall rules...");
            WindowsFirewall firewall = new WindowsFirewall
            {
                BlockByDefault = options.FirewallBlockByDefault,
                Rules          = WindowsFirewallRuleParser.Parse(File.ReadAllText(options.FirewallFilepath), '\t').ToList()
            };

            int  protocolNumber;
            bool anyProtocol = false;

            if (!NetworkProtocol.TryGetProtocolNumber(options.Protocol, out protocolNumber))
            {
                if (string.Equals("Any", options.Protocol, StringComparison.InvariantCultureIgnoreCase))
                {
                    anyProtocol = true;
                }
                else
                {
                    protocolNumber = int.Parse(options.Protocol);
                }
            }

            WindowsFirewallPacket packet = new WindowsFirewallPacket
            {
                SourceAddress   = IPAddress.Parse(options.SourceAddress),
                SourcePort      = string.Equals("Any", options.SourcePort, StringComparison.InvariantCultureIgnoreCase) ? null : (int?)int.Parse(options.SourcePort),
                DestinationPort = string.Equals("Any", options.DestinationPort, StringComparison.InvariantCultureIgnoreCase) ? null : (int?)int.Parse(options.DestinationPort),
                Protocol        = anyProtocol ? null : (int?)protocolNumber
            };

            Console.WriteLine("Checking action of firewall on packet...");
            using (var ctx = new Context())
            {
                Solver s          = ctx.MkSolver();
                var    packetVars = new WindowsFirewallPacketVariables(ctx);
                s.Assert(packet.Matches(ctx, packetVars));
                s.Check();

                if (s.Model.Eval(firewall.Allows(ctx, packetVars)).IsTrue)
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("Packet is allowed by firewall.");
                    Console.ResetColor();
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Packet is NOT allowed by firewall.");
                    Console.ResetColor();
                }

                List <WindowsFirewallRule> ruleMatches = firewall.GetMatches(ctx, packetVars, s.Model).ToList();
                if (!ruleMatches.Any())
                {
                    Console.WriteLine("No firewall rules match the test packet.");
                    return;
                }

                Console.WriteLine();
                Console.WriteLine("Firewall rules matching the test packet:");
                Console.WriteLine("-------------------------------------------------------------------------");
                Console.WriteLine("| Action | Rule Name                                                    |");
                Console.WriteLine("-------------------------------------------------------------------------");
                foreach (WindowsFirewallRule rule in ruleMatches)
                {
                    Console.WriteLine(
                        $"| {(rule.Allow ? "Allow" : "Block"), 6} " +
                        $"| {rule.Name.Substring(0, Math.Min(rule.Name.Length, 60)), -60} |");
                }

                Console.WriteLine("-------------------------------------------------------------------------");
            }
        }