mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-06 17:45:22 +00:00
Virtual tables for Apple's application level firewall
This commit is contained in:
parent
826f9d9905
commit
1a381e0feb
4
Makefile
4
Makefile
@ -9,6 +9,10 @@ build:
|
|||||||
python tools/gentable.py osquery/tables/specs/processes.table
|
python tools/gentable.py osquery/tables/specs/processes.table
|
||||||
python tools/gentable.py osquery/tables/specs/nvram.table
|
python tools/gentable.py osquery/tables/specs/nvram.table
|
||||||
python tools/gentable.py osquery/tables/specs/osx_version.table
|
python tools/gentable.py osquery/tables/specs/osx_version.table
|
||||||
|
python tools/gentable.py osquery/tables/specs/alf.table
|
||||||
|
python tools/gentable.py osquery/tables/specs/alf_exceptions.table
|
||||||
|
python tools/gentable.py osquery/tables/specs/alf_explicit_auths.table
|
||||||
|
python tools/gentable.py osquery/tables/specs/alf_services.table
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build && cmake .. && make -j5
|
cd build && cmake .. && make -j5
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ TARGET_LINK_LIBRARIES(osquery_core gflags)
|
|||||||
TARGET_LINK_LIBRARIES(osquery_core glog)
|
TARGET_LINK_LIBRARIES(osquery_core glog)
|
||||||
TARGET_LINK_LIBRARIES(osquery_core gtest)
|
TARGET_LINK_LIBRARIES(osquery_core gtest)
|
||||||
TARGET_LINK_LIBRARIES(osquery_core osquery_database)
|
TARGET_LINK_LIBRARIES(osquery_core osquery_database)
|
||||||
|
TARGET_LINK_LIBRARIES(osquery_core osquery_filesystem)
|
||||||
TARGET_LINK_LIBRARIES(osquery_core osquery_sqlite)
|
TARGET_LINK_LIBRARIES(osquery_core osquery_sqlite)
|
||||||
TARGET_LINK_LIBRARIES(osquery_core osquery_tables)
|
TARGET_LINK_LIBRARIES(osquery_core osquery_tables)
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
|
||||||
#include "osquery/core/sqlite_util.h"
|
#include "osquery/core/sqlite_util.h"
|
||||||
|
#include "osquery/filesystem.h"
|
||||||
|
|
||||||
using namespace osquery::db;
|
using namespace osquery::db;
|
||||||
namespace pt = boost::property_tree;
|
namespace pt = boost::property_tree;
|
||||||
@ -311,4 +312,172 @@ std::vector<SplitStringTestData> generateSplitStringTestData() {
|
|||||||
return {s1, s2, s3};
|
return {s1, s2, s3};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getALFContent() {
|
||||||
|
std::string content = R"(
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>allowsignedenabled</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>applications</key>
|
||||||
|
<array/>
|
||||||
|
<key>exceptions</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>path</key>
|
||||||
|
<string>/usr/libexec/configd</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>path</key>
|
||||||
|
<string>/usr/sbin/mDNSResponder</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>path</key>
|
||||||
|
<string>/usr/sbin/racoon</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>path</key>
|
||||||
|
<string>/usr/bin/nmblookup</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>path</key>
|
||||||
|
<string>/System/Library/PrivateFrameworks/Admin.framework/Versions/A/Resources/readconfig</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>3</integer>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>explicitauths</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>org.python.python.app</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>com.apple.ruby</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>com.apple.a2p</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>com.apple.javajdk16.cmd</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>com.apple.php</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>com.apple.nc</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>id</key>
|
||||||
|
<string>com.apple.ksh</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>firewall</key>
|
||||||
|
<dict>
|
||||||
|
<key>Apple Remote Desktop</key>
|
||||||
|
<dict>
|
||||||
|
<key>proc</key>
|
||||||
|
<string>AppleVNCServer</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>FTP Access</key>
|
||||||
|
<dict>
|
||||||
|
<key>proc</key>
|
||||||
|
<string>ftpd</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>ODSAgent</key>
|
||||||
|
<dict>
|
||||||
|
<key>proc</key>
|
||||||
|
<string>ODSAgent</string>
|
||||||
|
<key>servicebundleid</key>
|
||||||
|
<string>com.apple.ODSAgent</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>Personal File Sharing</key>
|
||||||
|
<dict>
|
||||||
|
<key>proc</key>
|
||||||
|
<string>AppleFileServer</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>Personal Web Sharing</key>
|
||||||
|
<dict>
|
||||||
|
<key>proc</key>
|
||||||
|
<string>httpd</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>Printer Sharing</key>
|
||||||
|
<dict>
|
||||||
|
<key>proc</key>
|
||||||
|
<string>cupsd</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>Remote Apple Events</key>
|
||||||
|
<dict>
|
||||||
|
<key>proc</key>
|
||||||
|
<string>AEServer</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>Remote Login - SSH</key>
|
||||||
|
<dict>
|
||||||
|
<key>proc</key>
|
||||||
|
<string>sshd-keygen-wrapper</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
<key>Samba Sharing</key>
|
||||||
|
<dict>
|
||||||
|
<key>proc</key>
|
||||||
|
<string>smbd</string>
|
||||||
|
<key>state</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>firewallunload</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>globalstate</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>loggingenabled</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>loggingoption</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>stealthenabled</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>version</key>
|
||||||
|
<string>1.0a25</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
)";
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
pt::ptree getALFTree() {
|
||||||
|
auto content = getALFContent();
|
||||||
|
pt::ptree tree;
|
||||||
|
fs::parsePlistContent(content, tree);
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
@ -97,6 +97,12 @@ std::vector<SplitStringTestData> generateSplitStringTestData();
|
|||||||
// generate test content of a property list
|
// generate test content of a property list
|
||||||
std::string getPlistContent();
|
std::string getPlistContent();
|
||||||
|
|
||||||
|
// generate test content of com.apple.alf
|
||||||
|
std::string getALFcontent();
|
||||||
|
|
||||||
|
// generate a test ptree of the content returned by getALFContent
|
||||||
|
boost::property_tree::ptree getALFTree();
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif /* OSQUERY_CORE_TEST_UTIL_H */
|
#endif /* OSQUERY_CORE_TEST_UTIL_H */
|
||||||
|
@ -13,6 +13,7 @@ ADD_LIBRARY(osquery_tables
|
|||||||
system/nvram.cpp
|
system/nvram.cpp
|
||||||
system/NSProcessInfo+PECocoaBackports.mm
|
system/NSProcessInfo+PECocoaBackports.mm
|
||||||
system/osx_version.mm
|
system/osx_version.mm
|
||||||
|
system/firewall.cpp
|
||||||
)
|
)
|
||||||
TARGET_LINK_LIBRARIES(osquery_tables boost_filesystem)
|
TARGET_LINK_LIBRARIES(osquery_tables boost_filesystem)
|
||||||
TARGET_LINK_LIBRARIES(osquery_tables glog)
|
TARGET_LINK_LIBRARIES(osquery_tables glog)
|
||||||
@ -28,3 +29,11 @@ TARGET_LINK_LIBRARIES(etc_hosts_tests osquery_core)
|
|||||||
TARGET_LINK_LIBRARIES(etc_hosts_tests osquery_database)
|
TARGET_LINK_LIBRARIES(etc_hosts_tests osquery_database)
|
||||||
TARGET_LINK_LIBRARIES(etc_hosts_tests osquery_filesystem)
|
TARGET_LINK_LIBRARIES(etc_hosts_tests osquery_filesystem)
|
||||||
TARGET_LINK_LIBRARIES(etc_hosts_tests osquery_tables)
|
TARGET_LINK_LIBRARIES(etc_hosts_tests osquery_tables)
|
||||||
|
|
||||||
|
ADD_EXECUTABLE(firewall_tests system/firewall_tests.cpp)
|
||||||
|
TARGET_LINK_LIBRARIES(firewall_tests gtest)
|
||||||
|
TARGET_LINK_LIBRARIES(firewall_tests glog)
|
||||||
|
TARGET_LINK_LIBRARIES(firewall_tests osquery_core)
|
||||||
|
TARGET_LINK_LIBRARIES(firewall_tests osquery_database)
|
||||||
|
TARGET_LINK_LIBRARIES(firewall_tests osquery_filesystem)
|
||||||
|
TARGET_LINK_LIBRARIES(firewall_tests osquery_tables)
|
||||||
|
11
osquery/tables/specs/alf.table
Normal file
11
osquery/tables/specs/alf.table
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
table_name("alf")
|
||||||
|
schema([
|
||||||
|
Column(name="allow_signed_enabled", type="int"),
|
||||||
|
Column(name="firewall_unload", type="int"),
|
||||||
|
Column(name="global_state", type="int"),
|
||||||
|
Column(name="logging_enabled", type="int"),
|
||||||
|
Column(name="logging_option", type="int"),
|
||||||
|
Column(name="stealth_enabled", type="int"),
|
||||||
|
Column(name="version", type="std::string"),
|
||||||
|
])
|
||||||
|
implementation("osquery/tables/system/firewall@genALF")
|
6
osquery/tables/specs/alf_exceptions.table
Normal file
6
osquery/tables/specs/alf_exceptions.table
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
table_name("alf_exceptions")
|
||||||
|
schema([
|
||||||
|
Column(name="path", type="std::string"),
|
||||||
|
Column(name="state", type="int"),
|
||||||
|
])
|
||||||
|
implementation("osquery/tables/system/firewall@genALFExceptions")
|
5
osquery/tables/specs/alf_explicit_auths.table
Normal file
5
osquery/tables/specs/alf_explicit_auths.table
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
table_name("alf_explicit_auths")
|
||||||
|
schema([
|
||||||
|
Column(name="processes", type="std::string"),
|
||||||
|
])
|
||||||
|
implementation("osquery/tables/system/firewall@genALFExplicitAuths")
|
7
osquery/tables/specs/alf_services.table
Normal file
7
osquery/tables/specs/alf_services.table
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
table_name("alf_services")
|
||||||
|
schema([
|
||||||
|
Column(name="service", type="std::string"),
|
||||||
|
Column(name="process", type="std::string"),
|
||||||
|
Column(name="state", type="int"),
|
||||||
|
])
|
||||||
|
implementation("osquery/tables/system/firewall@genALFServices")
|
218
osquery/tables/system/firewall.cpp
Normal file
218
osquery/tables/system/firewall.cpp
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "osquery/tables/system/firewall.h"
|
||||||
|
|
||||||
|
#include <glog/logging.h>
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include "osquery/database.h"
|
||||||
|
#include "osquery/filesystem.h"
|
||||||
|
#include "osquery/status.h"
|
||||||
|
|
||||||
|
using namespace osquery::db;
|
||||||
|
using osquery::Status;
|
||||||
|
namespace pt = boost::property_tree;
|
||||||
|
|
||||||
|
namespace osquery { namespace tables {
|
||||||
|
|
||||||
|
const std::string kALFPlistPath = "/Library/Preferences/com.apple.alf.plist";
|
||||||
|
|
||||||
|
// it.first represents the key that is used in com.apple.alf.plist to identify
|
||||||
|
// the data in question. it.second represents the value of the "service" column
|
||||||
|
// in the alf_services table.
|
||||||
|
const std::map<std::string, std::string> kFirewallTreeKeys = {
|
||||||
|
{"Apple Remote Desktop", "Apple Remote Desktop"},
|
||||||
|
{"FTP Access", "FTP"},
|
||||||
|
{"ODSAgent", "ODSAgent"},
|
||||||
|
{"Personal File Sharing", "File Sharing"},
|
||||||
|
{"Personal Web Sharing", "Web Sharing"},
|
||||||
|
{"Printer Sharing", "Printer Sharing"},
|
||||||
|
{"Remote Apple Events", "Remote Apple Events"},
|
||||||
|
{"Remote Login - SSH", "SSH"},
|
||||||
|
{"Samba Sharing", "Samba Sharing"},
|
||||||
|
};
|
||||||
|
|
||||||
|
// it.first represents the top level keys in com.apple.alf.plist to identify
|
||||||
|
// the data in question. it.second represents the names of the columns that
|
||||||
|
// each sample of data can be found under in the alf table.
|
||||||
|
const std::map<std::string, std::string> kTopLevelIntKeys = {
|
||||||
|
{"allowsignedenabled", "allow_signed_enabled"},
|
||||||
|
{"firewallunload", "firewall_unload"},
|
||||||
|
{"globalstate", "global_state"},
|
||||||
|
{"loggingenabled", "logging_enabled"},
|
||||||
|
{"loggingoption", "logging_option"},
|
||||||
|
{"stealthenabled", "stealth_enabled"},
|
||||||
|
};
|
||||||
|
|
||||||
|
// it.first represents the top level keys in com.apple.alf.plist to identify
|
||||||
|
// the data in question. it.second represents the names of the columns that
|
||||||
|
// each sample of data can be found under in the alf table.
|
||||||
|
const std::map<std::string, std::string> kTopLevelStringKeys = {
|
||||||
|
{"version", "version"},
|
||||||
|
};
|
||||||
|
|
||||||
|
Status genALFTreeFromFilesystem(pt::ptree& tree) {
|
||||||
|
try {
|
||||||
|
Status s = osquery::fs::parsePlist(kALFPlistPath, tree);
|
||||||
|
if (!s.ok()) {
|
||||||
|
LOG(ERROR) << "Error parsing " << kALFPlistPath << ": " << s.toString();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
} catch(const std::exception& e) {
|
||||||
|
return Status(1, e.what());
|
||||||
|
}
|
||||||
|
return Status(0, "OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QueryData parseALFTree(const pt::ptree& tree) {
|
||||||
|
Row r;
|
||||||
|
|
||||||
|
for (const auto& it : kTopLevelIntKeys) {
|
||||||
|
try {
|
||||||
|
int val = tree.get<int>(it.first);
|
||||||
|
r[it.second] = boost::lexical_cast<std::string>(val);
|
||||||
|
} catch (const pt::ptree_error& e) {
|
||||||
|
LOG(ERROR) << "Error retreiving " << it.second << " from com.apple.alf: "
|
||||||
|
<< e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& it : kTopLevelStringKeys) {
|
||||||
|
try {
|
||||||
|
std::string val = tree.get<std::string>(it.second);
|
||||||
|
r[it.first] = val;
|
||||||
|
} catch (const pt::ptree_error& e) {
|
||||||
|
LOG(ERROR) << "Error retreiving " << it.second << " from com.apple.alf: "
|
||||||
|
<< e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {r};
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryData genALF() {
|
||||||
|
pt::ptree tree;
|
||||||
|
auto s = genALFTreeFromFilesystem(tree);
|
||||||
|
if (!s.ok()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return parseALFTree(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryData parseALFExceptionsTree(const pt::ptree& tree) {
|
||||||
|
QueryData results;
|
||||||
|
|
||||||
|
pt::ptree exceptions_tree;
|
||||||
|
try {
|
||||||
|
exceptions_tree = tree.get_child("exceptions");
|
||||||
|
} catch (const pt::ptree_error& e) {
|
||||||
|
LOG(ERROR) << "Error retrieving exceptions key: " << e.what();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& it : exceptions_tree) {
|
||||||
|
std::string path;
|
||||||
|
int state;
|
||||||
|
try {
|
||||||
|
path = it.second.get<std::string>("path");
|
||||||
|
state = it.second.get<int>("state");
|
||||||
|
Row r;
|
||||||
|
r["path"] = path;
|
||||||
|
r["state"] = boost::lexical_cast<std::string>(state);
|
||||||
|
results.push_back(r);
|
||||||
|
} catch (const pt::ptree_error& e) {
|
||||||
|
LOG(ERROR) << "Error retrieving firewall exception keys: " << e.what();
|
||||||
|
} catch (const boost::bad_lexical_cast& e) {
|
||||||
|
LOG(ERROR) << "Error casting state (" << state << "): " << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryData genALFExceptions() {
|
||||||
|
pt::ptree tree;
|
||||||
|
auto s = genALFTreeFromFilesystem(tree);
|
||||||
|
if (!s.ok()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return parseALFExceptionsTree(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryData parseALFExplicitAuthsTree(const pt::ptree& tree) {
|
||||||
|
QueryData results;
|
||||||
|
|
||||||
|
pt::ptree auths_tree;
|
||||||
|
try {
|
||||||
|
auths_tree = tree.get_child("explicitauths");
|
||||||
|
} catch (const pt::ptree_error& e) {
|
||||||
|
LOG(ERROR) << "Error retrieving explicitauths key: " << e.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& it : auths_tree) {
|
||||||
|
std::string process;
|
||||||
|
try {
|
||||||
|
process = it.second.get<std::string>("id");
|
||||||
|
Row r;
|
||||||
|
r["process"] = process;
|
||||||
|
results.push_back(r);
|
||||||
|
} catch (const pt::ptree_error& e) {
|
||||||
|
LOG(ERROR) << "Error retrieving firewall exception keys: " << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryData genALFExplicitAuths() {
|
||||||
|
pt::ptree tree;
|
||||||
|
auto s = genALFTreeFromFilesystem(tree);
|
||||||
|
if (!s.ok()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return parseALFExplicitAuthsTree(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryData parseALFServicesTree(const pt::ptree& tree) {
|
||||||
|
QueryData results;
|
||||||
|
pt::ptree firewall_tree;
|
||||||
|
try {
|
||||||
|
firewall_tree = tree.get_child("firewall");
|
||||||
|
} catch (const pt::ptree_error& e) {
|
||||||
|
LOG(ERROR) << "Error retrieving firewall key: " << e.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& it : kFirewallTreeKeys) {
|
||||||
|
std::string proc;
|
||||||
|
int state;
|
||||||
|
pt::ptree subtree;
|
||||||
|
try {
|
||||||
|
subtree = firewall_tree.get_child(it.first);
|
||||||
|
proc = subtree.get<std::string>("proc");
|
||||||
|
state = subtree.get<int>("state");
|
||||||
|
Row r;
|
||||||
|
r["service"] = it.second;
|
||||||
|
r["process"] = proc;
|
||||||
|
r["state"] = boost::lexical_cast<std::string>(state);
|
||||||
|
results.push_back(r);
|
||||||
|
} catch (const pt::ptree_error& e) {
|
||||||
|
LOG(ERROR) << "Error retrieving " << it.first << " keys: " << e.what();
|
||||||
|
} catch (const boost::bad_lexical_cast& e) {
|
||||||
|
LOG(ERROR) << "Error casting state (" << state << "): " << e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryData genALFServices() {
|
||||||
|
pt::ptree tree;
|
||||||
|
auto s = genALFTreeFromFilesystem(tree);
|
||||||
|
if (!s.ok()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return parseALFServicesTree(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
52
osquery/tables/system/firewall.h
Normal file
52
osquery/tables/system/firewall.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#ifndef OSQUERY_TABLES_SYSTEM_FIREWALL_H
|
||||||
|
#define OSQUERY_TABLES_SYSTEM_FIREWALL_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
|
||||||
|
#include "osquery/database/results.h"
|
||||||
|
|
||||||
|
namespace osquery { namespace tables {
|
||||||
|
|
||||||
|
// Given a property tree of the parsed content of com.apple.alf.plist,
|
||||||
|
// parseALFExceptionsTree parses out the "exceptions" key
|
||||||
|
osquery::db::QueryData parseALFExceptionsTree(
|
||||||
|
const boost::property_tree::ptree& tree);
|
||||||
|
|
||||||
|
// Given a property tree of the parsed content of com.apple.alf.plist,
|
||||||
|
// parseALFExplicitAuthsTree parses out the "explicitauth" key
|
||||||
|
osquery::db::QueryData parseALFExplicitAuthsTree(
|
||||||
|
const boost::property_tree::ptree& tree);
|
||||||
|
|
||||||
|
// Given a property tree of the parsed content of com.apple.alf.plist,
|
||||||
|
// parseALFServicesTree parses out the services which exist under the
|
||||||
|
// "firewall" key
|
||||||
|
osquery::db::QueryData parseALFServicesTree(
|
||||||
|
const boost::property_tree::ptree& tree);
|
||||||
|
|
||||||
|
// Given a property tree of the parsed content of com.apple.alf.plist,
|
||||||
|
// parseALFTree parses out the top level string and int keys
|
||||||
|
osquery::db::QueryData parseALFTree(const boost::property_tree::ptree& tree);
|
||||||
|
|
||||||
|
// kALFPlistPath is the path of the com.apple.alf.plist path
|
||||||
|
extern const std::string kALFPlistPath;
|
||||||
|
|
||||||
|
// kFirewallTreeKeys is a map of keys and columns which are used while parsing
|
||||||
|
// in the function parseALFServicesTree
|
||||||
|
extern const std::map<std::string, std::string> kFirewallTreeKeys;
|
||||||
|
|
||||||
|
// kTopLevelIntKeys is a map of keys and columns which are used while parsing
|
||||||
|
// in the function parseALFTree
|
||||||
|
extern const std::map<std::string, std::string> kTopLevelIntKeys;
|
||||||
|
|
||||||
|
// kTopLevelStringKeys is a map of keys and columns which are used while
|
||||||
|
// parsing in the function parseALFTree
|
||||||
|
extern const std::map<std::string, std::string> kTopLevelStringKeys;
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif /* OSQUERY_TABLES_SYSTEM_FIREWALL_H */
|
165
osquery/tables/system/firewall_tests.cpp
Normal file
165
osquery/tables/system/firewall_tests.cpp
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <glog/logging.h>
|
||||||
|
|
||||||
|
#include "osquery/core/test_util.h"
|
||||||
|
#include "osquery/database.h"
|
||||||
|
#include "osquery/filesystem.h"
|
||||||
|
#include "osquery/tables/system/firewall.h"
|
||||||
|
|
||||||
|
using namespace osquery::core;
|
||||||
|
namespace pt = boost::property_tree;
|
||||||
|
|
||||||
|
namespace osquery { namespace tables {
|
||||||
|
|
||||||
|
class FirewallTests : public testing::Test {};
|
||||||
|
|
||||||
|
TEST_F(FirewallTests, test_parse_alf_tree) {
|
||||||
|
pt::ptree tree = getALFTree();
|
||||||
|
auto results = parseALFTree(tree);
|
||||||
|
osquery::db::QueryData expected = {
|
||||||
|
{
|
||||||
|
{"allow_signed_enabled", "1"},
|
||||||
|
{"firewall_unload", "0"},
|
||||||
|
{"global_state", "0"},
|
||||||
|
{"logging_enabled", "0"},
|
||||||
|
{"logging_option", "0"},
|
||||||
|
{"stealth_enabled", "0"},
|
||||||
|
{"version", "1.0a25"},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
EXPECT_EQ(results, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FirewallTests, test_parse_alf_exceptions_tree) {
|
||||||
|
pt::ptree tree = getALFTree();
|
||||||
|
auto results = parseALFExceptionsTree(tree);
|
||||||
|
osquery::db::QueryData expected = {
|
||||||
|
{
|
||||||
|
{"path", "/usr/libexec/configd"},
|
||||||
|
{"state", "3"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"path", "/usr/sbin/mDNSResponder"},
|
||||||
|
{"state", "3"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"path", "/usr/sbin/racoon"},
|
||||||
|
{"state", "3"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"path", "/usr/bin/nmblookup"},
|
||||||
|
{"state", "3"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"path", "/System/Library/PrivateFrameworks/Admin.framework/Versions/A/Resources/readconfig"},
|
||||||
|
{"state", "3"}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
EXPECT_EQ(results, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FirewallTests, test_parse_alf_explicit_auths_tree) {
|
||||||
|
pt::ptree tree = getALFTree();
|
||||||
|
auto results = parseALFExplicitAuthsTree(tree);
|
||||||
|
osquery::db::QueryData expected = {
|
||||||
|
{{"process", "org.python.python.app"}},
|
||||||
|
{{"process", "com.apple.ruby"}},
|
||||||
|
{{"process", "com.apple.a2p"}},
|
||||||
|
{{"process", "com.apple.javajdk16.cmd"}},
|
||||||
|
{{"process", "com.apple.php"}},
|
||||||
|
{{"process", "com.apple.nc"}},
|
||||||
|
{{"process", "com.apple.ksh"}},
|
||||||
|
};
|
||||||
|
EXPECT_EQ(results, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FirewallTests, test_parse_alf_services_tree) {
|
||||||
|
pt::ptree tree = getALFTree();
|
||||||
|
auto results = parseALFServicesTree(tree);
|
||||||
|
osquery::db::QueryData expected = {
|
||||||
|
{
|
||||||
|
{"service", "Apple Remote Desktop"},
|
||||||
|
{"process", "AppleVNCServer"},
|
||||||
|
{"state", "0"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"service", "FTP"},
|
||||||
|
{"process", "ftpd"},
|
||||||
|
{"state", "0"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"service", "ODSAgent"},
|
||||||
|
{"process", "ODSAgent"},
|
||||||
|
{"state", "0"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"service", "File Sharing"},
|
||||||
|
{"process", "AppleFileServer"},
|
||||||
|
{"state", "0"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"service", "Web Sharing"},
|
||||||
|
{"process", "httpd"},
|
||||||
|
{"state", "0"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"service", "Printer Sharing"},
|
||||||
|
{"process", "cupsd"},
|
||||||
|
{"state", "0"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"service", "Remote Apple Events"},
|
||||||
|
{"process", "AEServer"},
|
||||||
|
{"state", "0"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"service", "SSH"},
|
||||||
|
{"process", "sshd-keygen-wrapper"},
|
||||||
|
{"state", "0"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"service", "Samba Sharing"},
|
||||||
|
{"process", "smbd"},
|
||||||
|
{"state", "0"},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
EXPECT_EQ(results, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FirewallTests, test_errors) {
|
||||||
|
pt::ptree tree = getALFTree();
|
||||||
|
auto results = parseALFTree(tree);
|
||||||
|
ASSERT_THROW(tree.get<int>("foo"), pt::ptree_error);
|
||||||
|
ASSERT_THROW(tree.get<int>("version"), pt::ptree_error);
|
||||||
|
ASSERT_THROW(tree.get<int>("version"), pt::ptree_bad_data);
|
||||||
|
ASSERT_THROW(tree.get_child("foo"), pt::ptree_error);
|
||||||
|
ASSERT_THROW(tree.get_child("foo"), pt::ptree_bad_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FirewallTests, test_on_disk_format) {
|
||||||
|
pt::ptree tree;
|
||||||
|
auto s = osquery::fs::parsePlist(kALFPlistPath, tree);
|
||||||
|
EXPECT_TRUE(s.ok());
|
||||||
|
EXPECT_EQ(s.toString(), "OK");
|
||||||
|
for (const auto& it : kTopLevelIntKeys) {
|
||||||
|
EXPECT_NO_THROW(tree.get<int>(it.first));
|
||||||
|
}
|
||||||
|
for (const auto& it : kTopLevelStringKeys) {
|
||||||
|
EXPECT_NO_THROW(tree.get<std::string>(it.first));
|
||||||
|
}
|
||||||
|
EXPECT_NO_THROW(tree.get_child("firewall"));
|
||||||
|
auto firewall = tree.get_child("firewall");
|
||||||
|
for (const auto& it : kFirewallTreeKeys) {
|
||||||
|
EXPECT_NO_THROW(firewall.get_child(it.first));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
google::InitGoogleLogging(argv[0]);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user