Exemplo n.º 1
0
  def testSystemAccountAnomaly(self):
    passwd = [
        "root:x:0:0::/root:/bin/sash",
        "miss:x:1000:100:Missing:/home/miss:/bin/bash",
        "bad1:x:0:1001:Bad 1:/home/bad1:/bin/bash",
        "bad2:x:1002:0:Bad 2:/home/bad2:/bin/bash"
    ]
    shadow = [
        "root:{UNSET}:16000:0:99999:7:::", "ok:{SHA512}:16000:0:99999:7:::",
        "bad1::16333:0:99999:7:::", "bad2:{DES}:16333:0:99999:7:::"
    ]
    group = [
        "root:x:0:root", "miss:x:1000:miss", "bad1:x:1001:bad1",
        "bad2:x:1002:bad2"
    ]
    gshadow = ["root:::root", "miss:::miss", "bad1:::bad1", "bad2:::bad2"]
    stats, files = self._GenFiles(passwd, shadow, group, gshadow)

    no_grp = {
        "symptom": "Accounts with invalid gid.",
        "finding": ["gid 100 assigned without /etc/groups entry: miss"],
        "type": "PARSER_ANOMALY"
    }
    uid = {
        "symptom": "Accounts with shared uid.",
        "finding": ["uid 0 assigned to multiple accounts: bad1,root"],
        "type": "PARSER_ANOMALY"
    }
    gid = {
        "symptom": "Privileged group with unusual members.",
        "finding": ["Accounts in 'root' group: bad2"],
        "type": "PARSER_ANOMALY"
    }
    no_match = {
        "symptom":
            "Mismatched passwd and shadow files.",
        "finding": [
            "Present in passwd, missing in shadow: miss",
            "Present in shadow, missing in passwd: ok"
        ],
        "type":
            "PARSER_ANOMALY"
    }
    expected = [
        rdf_anomaly.Anomaly(**no_grp), rdf_anomaly.Anomaly(**uid),
        rdf_anomaly.Anomaly(**gid), rdf_anomaly.Anomaly(**no_match)
    ]

    parser = linux_file_parser.LinuxSystemPasswdParser()
    rdfs = parser.ParseMultiple(stats, files, None)
    results = [r for r in rdfs if isinstance(r, rdf_anomaly.Anomaly)]

    self.assertEqual(len(expected), len(results))
    for expect, result in zip(expected, results):
      self.assertEqual(expect.symptom, result.symptom)
      # Expand out repeated field helper.
      self.assertItemsEqual(list(expect.finding), list(result.finding))
      self.assertEqual(expect.type, result.type)
Exemplo n.º 2
0
 def CheckCryptResults(self, passwd, shadow, group, gshadow, algo, usr, grp):
   stats, files = self._GenFiles(passwd, shadow, group, gshadow)
   parser = linux_file_parser.LinuxSystemPasswdParser()
   results = list(parser.ParseMultiple(stats, files, None))
   usrs = [r for r in results if isinstance(r, rdfvalue.KnowledgeBaseUser)]
   grps = [r for r in results if isinstance(r, rdfvalue.Group)]
   self.assertEqual(1, len(usrs), "Different number of usr %s results" % algo)
   self.assertEqual(1, len(grps), "Different number of grp %s results" % algo)
   self.CheckExpectedUser(algo, usr, usrs[0])
   self.CheckExpectedGroup(algo, grp, grps[0])
Exemplo n.º 3
0
 def _GenResults(self):
     host_data = self.SetKnowledgeBase()
     login = {
         "/etc/passwd":
         """
         nopasswd:x:1000:1000::/home/nopasswd:/bin/bash
         md5:x:1001:1001::/home/md5:/bin/bash
         undying:x:1002:1002::/home/undying:/bin/bash
         disabled:x:1003:1003::/home/disabled:/bin/bash
         +nisuser:acr.7pt3dpA5s::::::/bin/zsh""",
         "/etc/shadow":
         """
         nopasswd::16000:0:365:7:::
         md5:$1$rootrootrootrootrootro:16000::::::
         undying:$6$saltsalt${0}:16000:0:99999:7:::
         disabled:!:16000:0:99999:7:::""".format("r" * 86),
         "/etc/group":
         """
         nopasswd:x:1000:nopasswd
         +:::
         md5:x:1001:md5
         undying:x:1002:undying
         disabled:x:1003:disabled""",
         "/etc/gshadow":
         """
         nopasswd:::nopasswd
         md5:::md5
         undying:::undying
         disabled:::disabled"""
     }
     perms = {
         "/etc/passwd": (0, 0, 0o100666),  # Anomalous write perm.
         "/etc/group": (1, 0, 0o100644),  # Anomalous owner.
         "/etc/shadow": (0, 0, 0o100444),  # Anomalous read perm.
         "/etc/gshadow": (0, 1, 0o100400)
     }  # Anomalous group.
     stats = []
     files = []
     for path, lines in login.items():
         p = rdf_paths.PathSpec(path=path, pathtype="OS")
         st_uid, st_gid, st_mode = perms.get(path)
         stats.append(
             rdf_client.StatEntry(pathspec=p,
                                  st_uid=st_uid,
                                  st_gid=st_gid,
                                  st_mode=st_mode))
         files.append(StringIO.StringIO(lines))
     parser = linux_file_parser.LinuxSystemPasswdParser()
     rdfs = list(parser.ParseMultiple(stats, files, None))
     host_data["LoginPolicyConfiguration"] = self.SetArtifactData(
         anomaly=[a for a in rdfs if isinstance(a, rdf_anomaly.Anomaly)],
         parsed=[r for r in rdfs if not isinstance(r, rdf_anomaly.Anomaly)],
         raw=stats)
     return self.RunChecks(host_data)
