Add system extension table (#6863)

This commit is contained in:
kumarak 2021-01-11 10:34:11 -05:00 committed by GitHub
parent c93fefb7f1
commit 4bef4e4c78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 270 additions and 0 deletions

View File

@ -154,6 +154,7 @@ function(generateOsqueryTablesSystemSystemtable)
darwin/smc_keys.cpp
darwin/startup_items.cpp
darwin/sysctl_utils.cpp
darwin/system_extensions.mm
darwin/system_info.cpp
darwin/time_machine.cpp
darwin/usb_devices.cpp

View File

@ -0,0 +1,85 @@
/**
* Copyright (c) 2014-present, The osquery authors
*
* This source code is licensed as defined by the LICENSE file found in the
* root directory of this source tree.
*
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
*/
#include <CoreServices/CoreServices.h>
#include <Foundation/Foundation.h>
#include <boost/algorithm/string.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <osquery/core/core.h>
#include <osquery/core/tables.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/logger/logger.h>
#include <osquery/sql/sql.h>
#include <osquery/utils/darwin/plist.h>
namespace pt = boost::property_tree;
namespace osquery {
namespace tables {
const std::string kSysExtDBPath = "/Library/SystemExtensions/db.plist";
std::string getExtensionCategory(const pt::ptree& ptree) {
std::vector<std::string> categories;
for (const auto& item : ptree) {
categories.push_back(item.second.get("", ""));
}
return boost::algorithm::join(categories, ", ");
}
void getExtensionRow(const pt::ptree& extension, Row& r) {
r["path"] = extension.get("originPath", "");
r["UUID"] = extension.get("uniqueID", "");
r["state"] = extension.get("state", "");
r["identifier"] = extension.get("identifier", "");
r["version"] = extension.get("bundleVersion.CFBundleShortVersionString", "");
r["team"] = extension.get("teamID", "");
// Get the system extension categories from the array
const auto category = extension.get_child("categories");
r["category"] = getExtensionCategory(category);
r["bundle_path"] = extension.get("container.bundlePath", "");
}
QueryData genExtensionsFromPtree(const pt::ptree& ptree) {
QueryData results;
const auto extensions_attr_opt = ptree.get_child_optional("extensions");
if (!extensions_attr_opt.has_value()) {
return results;
}
const auto& extensions_attr = extensions_attr_opt.value();
for (const auto& array_entry : extensions_attr) {
const auto& extension_value = array_entry.second;
Row r;
getExtensionRow(extension_value, r);
results.push_back(r);
}
return results;
}
QueryData genSystemExtensions(QueryContext& context) {
if (!osquery::pathExists(kSysExtDBPath)) {
VLOG(1) << "System extension database does not exist: " << kSysExtDBPath;
return {};
}
pt::ptree ptree;
if (!osquery::parsePlist(kSysExtDBPath, ptree).ok()) {
LOG(ERROR) << "Failed to parse: " << kSysExtDBPath;
return {};
}
return genExtensionsFromPtree(ptree);
}
}
}

View File

@ -113,6 +113,7 @@ function(generateOsqueryTablesSystemDarwinTests)
darwin/processes_tests.cpp
darwin/smc_tests.cpp
darwin/startup_items_tests.cpp
darwin/system_extensions_test.cpp
darwin/signature_tests.mm
)

View File

