예제 #1
0
QueryData genChromeBasedExtensions(QueryContext& context,
                                   const fs::path& sub_dir) {
  QueryData results;

  auto users = usersFromContext(context);
  for (const auto& row : users) {
    if (row.count("uid") > 0 && row.count("directory") > 0) {
      // For each user, enumerate all of their chrome profiles.
      std::vector<std::string> profiles;
      fs::path extension_path = row.at("directory") / sub_dir;
      if (!resolveFilePattern(extension_path, profiles, GLOB_FOLDERS).ok()) {
        continue;
      }

      // For each profile list each extension in the Extensions directory.
      std::vector<std::string> extensions;
      for (const auto& profile : profiles) {
        listDirectoriesInDirectory(profile, extensions);
      }

      // Generate an addons list from their extensions JSON.
      std::vector<std::string> versions;
      for (const auto& extension : extensions) {
        listDirectoriesInDirectory(extension, versions);
      }

      // Extensions use /<EXTENSION>/<VERSION>/manifest.json.
      for (const auto& version : versions) {
        genExtension(row.at("uid"), version, results);
      }
    }
  }

  return results;
}
예제 #2
0
QueryData genBrowserPlugins(QueryContext& context) {
  QueryData results;
  std::vector<std::string> bundles;

  // The caller is not requesting a JOIN against users.
  // This is "special" logic for user data-based tables since there is a concept
  // of system-available browser extensions.
  if (context.constraints["uid"].notExistsOrMatches("0")) {
    std::vector<std::string> bundles;
    if (listDirectoriesInDirectory(kBrowserPluginsPath, bundles).ok()) {
      for (const auto& dir : bundles) {
        genBrowserPlugin("0", dir, results);
      }
    }
  }

  // Iterate over each user
  auto users = usersFromContext(context);
  for (const auto& row : users) {
    if (row.count("uid") > 0 && row.count("directory") > 0) {
      std::vector<std::string> bundles;
      auto dir = fs::path(row.at("directory")) / kBrowserPluginsPath;
      if (listDirectoriesInDirectory(dir, bundles).ok()) {
        for (const auto& dir : bundles) {
          genBrowserPlugin(row.at("uid"), dir, results);
        }
      }
    }
  }

  return results;
}
예제 #3
0
QueryData genChromeBasedExtensions(QueryContext& context, const fs::path sub_dir) {
  QueryData results;

  auto homes = osquery::getHomeDirectories();
  for (const auto& home : homes) {
    // For each user, enumerate all of their chrome profiles.
    std::vector<std::string> profiles;
    fs::path extension_path = home / sub_dir;
    if (!resolveFilePattern(extension_path, profiles, REC_LIST_FOLDERS).ok()) {
      continue;
    }

    // For each profile list each extension in the Extensions directory.
    std::vector<std::string> extensions;
    for (const auto& profile : profiles) {
      listDirectoriesInDirectory(profile, extensions);
    }

    // Generate an addons list from their extensions JSON.
    std::vector<std::string> versions;
    for (const auto& extension : extensions) {
      listDirectoriesInDirectory(extension, versions);
    }

    // Extensions use /<EXTENSION>/<VERSION>/manifest.json.
    for (const auto& version : versions) {
      genExtension(version, results);
    }
  }

  return results;
}
예제 #4
0
bool INotifyEventPublisher::addMonitor(const std::string& path,
                                       bool recursive) {
  if (!isPathMonitored(path)) {
    int watch = ::inotify_add_watch(getHandle(), path.c_str(), IN_ALL_EVENTS);
    if (watch == -1) {
      LOG(ERROR) << "Could not add inotfy watch on: " << path;
      return false;
    }

    // Keep a list of the watch descriptors
    descriptors_.push_back(watch);
    // Keep a map of the path -> watch descriptor
    path_descriptors_[path] = watch;
    // Keep a map of the opposite (descriptor -> path)
    descriptor_paths_[watch] = path;
  }

  if (recursive && isDirectory(path).ok()) {
    std::vector<std::string> children;
    // Get a list of children of this directory (requesed recursive watches).
    listDirectoriesInDirectory(path, children);

    for (const auto& child : children) {
      addMonitor(child, recursive);
    }
  }

  return true;
}
예제 #5
0
파일: inotify.cpp 프로젝트: tburgin/osquery
bool INotifyEventPublisher::addMonitor(const std::string& path,
                                       uint32_t mask,
                                       bool recursive,
                                       bool add_watch) {
    if (!isPathMonitored(path)) {
        int watch = ::inotify_add_watch(
                        getHandle(), path.c_str(), ((mask == 0) ? kFileDefaultMasks : mask));
        if (add_watch && watch == -1) {
            LOG(WARNING) << "Could not add inotify watch on: " << path;
            return false;
        }

        // Keep a list of the watch descriptors
        descriptors_.push_back(watch);
        // Keep a map of the path -> watch descriptor
        path_descriptors_[path] = watch;
        // Keep a map of the opposite (descriptor -> path)
        descriptor_paths_[watch] = path;
    }

    if (recursive && isDirectory(path).ok()) {
        std::vector<std::string> children;
        // Get a list of children of this directory (requested recursive watches).
        listDirectoriesInDirectory(path, children, true);

        boost::system::error_code ec;
        for (const auto& child : children) {
            auto canonicalized = fs::canonical(child, ec).string() + '/';
            addMonitor(canonicalized, mask, false);
        }
    }

    return true;
}
예제 #6
0
QueryData genMemoryMap(QueryContext& context) {
  QueryData results;

  // Linux memory map is exposed in /sys.
  std::vector<std::string> regions;
  auto status = listDirectoriesInDirectory(kMemoryMapLocation, regions);
  if (!status.ok()) {
    return {};
  }

  for (const auto& index : regions) {
    fs::path index_path(index);
    Row r;
    r["region"] = index_path.filename().string();

    // The type is a textual description
    std::string content;
    readFile(index_path / "type", content);
    boost::trim(content);
    r["type"] = content;

    // Keep these in 0xFFFF (hex) form.
    readFile(index_path / "start", content);
    boost::trim(content);
    r["start"] = content;

    readFile(index_path / "end", content);
    boost::trim(content);
    r["end"] = content;

    results.push_back(r);
  }

  return results;
}
예제 #7
0
QueryData genScheduledTasks(QueryContext& context) {
  QueryData results;

  // First process all tasks in the root folder
  enumerateTasksForFolder("\\", results);

  // We attempt to derive the location of the tasks folder
  auto sysRoot = getEnvVar("SystemRoot");
  if (!sysRoot.is_initialized()) {
    return results;
  }
  auto sysTaskPath = *sysRoot + "\\System32\\Tasks";

  // Then process all tasks in subsequent folders
  std::vector<std::string> taskPaths;
  listDirectoriesInDirectory(sysTaskPath, taskPaths, true);
  for (const auto& path : taskPaths) {
    if (sysTaskPath.size() >= path.size()) {
      VLOG(1) << "Invalid task path " << path;
      continue;
    }
    auto taskPath =
        "\\" + join(split(path.substr(sysTaskPath.size(),
                                      (path.size() - sysTaskPath.size())),
                          "\\"),
                    "\\");
    enumerateTasksForFolder(taskPath, results);
  }

  return results;
}
예제 #8
0
void genSiteDirectories(const std::string& site, QueryData& results) {
  std::vector<std::string> directories;
  if (!listDirectoriesInDirectory(site, directories, true).ok()) {
    return;
  }

  for (const auto& directory : directories) {
    if (!isDirectory(directory).ok()) {
      continue;
    }

    Row r;
    if (directory.find(".dist-info") != std::string::npos) {
      auto path = directory + "/METADATA";
      genPackage(path, r);
    } else if (directory.find(".egg-info") != std::string::npos) {
      auto path = directory + "/PKG-INFO";
      genPackage(path, r);
    } else {
      continue;
    }

    r["directory"] = site;
    r["path"] = directory;
    results.push_back(r);
  }
}
예제 #9
0
QueryData genBrowserPlugins(QueryContext& context) {
  QueryData results;
  std::vector<std::string> bundles;

  // Lambda to walk through each browser plugin and process the plist file.
  auto enum_browser_plugins = [&results](const fs::path& path,
                                         const std::string& uid) {
    std::vector<std::string> bundles;
    if (listDirectoriesInDirectory(path, bundles).ok()) {
      for (const auto& dir : bundles) {
        genBrowserPlugin(uid, dir, results, false);
      }
    }

    // Check if the plugin is the 'Disabled' folder.
    std::vector<std::string> disabled_bundles;
    auto dis_path = path / "Disabled Plug-Ins";
    if (listDirectoriesInDirectory(dis_path, disabled_bundles).ok()) {
      for (const auto& disabled_dir : disabled_bundles) {
        genBrowserPlugin(uid, disabled_dir, results, true);
      }
    }
  };

  // The caller is not requesting a JOIN against users. This is "special" logic
  // for user data-based tables since there is a concept of system-available
  // browser extensions.
  if (context.constraints["uid"].notExistsOrMatches("0")) {
    enum_browser_plugins(kBrowserPluginsPath, "0");
  }

  // Iterate over each user
  auto users = usersFromContext(context);
  for (const auto& row : users) {
    if (row.count("uid") > 0 && row.count("directory") > 0) {
      auto dir = fs::path(row.at("directory")) / kBrowserPluginsPath;
      enum_browser_plugins(dir, row.at("uid"));
    }
  }
  return results;
}
예제 #10
0
QueryData genBrowserPlugins(QueryContext& context) {
  QueryData results;

  std::vector<std::string> bundles;
  if (listDirectoriesInDirectory(kBrowserPluginsPath, bundles).ok()) {
    for (const auto& dir : bundles) {
      genBrowserPlugin(dir, results);
    }
  }

  auto homes = osquery::getHomeDirectories();
  for (const auto& home : homes) {
    bundles.clear();
    if (listDirectoriesInDirectory(home / kBrowserPluginsPath, bundles).ok()) {
      for (const auto& dir : bundles) {
        genBrowserPlugin(dir, results);
      }
    }
  }

  return results;
}
예제 #11
0
void genAllControls(QueryData& results,
                    const std::map<std::string, std::string>& config,
                    const std::string& subsystem) {
  // Linux sysctl subsystems are directories in /proc
  std::vector<std::string> subsystems;
  if (!listDirectoriesInDirectory("/proc/sys", subsystems).ok()) {
    return;
  }

  for (const auto& sub : subsystems) {
    if (subsystem.size() != 0 && fs::path(sub).filename().string() != subsystem) {
      // Request is limiting subsystem.
      continue;
    } 
    genControlInfo(sub, results, config);
  }
}
예제 #12
0
QueryData genPythonPackages(QueryContext& context) {
  QueryData results;
  std::set<std::string> paths;
  if (context.constraints.count("directory") > 0 &&
      context.constraints.at("directory").exists(EQUALS)) {
    paths = context.constraints["directory"].getAll(EQUALS);
  } else {
    paths = kPythonPath;
  }
  for (const auto& key : paths) {
    genSiteDirectories(key, results);
  }

  if (isPlatform(PlatformType::TYPE_OSX)) {
    for (const auto& dir : kDarwinPythonPath) {
      std::vector<std::string> versions;
      if (!listDirectoriesInDirectory(dir, versions, false).ok()) {
        continue;
      }

      for (const auto& version : versions) {
        // macOS will link older versions to 2.6.
        auto version_path = fs::path(version).parent_path();
        if (fs::is_symlink(symlink_status(version_path))) {
          continue;
        }

        auto complete = version + "lib/python" +
                        version_path.filename().string() + "/site-packages/";
        genSiteDirectories(complete, results);
      }
    }
  } else if (isPlatform(PlatformType::TYPE_WINDOWS)) {
    // Enumerate any system installed python packages
    auto installPathKey = "HKEY_LOCAL_MACHINE\\" + kWinPythonInstallKey;
    genWinPythonPackages(installPathKey, results);

    // Enumerate any user installed python packages
    installPathKey = "HKEY_USERS\\%\\" + kWinPythonInstallKey;
    genWinPythonPackages(installPathKey, results);
  }

  return results;
}
예제 #13
0
QueryData genFirefoxAddons(QueryContext& context) {
  QueryData results;

  auto homes = osquery::getHomeDirectories();
  for (const auto& home : homes) {
    // For each user, enumerate all of their Firefox profiles.
    std::vector<std::string> profiles;
    if (!listDirectoriesInDirectory(home / kFirefoxPath, profiles).ok()) {
      continue;
    }

    // Generate an addons list from their extensions JSON.
    for (const auto& profile : profiles) {
      genFirefoxAddonsFromExtensions(profile, results);
    }
  }

  return results;
}
예제 #14
0
void genControlInfo(const std::string& mib_path,
                    QueryData& results,
                    const std::map<std::string, std::string>& config) {
  if (isDirectory(mib_path).ok()) {
    // Iterate through the subitems and items.
    std::vector<std::string> items;
    if (listDirectoriesInDirectory(mib_path, items).ok()) {
      for (const auto& item : items) {
        genControlInfo(item, results, config);
      }
    }

    if (listFilesInDirectory(mib_path, items).ok()) {
      for (const auto& item : items) {
        genControlInfo(item, results, config);
      }
    }
    return;
  }

  // This is a file (leaf-control).
  Row r;
  r["name"] = mib_path.substr(kSystemControlPath.size());

  std::replace(r["name"].begin(), r["name"].end(), '/', '.');
  // No known way to convert name MIB to int array.
  r["subsystem"] = osquery::split(r.at("name"), ".")[0];

  if (isReadable(mib_path).ok()) {
    std::string content;
    readFile(mib_path, content);
    boost::trim(content);
    r["current_value"] = content;
  }

  if (config.count(r.at("name")) > 0) {
    r["config_value"] = config.at(r.at("name"));
  }
  r["type"] = "string";
  results.push_back(r);
}
예제 #15
0
QueryData genFirefoxAddons(QueryContext& context) {
  QueryData results;

  // Iterate over each user
  QueryData users = usersFromContext(context);
  for (const auto& row : users) {
    if (row.count("uid") > 0 && row.count("directory") > 0) {
      // For each user, enumerate all of their Firefox profiles.
      std::vector<std::string> profiles;
      auto directory = fs::path(row.at("directory")) / kFirefoxPath;
      if (!listDirectoriesInDirectory(directory, profiles).ok()) {
        continue;
      }

      // Generate an addons list from their extensions JSON.
      for (const auto& profile : profiles) {
        genFirefoxAddonsFromExtensions(row.at("uid"), profile, results);
      }
    }
  }

  return results;
}