示例#1
0
QueryData genRpmPackages(QueryContext& context) {
  QueryData results;

  auto dropper = DropPrivileges::get();
  if (!dropper->dropTo("nobody") && isUserAdmin()) {
    LOG(WARNING) << "Cannot drop privileges for rpm_packages";
    return results;
  }

  // Isolate RPM/package inspection to the canonical: /usr/lib/rpm.
  RpmEnvironmentManager env_manager;

  // The following implementation uses http://rpm.org/api/4.11.1/
  rpmInitCrypto();
  if (rpmReadConfigFiles(nullptr, nullptr) != 0) {
    TLOG << "Cannot read RPM configuration files";
    return results;
  }

  rpmts ts = rpmtsCreate();
  rpmdbMatchIterator matches;
  if (context.constraints["name"].exists(EQUALS)) {
    auto name = (*context.constraints["name"].getAll(EQUALS).begin());
    matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size());
  } else {
    matches = rpmtsInitIterator(ts, RPMTAG_NAME, nullptr, 0);
  }

  Header header;
  while ((header = rpmdbNextIterator(matches)) != nullptr) {
    Row r;
    rpmtd td = rpmtdNew();
    r["name"] = getRpmAttribute(header, RPMTAG_NAME, td);
    r["version"] = getRpmAttribute(header, RPMTAG_VERSION, td);
    r["release"] = getRpmAttribute(header, RPMTAG_RELEASE, td);
    r["source"] = getRpmAttribute(header, RPMTAG_SOURCERPM, td);
    r["size"] = getRpmAttribute(header, RPMTAG_SIZE, td);
    r["sha1"] = getRpmAttribute(header, RPMTAG_SHA1HEADER, td);
    r["arch"] = getRpmAttribute(header, RPMTAG_ARCH, td);

    rpmtdFree(td);
    results.push_back(r);
  }

  rpmdbFreeIterator(matches);
  rpmtsFree(ts);
  rpmFreeCrypto();
  rpmFreeRpmrc();

  return results;
}
示例#2
0
QueryData genOSXDefaultPreferences(QueryContext& context) {
  QueryData results;

  CFStringRef username = nullptr;
  if (context.constraints["username"].exists(EQUALS)) {
    auto users = context.constraints["username"].getAll(EQUALS);
    username = CFStringCreateWithCString(
        kCFAllocatorDefault, (*users.begin()).c_str(), kCFStringEncodingUTF8);
  }

  const auto* user = (username != nullptr)
                         ? &username
                         : (isUserAdmin()) ? &kCFPreferencesAnyUser
                                           : &kCFPreferencesCurrentUser;

  // Need lambda to iterate the map.
  auto preferencesIterator =
      ([&results, &username](CFMutableArrayRef& am, bool current_host) {
        for (CFIndex i = 0; i < CFArrayGetCount(am); ++i) {
          auto domain = static_cast<CFStringRef>(CFArrayGetValueAtIndex(am, i));
          genOSXDomainPrefs(username, domain, current_host, results);
        }
      });

  CFMutableArrayRef app_map = nullptr;
  if (context.constraints["domain"].exists(EQUALS)) {
    // If a specific domain is requested, speed up the set of type conversions.
    auto domains = context.constraints["domain"].getAll(EQUALS);
    app_map = CFArrayCreateMutable(
        kCFAllocatorDefault, domains.size(), &kCFTypeArrayCallBacks);
    for (const auto& domain : domains) {
      auto cf_domain = CFStringCreateWithCString(
          kCFAllocatorDefault, domain.c_str(), kCFStringEncodingASCII);
      CFArrayAppendValue(app_map, cf_domain);
      CFRelease(cf_domain);
    }

    // Iterate over each preference domain (applicationID).
    preferencesIterator(app_map, true);
    preferencesIterator(app_map, false);
    CFRelease(app_map);
  } else {
    // Listing ALL application preferences is deprecated.
    OSQUERY_USE_DEPRECATED(
        app_map = (CFMutableArrayRef)CFPreferencesCopyApplicationList(
            *user, kCFPreferencesCurrentHost));
    if (app_map != nullptr) {
      // Iterate over each preference domain (applicationID).
      preferencesIterator(app_map, true);
      CFRelease(app_map);
    }

    // Again for 'any' host.
    OSQUERY_USE_DEPRECATED(
        app_map = (CFMutableArrayRef)CFPreferencesCopyApplicationList(
            *user, kCFPreferencesAnyHost));
    if (app_map != nullptr) {
      // Iterate over each preference domain (applicationID).
      preferencesIterator(app_map, false);
      CFRelease(app_map);
    }
  }

  if (username != nullptr) {
    CFRelease(username);
  }

  return results;
}
示例#3
0
void genOSXDomainPrefs(const CFStringRef& username,
                       const CFStringRef& domain,
                       bool current_host,
                       QueryData& results) {
  const auto* user = (username != nullptr)
                         ? &username
                         : (isUserAdmin()) ? &kCFPreferencesAnyUser
                                           : &kCFPreferencesCurrentUser;
  const auto* host =
      (current_host) ? &kCFPreferencesCurrentHost : &kCFPreferencesAnyHost;
  auto keys = CFPreferencesCopyKeyList(domain, *user, *host);
  if (keys == nullptr) {
    return;
  }

  auto values = CFPreferencesCopyMultiple(keys, domain, *user, *host);
  if (values == nullptr) {
    CFRelease(keys);
    return;
  }

  std::string username_string;
  if (username != nullptr) {
    username_string = stringFromCFString(username);
  }

  // Iterate over each preference domain's preference name.
  for (CFIndex j = 0; j < CFArrayGetCount(keys); ++j) {
    Row r;

    r["username"] = username_string;
    r["host"] = (current_host) ? "current" : "any";
    r["domain"] = stringFromCFString(domain);
    auto key = static_cast<CFStringRef>(CFArrayGetValueAtIndex(keys, j));
    if (CFStringGetTypeID() != CFGetTypeID(key)) {
      continue;
    }

    // Interesting results/behavior from Microsoft products.
    r["key"] = stringFromCFString(key);
    if (r.at("key").find('>') != std::string::npos ||
        r.at("key").find('<') != std::string::npos || r.at("key").size() == 0) {
      continue;
    }

    // Check if the preference key is managed by a profile.
    auto forced = CFPreferencesAppValueIsForced(key, domain);
    r["forced"] = (forced) ? '1' : '0';

    CFTypeRef value = nullptr;
    if (forced) {
      value = static_cast<CFTypeRef>(CFPreferencesCopyAppValue(key, domain));
    } else {
      // Check the key and key type (which may be any CF type).
      value = static_cast<CFTypeRef>(CFDictionaryGetValue(values, key));
    }
    genOSXPrefValues(value, r, results, 0);
    if (forced) {
      CFRelease(value);
    }
  }

  CFRelease(values);
  CFRelease(keys);
}
示例#4
0
void genRpmPackageFiles(RowYield& yield, QueryContext& context) {
  auto dropper = DropPrivileges::get();
  if (!dropper->dropTo("nobody") && isUserAdmin()) {
    LOG(WARNING) << "Cannot drop privileges for rpm_package_files";
    return;
  }

  // Isolate RPM/package inspection to the canonical: /usr/lib/rpm.
  RpmEnvironmentManager env_manager;

  if (rpmReadConfigFiles(nullptr, nullptr) != 0) {
    TLOG << "Cannot read RPM configuration files";
    return;
  }

  rpmts ts = rpmtsCreate();
  rpmdbMatchIterator matches;
  if (context.constraints["package"].exists(EQUALS)) {
    auto name = (*context.constraints["package"].getAll(EQUALS).begin());
    matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size());
  } else {
    matches = rpmtsInitIterator(ts, RPMTAG_NAME, nullptr, 0);
  }

  Header header;
  while ((header = rpmdbNextIterator(matches)) != nullptr) {
    rpmtd td = rpmtdNew();
    rpmfi fi = rpmfiNew(ts, header, RPMTAG_BASENAMES, RPMFI_NOHEADER);
    std::string package_name = getRpmAttribute(header, RPMTAG_NAME, td);

    auto file_count = rpmfiFC(fi);
    if (file_count <= 0) {
      VLOG(1) << "RPM package " << package_name << " contains 0 files";
      rpmfiFree(fi);
      continue;
    } else if (file_count > MAX_RPM_FILES) {
      VLOG(1) << "RPM package " << package_name << " contains over "
              << MAX_RPM_FILES << " files";
      rpmfiFree(fi);
      continue;
    }

    // Iterate over every file in this package.
    for (size_t i = 0; rpmfiNext(fi) >= 0 && i < file_count; i++) {
      Row r;
      auto path = rpmfiFN(fi);
      r["package"] = package_name;
      r["path"] = (path != nullptr) ? path : "";
      auto username = rpmfiFUser(fi);
      r["username"] = (username != nullptr) ? username : "";
      auto groupname = rpmfiFGroup(fi);
      r["groupname"] = (groupname != nullptr) ? groupname : "";
      r["mode"] = lsperms(rpmfiFMode(fi));
      r["size"] = BIGINT(rpmfiFSize(fi));

      int digest_algo;
      auto digest = rpmfiFDigestHex(fi, &digest_algo);
      if (digest_algo == PGPHASHALGO_SHA256) {
        r["sha256"] = (digest != nullptr) ? digest : "";
      }

      yield(r);
    }

    rpmfiFree(fi);
    rpmtdFree(td);
  }

  rpmdbFreeIterator(matches);
  rpmtsFree(ts);
  rpmFreeRpmrc();
}