@ -0,0 +1,126 @@
/**
* Copyright (c) 2014-present, The osquery authors
*
* This source code is licensed as defined by the LICENSE file found in the
* root directory of this source tree.
*
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
*/
#include <boost/property_tree/json_parser.hpp>
#include <gtest/gtest.h>
#include <osquery/config/tests/test_utils.h>
#include <osquery/core/sql/query_data.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/utils/darwin/plist.h>
namespace pt = boost::property_tree;
namespace osquery {
namespace tables {
extern QueryData genExtensionsFromPtree(const pt::ptree& ptree);
class SystemExtensionTests : public testing::Test {};
TEST_F(SystemExtensionTests, test_parse_ptree) {
pt::ptree ptree;
std::stringstream ss;
ss << "{ \"version\": \"1\", \"extensions\": [{ \"state\": "
"\"activated_enabled\", "
"\"categories\": [ \"com.apple.system_extension.network_extension\" ], "
"\"originPath\": "
"\"/Applications/LuLu.app/Contents/Library/SystemExtensions/com."
"objective-see.lulu.extension.systemextension\", "
"\"additionalLaunchdPlistEntries\": "
"\"YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMS"
"AAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGvEBULDBkaGxwdIyQlKzEyODlBQk"
"NHSEtVJG51bGzTDQ4PEBQYV05TLmtleXNaTlMub2JqZWN0c1YkY2xhc3OjERITgAKAA4AE"
"oxUWF4AFgAaACoAJW1Byb2Nlc3NUeXBlXE1hY2hTZXJ2aWNlc1xMYXVuY2hFdmVudHNbSW"
"50ZXJhY3RpdmXTDQ4PHiAYoR+"
"AB6EhgAiACV8QIVZCRzk3VUI0VEEuY29tLm9iamVjdGl2ZS1zZWUubHVsdQnSJicoKVokY"
"2xhc3NuYW1lWCRjbGFzc2VzXE5TRGljdGlvbmFyeaIoKlhOU09iamVjdNMNDg8sLhihLYA"
"LoS+"
"ADIAJXxAsY29tLmFwcGxlLm5ldHdvcmtleHRlbnNpb24ucHJvdmlkZXIubWF0Y2hpbmfTD"
"Q4P"
"MzUYoTSADaE2gA6ACV8QIGNvbS5vYmplY3RpdmUtc2VlLmx1bHUuZXh0ZW5zaW9u0w0ODz"
"o9G"
"KI7PIAPgBCiPj+"
"AEYAUgAlfEBFORUV4dGVuc2lvblBvaW50c18QGk5FUHJvdmlkZXJCdW5kbGVJZGVudGlma"
"WVy"
"0g4PREahRYASgBNfECZjb20uYXBwbGUubmV0d29ya2V4dGVuc2lvbi5maWx0ZXItZGF0Yd"
"ImJ0lKV05TQXJyYXmiSSpfECBjb20ub2JqZWN0aXZlLXNlZS5sdWx1LmV4dGVuc2lvbgAI"
"ABE"
"AGgAkACkAMgA3AEkATABRAFMAawBxAHgAgACLAJIAlgCYAJoAnACgAKIApACmAKgAtADBA"
"M4A2gDhAOMA5QDnAOkA6wEPARABFQEgASkBNgE5AUIBSQFLAU0BTwFRAVMBggGJAYsBjQG"
"PAZEBk"
"wG2Ab0BwAHCAcQBxwHJAcsBzQHhAf4CAwIFAgcCCQIyAjcCPwJCAAAAAAAAAgEAAAAAAAA"
"ATAAAAAAAAAAAAAAAAAAAAmU=\", \"bundleVersion\": { "
"\"CFBundleShortVersionString\": \"2.0.0\", \"CFBundleVersion\": "
"\"2.0.0\" }, \"identifier\": \"com.objective-see.lulu.extension\", "
"\"stagedBundleURL\": { \"relative\": "
"\"file:///Library/SystemExtensions/B4A2DE3D-1047-4109-9878-"
"CC8238F6DE29/com.objective-see.lulu.extension.systemextension/\" }, "
"\"container\": { \"bundlePath\": \"/Applications/LuLu.app\" }, "
"\"uniqueID\": \"B4A2DE3D-1047-4109-9878-CC8238F6DE29\", "
"\"stagedCdhashes\": { \"bb21ef2b71632c7c01c2173e465b993aa565508a\": { "
"\"cputype\": \"16777223\", \"cpusubtype\": \"3\" }}, \"references\": "
"[{\"appIdentifier\": \"com.objective-see.lulu.app\", \"appRef\": "
"\"file:///.file/id=6571367.25554446/\", \"teamID\": "
"\"VBG97UB4TA\"}], \"teamID\": \"VBG97UB4TA\" }], \"developerMode\": "
"\"0\", \"extensionPolicies\": \"\", \"bootUUID\": "
"\"E7C066D9-19F4-4E47-8E1E-35E1C1434905\" }";
try {
pt::read_json(ss, ptree);
} catch (std::exception& e) {
// Force fail the test on exception
ASSERT_TRUE(false);
}
QueryData results = genExtensionsFromPtree(ptree);
ASSERT_EQ(results.size(), 1U);
EXPECT_EQ(results[0]["state"], "activated_enabled");
EXPECT_EQ(results[0]["category"],
"com.apple.system_extension.network_extension");
EXPECT_EQ(results[0]["identifier"], "com.objective-see.lulu.extension");
EXPECT_EQ(results[0]["version"], "2.0.0");
EXPECT_EQ(results[0]["UUID"], "B4A2DE3D-1047-4109-9878-CC8238F6DE29");
EXPECT_EQ(results[0]["team"], "VBG97UB4TA");
EXPECT_EQ(results[0]["path"],
"/Applications/LuLu.app/Contents/Library/SystemExtensions/"
"com.objective-see.lulu.extension.systemextension");
EXPECT_EQ(results[0]["bundle_path"], "/Applications/LuLu.app");
}
TEST_F(SystemExtensionTests, test_parse_plist) {
auto dbplist_path = getTestConfigDirectory() / "db.plist";
if (!osquery::pathExists(dbplist_path)) {
return;
}
pt::ptree ptree;
if (!osquery::parsePlist(dbplist_path, ptree).ok()) {
return;
}
QueryData results = genExtensionsFromPtree(ptree);
ASSERT_EQ(results.size(), 1U);
EXPECT_EQ(results[0]["state"], "activated_enabled");
EXPECT_EQ(results[0]["category"],
"com.apple.system_extension.network_extension");
EXPECT_EQ(results[0]["identifier"], "com.objective-see.lulu.extension");
EXPECT_EQ(results[0]["version"], "2.0.0");
EXPECT_EQ(results[0]["UUID"], "B4A2XXXX-XXXX-XXXX-XXXX-XXXX38F6DE29");
EXPECT_EQ(results[0]["team"], "ABCDXYZUV");
EXPECT_EQ(results[0]["path"],
"/Applications/LuLu.app/Contents/Library/SystemExtensions/"
"com.objective-see.lulu.extension.systemextension");
EXPECT_EQ(results[0]["bundle_path"], "/Applications/LuLu.app");
}
} // namespace tables
} // namespace osquery

