Exemple #1
0
  def testNtpDoesntAllowOpenQueries(self):
    """Test for checking we don't allow queries by default."""
    parser = config_file.NtpdParser()

    check_id = "TIME-NTP-NO-OPEN-QUERIES"
    artifact_id = "NtpConfFile"
    good_config = {"/etc/ntp.conf": """
        restrict default nomodify noquery nopeer
        """}
    bad_config = {"/etc/ntp.conf": """
        restrict default nomodify nopeer
        """}
    bad_default_config = {"/etc/ntp.conf": """
        """}

    # A good config should pass.
    results = self.RunChecks(
        self.GenFileData("NtpConfFile", good_config, parser))
    self.assertCheckUndetected(check_id, results)

    found = ["Expected state was not found"]
    sym = ("Missing attribute: ntpd.conf is configured or defaults to open "
           "queries. Can allow DDoS. This configuration is an on-going "
           "recommendation following the Ntp December 2014 Vulnerability "
           "notice. (http://support.ntp.org/bin/view/Main/SecurityNotice)")
    # A bad one should detect a problem.
    results = self.RunChecks(self.GenFileData(artifact_id, bad_config, parser))
    self.assertCheckDetectedAnom(check_id, results, sym, found)

    # And as the default is to be queryable, check we detect an empty config.
    results = self.RunChecks(
        self.GenFileData(artifact_id, bad_default_config, parser))
    self.assertCheckDetectedAnom(check_id, results, sym, found)
Exemple #2
0
    def testNtpHasMonitorDisabled(self):
        """Test for checking that monitor is disabled."""
        parser = config_file.NtpdParser()

        good_config = {
            "/etc/ntp.conf": """
        disable monitor
        """
        }
        good_tricky_config = {
            "/etc/ntp.conf":
            """
        disable monitor auth
        enable kernel monitor auth
        disable kernel monitor
        """
        }
        bad_config = {"/etc/ntp.conf": """
        enable monitor
        """}
        bad_default_config = {"/etc/ntp.conf": """
        """}
        bad_tricky_config = {
            "/etc/ntp.conf":
            """
        enable kernel monitor auth
        disable monitor auth
        enable kernel monitor
        """
        }
        found = ["ntpd.conf has monitor flag set to True."]
        sym = (
            "Found: ntpd.conf is configured to allow monlist NTP reflection "
            "attacks.")

        results = self.RunChecks(
            self.GenFileData("NtpConfFile", good_config, parser))
        self.assertCheckUndetected("TIME-NTP-REFLECTION", results)

        results = self.RunChecks(
            self.GenFileData("NtpConfFile", good_tricky_config, parser))
        self.assertCheckUndetected("TIME-NTP-REFLECTION", results)

        results = self.RunChecks(
            self.GenFileData("NtpConfFile", bad_config, parser))
        self.assertCheckDetectedAnom("TIME-NTP-REFLECTION", results, sym,
                                     found)

        results = self.RunChecks(
            self.GenFileData("NtpConfFile", bad_default_config, parser))
        self.assertCheckDetectedAnom("TIME-NTP-REFLECTION", results, sym,
                                     found)

        results = self.RunChecks(
            self.GenFileData("NtpConfFile", bad_tricky_config, parser))
        self.assertCheckDetectedAnom("TIME-NTP-REFLECTION", results, sym,
                                     found)
Exemple #3
0
    def testNtpDoesntAllowOpenQueries(self):
        """Test for checking we don't allow queries by default."""
        parser = config_file.NtpdParser()

        good_config = {
            "/etc/ntp.conf":
            """
        restrict default nomodify noquery nopeer
        """
        }
        bad_config = {
            "/etc/ntp.conf":
            """
        restrict default nomodify nopeer
        """
        }
        bad_default_config = {"/etc/ntp.conf": """
        """}

        # A good config should pass.
        results = self.RunChecks(
            self.GenFileData("NtpConfFile", good_config, parser))
        self.assertCheckUndetected("TIME-NTP-VULN-2014-12", results)

        found = ["Expected state was not found"]
        sym = (
            "Missing attribute: ntpd.conf is configured or defaults to open "
            "queries. Can allow DDoS.")
        # A bad one should detect a problem.
        results = self.RunChecks(
            self.GenFileData("NtpConfFile", bad_config, parser))
        self.assertCheckDetectedAnom("TIME-NTP-VULN-2014-12", results, sym,
                                     found)

        # And as the default is to be queryable, check we detect an empty config.
        results = self.RunChecks(
            self.GenFileData("NtpConfFile", bad_default_config, parser))
        self.assertCheckDetectedAnom("TIME-NTP-VULN-2014-12", results, sym,
                                     found)
Exemple #4
0
  def testParseNtpConfig(self):
    test_data = r"""
    # Time servers
    server 1.2.3.4 iburst
    server 4.5.6.7 iburst
    server 8.9.10.11 iburst
    server pool.ntp.org iburst
    server 2001:1234:1234:2::f iburst

    # Drift file
    driftfile /var/lib/ntp/ntp.drift

    restrict default nomodify noquery nopeer

    # Guard against monlist NTP reflection attacks.
    disable monitor

    # Enable the creation of a peerstats file
    enable stats
    statsdir /var/log/ntpstats
    filegen peerstats file peerstats type day link enable

    # Test only.
    ttl 127 88
    broadcastdelay 0.01
"""
    conffile = StringIO.StringIO(test_data)
    parser = config_file.NtpdParser()
    results = list(parser.Parse(None, conffile, None))

    # We expect some results.
    self.assertTrue(results)
    # There should be only one result.
    self.assertEqual(1, len(results))
    # Now that we are sure, just use that single result for easy of reading.
    results = results[0]

    # Check all the expected "simple" config keywords are present.
    expected_config_keywords = set(
        ["driftfile", "statsdir", "filegen", "ttl",
         "broadcastdelay"]) | set(parser._defaults.keys())
    self.assertEqual(expected_config_keywords, set(results.config.keys()))

    # Check all the expected "keyed" config keywords are present.
    self.assertTrue(results.server)
    self.assertTrue(results.restrict)
    # And check one that isn't in the config, isn't in out result.
    self.assertFalse(results.trap)

    # Check we got all the "servers".
    servers = ["1.2.3.4", "4.5.6.7", "8.9.10.11", "pool.ntp.org",
               "2001:1234:1234:2::f"]
    self.assertItemsEqual(servers, [r.address for r in results.server])
    # In our test data, they all have "iburst" as an arg. Check that is found.
    for r in results.server:
      self.assertEqual("iburst", r.options)

    # Check a few values were parsed correctly.
    self.assertEqual("/var/lib/ntp/ntp.drift", results.config["driftfile"])
    self.assertEqual("/var/log/ntpstats", results.config["statsdir"])
    self.assertEqual("peerstats file peerstats type day link enable",
                     results.config["filegen"])
    self.assertEqual(1, len(results.restrict))
    self.assertEqual("default", results.restrict[0].address)
    self.assertEqual("nomodify noquery nopeer", results.restrict[0].options)
    # A option that can have a list of integers.
    self.assertEqual([127, 88], results.config["ttl"])
    # An option that should only have a single float.
    self.assertEqual([0.01], results.config["broadcastdelay"])

    # Check the modified defaults.
    self.assertFalse(results.config["monitor"])
    self.assertTrue(results.config["stats"])

    # Check an unlisted defaults are unmodified.
    self.assertFalse(results.config["kernel"])
    self.assertTrue(results.config["auth"])