mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-07 01:55:20 +00:00
[#787] Add chrome, firefox, and safari related tables
This commit is contained in:
parent
4916392aa8
commit
e281e6a214
@ -10,6 +10,9 @@ if(APPLE)
|
||||
)
|
||||
|
||||
ADD_OSQUERY_LIBRARY(FALSE osquery_tables_darwin
|
||||
applications/darwin/browser_chrome.cpp
|
||||
applications/darwin/browser_firefox.cpp
|
||||
applications/darwin/browser_safari.cpp
|
||||
events/darwin/passwd_changes.cpp
|
||||
events/darwin/file_changes.cpp
|
||||
events/darwin/hardware_events.cpp
|
||||
|
112
osquery/tables/applications/darwin/browser_chrome.cpp
Normal file
112
osquery/tables/applications/darwin/browser_chrome.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <osquery/filesystem.h>
|
||||
#include <osquery/logger.h>
|
||||
#include <osquery/tables.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
namespace osquery {
|
||||
namespace tables {
|
||||
|
||||
/// Each home directory will include custom extensions.
|
||||
#define kChromePath "/Library/Application Support/Google/Chrome/Default/"
|
||||
#define kChromeExtensionsPath "Extensions/"
|
||||
#define kChromeManifestFile "/manifest.json"
|
||||
|
||||
const std::map<std::string, std::string> kChromeExtensionKeys = {
|
||||
{"version", "version"},
|
||||
{"name", "name"},
|
||||
{"description", "description"},
|
||||
{"default_locale", "locale"},
|
||||
{"update_url", "update_url"},
|
||||
{"author", "author"},
|
||||
{"background.persistent", "persistent"},
|
||||
};
|
||||
|
||||
void genChromeExtension(const std::string& path, QueryData& results) {
|
||||
std::string json_data;
|
||||
if (!readFile(path + kChromeManifestFile, json_data).ok()) {
|
||||
VLOG(1) << "Could not read file: " << path + kChromeManifestFile;
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the extensions data into a JSON blob, then property tree.
|
||||
pt::ptree tree;
|
||||
std::stringstream json_stream;
|
||||
json_stream << json_data;
|
||||
try {
|
||||
pt::read_json(json_stream, tree);
|
||||
} catch (const pt::json_parser::json_parser_error& e) {
|
||||
VLOG(1) << "Could not parse JSON from: " << path + kChromeManifestFile;
|
||||
return;
|
||||
}
|
||||
|
||||
Row r;
|
||||
// Most of the keys are in the top-level JSON dictionary.
|
||||
for (const auto& it : kChromeExtensionKeys) {
|
||||
try {
|
||||
r[it.second] = tree.get<std::string>(it.first);
|
||||
} catch (const pt::ptree_error& e) {
|
||||
r[it.second] = "";
|
||||
}
|
||||
|
||||
// Convert JSON bool-types to an integer.
|
||||
if (r[it.second] == "true") {
|
||||
r[it.second] = INTEGER(1);
|
||||
} else if (r[it.second] == "false") {
|
||||
r[it.second] = INTEGER(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the default persistence setting to false
|
||||
if (r.at("persistent") == "") {
|
||||
r["persistent"] = INTEGER(0);
|
||||
}
|
||||
|
||||
r["identifier"] = fs::path(path).parent_path().leaf().string();
|
||||
r["path"] = path;
|
||||
results.push_back(r);
|
||||
}
|
||||
|
||||
QueryData genChromeExtensions(QueryContext& context) {
|
||||
QueryData results;
|
||||
|
||||
auto homes = osquery::getHomeDirectories();
|
||||
for (const auto& home : homes) {
|
||||
// For each user, enumerate all of their Chrome profiles.
|
||||
std::vector<std::string> extensions;
|
||||
fs::path extension_path = home / (kChromePath kChromeExtensionsPath);
|
||||
if (!listDirectoriesInDirectory(extension_path, extensions).ok()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generate an addons list from their extensions JSON.
|
||||
for (const auto& extension : extensions) {
|
||||
std::vector<std::string> versions;
|
||||
if (!listDirectoriesInDirectory(extension, versions).ok()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Extensions use /<ID>/<VERSION>/manifest.json.
|
||||
for (const auto& version : versions) {
|
||||
genChromeExtension(version, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
118
osquery/tables/applications/darwin/browser_firefox.cpp
Normal file
118
osquery/tables/applications/darwin/browser_firefox.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <osquery/filesystem.h>
|
||||
#include <osquery/logger.h>
|
||||
#include <osquery/tables.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
namespace osquery {
|
||||
namespace tables {
|
||||
|
||||
/// Each home directory will include custom extensions.
|
||||
#define kFirefoxPath "/Library/Application Support/Firefox/Profiles/"
|
||||
#define kFirefoxExtensionsFile "/extensions.json"
|
||||
|
||||
/// Not parsed, but may be helpful later.
|
||||
#define kFirefoxAddonsFile "/addons.json"
|
||||
#define kFirefoxWebappsFile "/webapps/webapps.json"
|
||||
|
||||
const std::map<std::string, std::string> kFirefoxAddonKeys = {
|
||||
{"defaultLocale.name", "name"},
|
||||
{"id", "identifier"},
|
||||
{"type", "type"},
|
||||
{"version", "version"},
|
||||
{"defaultLocale.creator", "creator"},
|
||||
{"defaultLocale.description", "description"},
|
||||
{"sourceURI", "source_url"},
|
||||
{"visible", "visible"},
|
||||
{"active", "active"},
|
||||
{"applyBackgroundUpdates", "autoupdate"},
|
||||
{"hasBinaryComponents", "native"},
|
||||
{"location", "location"},
|
||||
{"descriptor", "path"},
|
||||
};
|
||||
|
||||
void genFirefoxAddonsFromExtensions(const std::string& path,
|
||||
QueryData& results) {
|
||||
std::string json_data;
|
||||
if (!readFile(path + kFirefoxExtensionsFile, json_data).ok()) {
|
||||
VLOG(1) << "Could not read file: " << path + kFirefoxExtensionsFile;
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the extensions data into a JSON blob, then property tree.
|
||||
pt::ptree tree;
|
||||
std::stringstream json_stream;
|
||||
json_stream << json_data;
|
||||
try {
|
||||
pt::read_json(json_stream, tree);
|
||||
} catch (const pt::json_parser::json_parser_error& e) {
|
||||
VLOG(1) << "Could not parse JSON from: " << path + kFirefoxExtensionsFile;
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& addon : tree.get_child("addons")) {
|
||||
Row r;
|
||||
// Most of the keys are in the top-level JSON dictionary.
|
||||
for (const auto& it : kFirefoxAddonKeys) {
|
||||
try {
|
||||
r[it.second] = addon.second.get<std::string>(it.first);
|
||||
} catch (const pt::ptree_error& e) {
|
||||
r[it.second] = "";
|
||||
}
|
||||
|
||||
// Convert bool-types to an integer.
|
||||
if (r[it.second] == "true" || r[it.second] == "YES" ||
|
||||
r[it.first] == "Yes") {
|
||||
r[it.second] = INTEGER(1);
|
||||
} else if (r[it.second] == "false" || r[it.second] == "NO" ||
|
||||
r[it.second] == "No") {
|
||||
r[it.second] = INTEGER(0);
|
||||
}
|
||||
}
|
||||
|
||||
// There are several ways to disabled the addon, check each.
|
||||
if (addon.second.get<std::string>("softDisable", "false") == "true" ||
|
||||
addon.second.get<std::string>("appDisabled", "false") == "true" ||
|
||||
addon.second.get<std::string>("userDisabled", "false") == "true") {
|
||||
r["disabled"] = INTEGER(1);
|
||||
} else {
|
||||
r["disabled"] = INTEGER(0);
|
||||
}
|
||||
results.push_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
125
osquery/tables/applications/darwin/browser_safari.cpp
Normal file
125
osquery/tables/applications/darwin/browser_safari.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <osquery/filesystem.h>
|
||||
#include <osquery/tables.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
namespace pt = boost::property_tree;
|
||||
|
||||
namespace osquery {
|
||||
namespace tables {
|
||||
|
||||
/// Each home directory will include custom extensions.
|
||||
#define kSafariExtensionsPath "/Library/Safari/Extensions/"
|
||||
|
||||
#define kSafariPluginsPath "/Library/Internet Plug-Ins/"
|
||||
|
||||
/// Safari extensions will not load unless they have the expected pattern.
|
||||
#define kSafariExtensionsPattern "%.safariextz"
|
||||
|
||||
const std::map<std::string, std::string> kSafariPluginKeys = {
|
||||
{"WebPluginName", "name"},
|
||||
{"CFBundleIdentifier", "identifier"},
|
||||
{"CFBundleShortVersionString", "version"},
|
||||
{"DTPlatformBuild", "sdk"},
|
||||
{"WebPluginDescription", "description"},
|
||||
{"CFBundleDevelopmentRegion", "development_region"},
|
||||
{"LSRequiresNativeExecution", "native"},
|
||||
};
|
||||
|
||||
void genSafariPlugin(const std::string& path, QueryData& results) {
|
||||
Row r;
|
||||
pt::ptree tree;
|
||||
if (osquery::parsePlist(path + "/Contents/Info.plist", tree).ok()) {
|
||||
// Plugin did not include an Info.plist, or it was invalid
|
||||
for (const auto& it : kSafariPluginKeys) {
|
||||
try {
|
||||
r[it.second] = tree.get<std::string>(it.first);
|
||||
} catch (const pt::ptree_error& e) {
|
||||
r[it.second] = "";
|
||||
}
|
||||
|
||||
// Convert Plist bool-types to an integer.
|
||||
if (r[it.second] == "true" || r[it.second] == "YES" ||
|
||||
r[it.first] == "Yes") {
|
||||
r[it.second] = INTEGER(1);
|
||||
} else if (r[it.second] == "false" || r[it.second] == "NO" ||
|
||||
r[it.second] == "No") {
|
||||
r[it.second] = INTEGER(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r.at("is_native").size() == 0) {
|
||||
// The default case for native execution is false.
|
||||
r["is_native"] = "0";
|
||||
}
|
||||
|
||||
r["path"] = path;
|
||||
results.push_back(r);
|
||||
}
|
||||
|
||||
QueryData genSafariPlugins(QueryContext& context) {
|
||||
QueryData results;
|
||||
|
||||
std::vector<std::string> bundles;
|
||||
if (listDirectoriesInDirectory(kSafariPluginsPath, bundles).ok()) {
|
||||
for (const auto& dir : bundles) {
|
||||
genSafariPlugin(dir, results);
|
||||
}
|
||||
}
|
||||
|
||||
auto homes = osquery::getHomeDirectories();
|
||||
for (const auto& home : homes) {
|
||||
bundles.clear();
|
||||
if (listDirectoriesInDirectory(home / kSafariPluginsPath, bundles).ok()) {
|
||||
for (const auto& dir : bundles) {
|
||||
genSafariPlugin(dir, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
void genSafariExtension(const std::string& path, QueryData& results) {
|
||||
Row r;
|
||||
r["name"] = fs::path(path).stem().string();
|
||||
r["path"] = path;
|
||||
results.push_back(r);
|
||||
}
|
||||
|
||||
QueryData genSafariExtensions(QueryContext& context) {
|
||||
QueryData results;
|
||||
|
||||
auto homes = osquery::getHomeDirectories();
|
||||
for (const auto& home : homes) {
|
||||
auto dir = home / kSafariExtensionsPath;
|
||||
// Check that an extensions directory exists.
|
||||
if (!pathExists(dir).ok()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Glob the extension files.
|
||||
std::vector<std::string> paths;
|
||||
if (!resolveFilePattern(dir / kSafariExtensionsPattern, paths).ok()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto& extension_path : paths) {
|
||||
genSafariExtension(extension_path, results);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
15
osquery/tables/specs/darwin/chrome_extensions.table
Normal file
15
osquery/tables/specs/darwin/chrome_extensions.table
Normal file
@ -0,0 +1,15 @@
|
||||
table_name("chrome_extensions")
|
||||
description("Chrome browser extensions.")
|
||||
schema([
|
||||
Column("name", TEXT, "Extension display name"),
|
||||
Column("identifier", TEXT, "Extension identifier"),
|
||||
Column("version", TEXT, "Extension-supplied version"),
|
||||
Column("description", TEXT, "Extension-optional description"),
|
||||
Column("locale", TEXT, "Default locale supported by extension"),
|
||||
Column("update_url", TEXT, "Extension-supplied update URI"),
|
||||
Column("author", TEXT, "Optional extension author"),
|
||||
Column("persistent", INTEGER,
|
||||
"1 if extension is persistent across all tabs else 0"),
|
||||
Column("path", TEXT, "Path to extension folder"),
|
||||
])
|
||||
implementation("applications/browser_chrome@genChromeExtensions")
|
23
osquery/tables/specs/darwin/firefox_addons.table
Normal file
23
osquery/tables/specs/darwin/firefox_addons.table
Normal file
@ -0,0 +1,23 @@
|
||||
table_name("firefox_addons")
|
||||
description("Firefox browser extensions, webapps, and addons.")
|
||||
schema([
|
||||
Column("name", TEXT, "Addon display name"),
|
||||
Column("identifier", TEXT, "Addon identifier"),
|
||||
Column("creator", TEXT< "Addon-supported creator string"),
|
||||
Column("type", TEXT, "Extension, addon, webapp"),
|
||||
Column("version", TEXT, "Addon-supplied version string"),
|
||||
Column("description", TEXT, "Addon-supplied description string"),
|
||||
Column("source_url", TEXT, "URL that installed the addon"),
|
||||
Column("visible", INTEGER, "1 if the addon is shown in browser else 0"),
|
||||
Column("active", INTEGER, "1 if the addon is active else 0"),
|
||||
Column("disabled", INTEGER,
|
||||
"1 if the addon is application-disabled else 0"),
|
||||
Column("autoupdate", INTEGER,
|
||||
"1 if the addon applies background updates else 0"),
|
||||
Column("native", INTEGER,
|
||||
"1 if the addon includes binary components else 0"),
|
||||
Column("location", TEXT, "Global, profile location"),
|
||||
Column("path", TEXT, "Path to plugin bundle"),
|
||||
|
||||
])
|
||||
implementation("applications/browser_firefox@genFirefoxAddons")
|
7
osquery/tables/specs/darwin/safari_extensions.table
Normal file
7
osquery/tables/specs/darwin/safari_extensions.table
Normal file
@ -0,0 +1,7 @@
|
||||
table_name("safari_extensions")
|
||||
description("Safari browser extension details for all users.")
|
||||
schema([
|
||||
Column("name", TEXT, "Default name of the node"),
|
||||
Column("path", TEXT, "Path to extension xar"),
|
||||
])
|
||||
implementation("applications/browser_safari@genSafariExtensions")
|
13
osquery/tables/specs/darwin/safari_plugins.table
Normal file
13
osquery/tables/specs/darwin/safari_plugins.table
Normal file
@ -0,0 +1,13 @@
|
||||
table_name("safari_plugins")
|
||||
description("Safari browser plugin details for all users.")
|
||||
schema([
|
||||
Column("name", TEXT, "Plugin display name"),
|
||||
Column("identifier", TEXT, "Plugin identifier"),
|
||||
Column("version", TEXT, "Plugin short version"),
|
||||
Column("sdk", TEXT, "Build SDK used to compile plugin"),
|
||||
Column("description", TEXT, "Plugin description text"),
|
||||
Column("development_region", TEXT, "Plugin language-localization"),
|
||||
Column("native", INTEGER, "Plugin requires native execution"),
|
||||
Column("path", TEXT, "Path to plugin bundle"),
|
||||
])
|
||||
implementation("applications/browser_safari@genSafariPlugins")
|
Loading…
Reference in New Issue
Block a user