View File

@ -133,6 +133,7 @@ function(generateNativeTables)
"darwin/signature.table:macos"
"darwin/sip_config.table:macos"
"darwin/smc_keys.table:macos"
"darwin/system_extensions.table:macos"
"darwin/temperature_sensors.table:macos"
"darwin/time_machine_backups.table:macos"
"darwin/time_machine_destinations.table:macos"

View File

@ -0,0 +1,16 @@
table_name("system_extensions")
description("macOS (>= 10.15) system extension table.")
schema([
Column("path", TEXT, "Original path of system extension"),
Column("UUID", TEXT, "Extension unique id"),
Column("state", TEXT, "System extension state"),
Column("identifier", TEXT, "Identifier name"),
Column("version", TEXT, "System extension version"),
Column("category", TEXT, "System extension category"),
Column("bundle_path", TEXT, "System extension bundle path"),
Column("team", TEXT, "Signing team ID")
])
implementation("system_extensions@genSystemExtensions")
examples([
"select * from system_extensions",
])

View File

@ -256,6 +256,7 @@ function(generateTestsIntegrationTablesTestsTest)
smart_drive_info.cpp
smc_keys.cpp
startup_items.cpp
system_extensions.cpp
temperature_sensors.cpp
time_machine_backups.cpp
time_machine_destinations.cpp

View File

@ -0,0 +1,39 @@
/**
* Copyright (c) 2014-present, The osquery authors
*
* This source code is licensed as defined by the LICENSE file found in the
* root directory of this source tree.
*
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
*/
// Sanity check integration test for system_info
// Spec file: specs/system_info.table
#include <osquery/tests/integration/tables/helper.h>
namespace osquery {
namespace table_tests {
class SystemExtension : public testing::Test {
protected:
void SetUp() override {
setUpEnvironment();
}
};
TEST_F(SystemExtension, test_sanity) {
QueryData data = execute_query("select * from system_extensions");
ValidationMap row_map = {{"path", NormalType},
{"UUID", NormalType},
{"state", NormalType},
{"identifier", NormalType},
{"version", NormalType},
{"category", NormalType},
{"bundle_path", NormalType},
{"team", NormalType}};
validate_rows(data, row_map);
}
} // namespace table_tests
} // namespace osquery

Binary file not shown.