Example #1
0
inline void updateAuditRow(const AuditEventContextRef& ec, Row& r) {
  const auto& fields = ec->fields;
  if (ec->type == AUDIT_SYSCALL) {
    r["pid"] = (fields.count("pid")) ? fields.at("pid") : "0";
    r["parent"] = fields.count("ppid") ? fields.at("ppid") : "0";
    r["uid"] = fields.count("uid") ? fields.at("uid") : "0";
    r["euid"] = fields.count("euid") ? fields.at("euid") : "0";
    r["gid"] = fields.count("gid") ? fields.at("gid") : "0";
    r["egid"] = fields.count("egid") ? fields.at("euid") : "0";
    r["path"] = (fields.count("exe")) ? decodeAuditValue(fields.at("exe")) : "";

    // This should get overwritten during the EXECVE state.
    r["cmdline"] = (fields.count("comm")) ? fields.at("comm") : "";
    // Do not record a cmdline size. If the final state is reached and no 'argc'
    // has been filled in then the EXECVE state was not used.
    r["cmdline_size"] = "";

    r["overflows"] = "";
    r["env_size"] = "0";
    r["env_count"] = "0";
    r["env"] = "";
  }

  if (ec->type == AUDIT_EXECVE) {
    // Reset the temporary storage from the SYSCALL state.
    r["cmdline"] = "";
    for (const auto& arg : fields) {
      if (arg.first == "argc") {
        continue;
      }

      // Amalgamate all the "arg*" fields.
      if (r.at("cmdline").size() > 0) {
        r["cmdline"] += " ";
      }
      r["cmdline"] += decodeAuditValue(arg.second);
    }

    // There may be a better way to calculate actual size from audit.
    // Then an overflow could be calculated/determined based on actual/expected.
    r["cmdline_size"] = std::to_string(r.at("cmdline").size());
  }

  if (ec->type == AUDIT_PATH) {
    r["mode"] = (fields.count("mode")) ? fields.at("mode") : "";
    r["owner_uid"] = fields.count("ouid") ? fields.at("ouid") : "0";
    r["owner_gid"] = fields.count("ogid") ? fields.at("ogid") : "0";

    auto qd = SQL::selectAllFrom("file", "path", EQUALS, r.at("path"));
    if (qd.size() == 1) {
      r["ctime"] = qd.front().at("ctime");
      r["atime"] = qd.front().at("atime");
      r["mtime"] = qd.front().at("mtime");
      r["btime"] = "0";
    }

    // Uptime is helpful for execution-based events.
    r["uptime"] = std::to_string(tables::getUptime());
  }
}
Example #2
0
TEST_F(AuditTests, test_audit_value_decode) {
  // In the normal case the decoding only removes '"' characters from the ends.
  auto decoded_normal = decodeAuditValue("\"/bin/ls\"");
  EXPECT_EQ(decoded_normal, "/bin/ls");

  // If the first char is not '"', the value is expected to be hex-encoded.
  auto decoded_hex = decodeAuditValue("736C6565702031");
  EXPECT_EQ(decoded_hex, "sleep 1");

  // When the hex fails to decode the input value is returned as the result.
  auto decoded_fail = decodeAuditValue("7");
  EXPECT_EQ(decoded_fail, "7");
}
Example #3
0
Status ProcessEventSubscriber::Callback(const ECRef& ec, const SCRef& sc) {
  // Check and set the valid state change.
  // If this is an unacceptable change reset the state and clear row data.
  if (ec->fields.count("success") && ec->fields.at("success") == "no") {
    return Status(0, "OK");
  }

  if (!validAuditState(ec->type, state_).ok()) {
    state_ = STATE_SYSCALL;
    Row().swap(row_);
    return Status(0, "OK");
  }

  // Fill in row fields based on the event state.
  updateAuditRow(ec, row_);

  // Only add the event if finished (aka a PATH event was emitted).
  if (state_ == STATE_SYSCALL) {
    // If the EXECVE state was not used, decode the cmdline value.
    if (row_.at("cmdline_size").size() == 0) {
      // This allows at most 1 decode call per potentially-encoded item.
      row_["cmdline"] = decodeAuditValue(row_.at("cmdline"));
      row_["cmdline_size"] = "1";
    }

    add(row_, getUnixTime());
    Row().swap(row_);
  }

  return Status(0, "OK");
}
Example #4
0
bool SocketUpdate(size_t type, const AuditFields& fields, AuditFields& r) {
  if (type == AUDIT_TYPE_SOCKADDR) {
    const auto& saddr = fields.at("saddr");
    if (saddr.size() < 4 || saddr[0] == '1') {
      return false;
    }

    r["protocol"] = '0';
    r["local_port"] = '0';
    r["remote_port"] = '0';
    // Parse the struct and emit the row.
    if (!parseSockAddr(saddr, r)) {
      return false;
    }
    return true;
  }

  r["auid"] = fields.at("auid");
  r["pid"] = fields.at("pid");
  r["path"] = decodeAuditValue(fields.at("exe"));
  // TODO: This is a hex value.
  r["fd"] = fields.at("a0");
  // The open/bind success status.
  r["success"] = (fields.at("success") == "yes") ? "1" : "0";
  r["uptime"] = std::to_string(tables::getUptime());
  return true;
}