Exemplo n.º 4
0
 def testNoAnomaliesWhenEverythingIsFine(self):
   passwd = ["ok_1:x:1000:1000::/home/ok_1:/bin/bash",
             "ok_2:x:1001:1001::/home/ok_2:/bin/bash"]
   shadow = ["ok_1:{SHA256}:16000:0:99999:7:::",
             "ok_2:{SHA512}:16000:0:99999:7:::"]
   group = ["ok_1:x:1000:ok_1", "ok_2:x:1001:ok_2"]
   gshadow = ["ok_1:::ok_1", "ok_2:::ok_2"]
   stats, files = self._GenFiles(passwd, shadow, group, gshadow)
   parser = linux_file_parser.LinuxSystemPasswdParser()
   rdfs = parser.ParseMultiple(stats, files, None)
   results = [r for r in rdfs if isinstance(r, rdfvalue.Anomaly)]
   self.assertFalse(results)
Exemplo n.º 5
0
 def _GenResults(self):
     parser = linux_file_parser.LinuxSystemPasswdParser()
     if self.results is None:
         host_data = self.SetKnowledgeBase()
         login = {
             "/etc/passwd":
             """
           nopasswd:x:1000:1000::/home/nopasswd:/bin/bash
           md5:x:1001:1001::/home/md5:/bin/bash
           undying:x:1002:1002::/home/undying:/bin/bash
           disabled:x:1003:1003::/home/disabled:/bin/bash
           +nisuser:acr.7pt3dpA5s::::::/bin/zsh""",
             "/etc/shadow":
             """
           nopasswd::16000:0:365:7:::
           md5:$1$rootrootrootrootrootro:16000:0:365:7:::
           undying:$6$saltsalt${0}:16000:0:99999:7:::
           disabled:!:16000:0:99999:7:::""".format("r" * 86),
             "/etc/group":
             """
           nopasswd:x:1000:nopasswd
           +:::
           md5:x:1001:md5
           undying:x:1002:undying
           disabled:x:1003:disabled""",
             "/etc/gshadow":
             """
           nopasswd:::nopasswd
           md5:::md5
           undying:::undying
           disabled:::disabled"""
         }
         modes = {
             "/etc/passwd": {
                 "st_mode": 0o100666
             },  # Bad write perm.
             "/etc/group": {
                 "st_uid": 1
             },  # Bad owner.
             "/etc/shadow": {
                 "st_mode": 0o100444
             },  # Bad read perm.
             "/etc/gshadow": {
                 "st_gid": 1,
                 "st_mode": 0o100400
             }
         }  # Bad group.
         host_data = self.GenFileData("LoginPolicyConfiguration", login,
                                      parser, modes)
         return self.RunChecks(host_data)
Exemplo n.º 6
0
 def _GenResults(self):
     if self.results is None:
         host_data = self.SetKnowledgeBase()
         login = {
             "/etc/passwd":
             """
           nopasswd:x:1000:1000::/home/nopasswd:/bin/bash
           md5:x:1001:1001::/home/md5:/bin/bash
           undying:x:1002:1002::/home/undying:/bin/bash
           +nisuser:acr.7pt3dpA5s::::::/bin/zsh""",
             "/etc/shadow":
             """
           nopasswd::16000:0:365:7:::
           md5:$1$rootrootrootrootrootro:16000:0:365:7:::
           undying:$6$saltsalt${0}:16000:0:99999:7:::""".format("r" * 86),
             "/etc/group":
             """
           nopasswd:x:1000:nopasswd
           +:::
           md5:x:1001:md5
           undying:x:1002:undying""",
             "/etc/gshadow":
             """
           nopasswd:::nopasswd
           md5:::md5
           undying:::undying"""
         }
         stats = []
         files = []
         for path, lines in login.items():
             p = rdfvalue.PathSpec(path=path)
             stats.append(rdfvalue.StatEntry(pathspec=p))
             files.append(StringIO.StringIO(lines))
         parser = linux_file_parser.LinuxSystemPasswdParser()
         rdfs = list(parser.ParseMultiple(stats, files, None))
         host_data["LoginPolicyConfiguration"] = rdfs
         return self.RunChecks(host_data)