osquery-1/osquery/tables/other/yara.cpp

172 lines
4.9 KiB
C++
Raw Normal View History

Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
/*
* Copyright (c) 2014, Facebook, Inc.
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
* 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/filesystem.hpp>
#include <osquery/filesystem.h>
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
#include <osquery/logger.h>
#include <osquery/tables.h>
#include <osquery/status.h>
#include "osquery/tables/other/yara_utils.h"
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
#ifdef CONCAT
#undef CONCAT
#endif
#include <yara.h>
namespace osquery {
namespace tables {
Status doYARAScan(YR_RULES* rules,
const std::string& path,
const std::string& pattern,
QueryData& results,
const std::string& group,
const std::string& sigfile) {
Row r;
// These are default values, to be updated in YARACallback.
r["count"] = INTEGER(0);
r["matches"] = std::string("");
r["strings"] = std::string("");
r["tags"] = std::string("");
// XXX: use target_path instead to be consistent with yara_events?
r["path"] = path;
r["pattern"] = pattern;
r["sig_group"] = std::string(group);
r["sigfile"] = std::string(sigfile);
int result = yr_rules_scan_file(rules,
path.c_str(),
SCAN_FLAGS_FAST_MODE,
YARACallback,
(void*)&r,
0);
if (result != ERROR_SUCCESS) {
return Status(1, "Scan error (" + std::to_string(result) + ")");
}
results.push_back(r);
return Status(0, "OK");
}
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
QueryData genYara(QueryContext& context) {
QueryData results;
auto paths = context.constraints["path"].getAll(EQUALS);
auto patterns = context.constraints["pattern"].getAll(EQUALS);
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
auto groups = context.constraints["sig_group"].getAll(EQUALS);
auto sigfiles = context.constraints["sigfile"].getAll(EQUALS);
// Must specify a path constraint and at least one of sig_group or sigfile.
if (groups.size() == 0 && sigfiles.size() == 0) {
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
return results;
}
// XXX: Abstract this into a common "get rules for group" function.
[fix #1390] query pack re-org This commit contains the features specified in #1390 as well as a refactoring of the general osquery configuration code. The API for the config plugins hasn't changed, although now there's a `genPack` method that config plugins can implement. If a plugin doesn't implement `genPack`, then the map<string, string> format cannot be used. The default config plugin, the filesystem plugin, now implements `genPack`, so existing query packs code will continue to work as it always has. Now many other config plugins can implement custom pack handling for what makes sense in their context. `genPacks` is not a pure virtual, so it doesn't have to be implemented in your plugin if you don't want to use it. Also, more importantly, all config plugins can use the standard inline pack format if they want to use query packs. Which is awesome. For more information, refer to #1390, the documentation and the doxygen comments included with this pull requests, as well as the following example config which is now supported, regardless of what config plugin you're using: ```json { "options": { "enable_monitor": "true" }, "packs": { "core_os_monitoring": { "version": "1.4.5", "discovery": [ "select pid from processes where name like '%osqueryd%';" ], "queries": { "kernel_modules": { "query": "SELECT name, size FROM kernel_modules;", "interval": 600 }, "system_controls": { "query": "SELECT * FROM system_controls;", "interval": 600, "snapshot": true, }, "usb_devices": { "query": "SELECT * FROM usb_devices;", "interval": 600 } } }, "osquery_internal_info": { "version": "1.4.5", "discovery": [ "select pid from processes where name like '%osqueryd%';" ], "queries": { "info": { "query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;", "interval": 60, "snapshot": true }, "registry": { "query": "SELECT * FROM osquery_registry;", "interval": 600, "snapshot": true }, "schedule": { "query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;", "interval": 60, "snapshot": true } } } } } ``` The `osquery_packs` table was modified to remove the superfluous columns which could already have been found in `osquery_schedule`. Two more columns were added in their place, representing stats about pack's discovery query execution history. Notably, the internal API for the `osquery::Config` class has changed rather dramatically as apart of the refactoring. We think this is an improvement. While strictly adhering to the osquery config plugin interface will have avoided any compatibility errors, advanced users may notice compilation errors if they access config data directly. All internal users of the config have obviously been updated. Yet another reason to merge your code into mainline; we update it for you when we refactor!
2015-08-19 20:27:49 +00:00
auto parser = Config::getParser("yara");
if (parser == nullptr || parser.get() == nullptr) {
LOG(ERROR) << "YARA config parser plugin has no pointer";
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
return results;
}
[fix #1390] query pack re-org This commit contains the features specified in #1390 as well as a refactoring of the general osquery configuration code. The API for the config plugins hasn't changed, although now there's a `genPack` method that config plugins can implement. If a plugin doesn't implement `genPack`, then the map<string, string> format cannot be used. The default config plugin, the filesystem plugin, now implements `genPack`, so existing query packs code will continue to work as it always has. Now many other config plugins can implement custom pack handling for what makes sense in their context. `genPacks` is not a pure virtual, so it doesn't have to be implemented in your plugin if you don't want to use it. Also, more importantly, all config plugins can use the standard inline pack format if they want to use query packs. Which is awesome. For more information, refer to #1390, the documentation and the doxygen comments included with this pull requests, as well as the following example config which is now supported, regardless of what config plugin you're using: ```json { "options": { "enable_monitor": "true" }, "packs": { "core_os_monitoring": { "version": "1.4.5", "discovery": [ "select pid from processes where name like '%osqueryd%';" ], "queries": { "kernel_modules": { "query": "SELECT name, size FROM kernel_modules;", "interval": 600 }, "system_controls": { "query": "SELECT * FROM system_controls;", "interval": 600, "snapshot": true, }, "usb_devices": { "query": "SELECT * FROM usb_devices;", "interval": 600 } } }, "osquery_internal_info": { "version": "1.4.5", "discovery": [ "select pid from processes where name like '%osqueryd%';" ], "queries": { "info": { "query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;", "interval": 60, "snapshot": true }, "registry": { "query": "SELECT * FROM osquery_registry;", "interval": 600, "snapshot": true }, "schedule": { "query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory from osquery_schedule;", "interval": 60, "snapshot": true } } } } } ``` The `osquery_packs` table was modified to remove the superfluous columns which could already have been found in `osquery_schedule`. Two more columns were added in their place, representing stats about pack's discovery query execution history. Notably, the internal API for the `osquery::Config` class has changed rather dramatically as apart of the refactoring. We think this is an improvement. While strictly adhering to the osquery config plugin interface will have avoided any compatibility errors, advanced users may notice compilation errors if they access config data directly. All internal users of the config have obviously been updated. Yet another reason to merge your code into mainline; we update it for you when we refactor!
2015-08-19 20:27:49 +00:00
std::shared_ptr<YARAConfigParserPlugin> yaraParser;
try {
yaraParser = std::dynamic_pointer_cast<YARAConfigParserPlugin>(parser);
} catch (const std::bad_cast& e) {
LOG(ERROR) << "Error casting yara config parser plugin";
return results;
}
if (yaraParser == nullptr || yaraParser.get() == nullptr) {
LOG(ERROR) << "YARA config parser plugin has no pointer";
return results;
}
auto& rules = yaraParser->rules();
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
// Store resolved paths in a vector of pairs.
// Each pair has the first element as the path to scan and the second
// element as the pattern which generated it.
std::vector<std::pair<std::string, std::string> > path_pairs;
// Expand patterns and push onto path_pairs.
for (const auto& pattern : patterns) {
std::vector<std::string> expanded_patterns;
auto status = resolveFilePattern(pattern, expanded_patterns);
if (!status.ok()) {
VLOG(1) << "Could not expand pattern properly: " << status.toString();
return results;
}
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
for (const auto& resolved : expanded_patterns) {
if (!isReadable(resolved)) {
continue;
}
path_pairs.push_back(make_pair(resolved, pattern));
}
}
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
// Collect all paths specified too.
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
for (const auto& path_string : paths) {
if (!isReadable(path_string)) {
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
continue;
}
path_pairs.push_back(make_pair(path_string, ""));
}
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
// Compile all sigfiles into a map.
for (const auto& file : sigfiles) {
// Check if this on-demand sigfile has not been used/compiled.
if (rules.count(file) == 0) {
auto path = (file[0] != '/') ? std::string("/etc/osquery/yara/") : "";
path += file;
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
YR_RULES* tmp_rules = nullptr;
auto status = compileSingleFile(path, &tmp_rules);
if (!status.ok()) {
VLOG(1) << "YARA error: " << status.toString();
} else {
rules[file] = tmp_rules;
groups.insert(file);
}
}
}
// Scan every path pair.
for (const auto& path_pair : path_pairs) {
// Scan using siggroups.
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
for (const auto& group : groups) {
if (rules.count(group) == 0) {
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
continue;
}
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
VLOG(1) << "Scanning with group: " << group;
auto status = doYARAScan(rules[group],
path_pair.first.c_str(),
path_pair.second,
results,
group,
group);
if (!status.ok()) {
VLOG(1) << "YARA error: " << status.toString();
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
}
}
}
Major YARA refactor and enhancements 1. Rename yara_matches to yara_events. 2. Add support for Config::getParser(). - This returns a ConfigPluginRef, which is the ConfigParser for the given key. - Being able to get the parser is useful because the YARAConfigParserPlugin uses it to store the compiled rules as an attribute. 3. Finish rename and use ConfigParserPlugin. - Finish the table rename to yara_events. - Use the new ConfigParserPlugin interface to parse the YARA configuration. The file_paths and signatures are stored in the ConfigParserPlugin named "yara" under the key "yara". The rules are compiled and stored as a private attribute of the same ConfigParserPlugin object. Here is an example config using this new structure: { // Description of the YARA feature. "yara": { "signatures": { // Each key is an arbitrary group name to give the signatures listed "sig_group_1": [ "/Users/wxs/foo.sig", "/Users/wxs//bar.sig" ], "sig_group_2": [ "/Users/wxs/baz.sig" ] }, "file_paths": { // Each key is a key from file_paths // The value is a list of signature groups to run when an event fires // These will be watched for and scanned when the event framework // fire off an event to yara_events table "system_binaries": [ "sig_group_1" ], "tmp": [ "sig_group_1", "sig_group_2" ] } }, // Paths to watch for filesystem events "file_paths": { "system_binaries": [ "/usr/bin/%", "/usr/sbin/%" ], "tmp": [ "/Users/wxs/tmp/%%" ] } } - Currently the signature file must be an absolute path. 3. Move common YARA code to yara_utils. - In preparation for the yara table (different from yara_events) I'm moving the common YARA code into a separate place which is shared between the two tables. 4. Add yara table. - This allows you to do things like: ```sql select * from yara where path="/bin/ls" and sigfile="/tmp/foo.sig"; select * from yara where path="/bin/ls" and sig_group="sig_group_1"; ``` - The latter will use the signature grouping from the config. 5. Check for keys not existing.
2015-04-17 20:03:43 +00:00
return results;
}
}
}