Skip to content

Commit

Permalink
macos: automating audit rules install (#6447)
Browse files Browse the repository at this point in the history
  • Loading branch information
npamnani-uptycs authored May 25, 2020
1 parent b64a63f commit 6c75b04
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 23 deletions.
21 changes: 21 additions & 0 deletions osquery/events/audit_flags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,30 @@ FLAG(bool,
true,
"Disable receiving events from the audit subsystem");

/// Control the audit subsystem by allowing subscriptions to apply rules.
FLAG(bool,
audit_allow_config,
false,
"Allow the audit publisher to change auditing configuration");

FLAG(bool,
audit_allow_sockets,
false,
"Allow the audit publisher to install socket-related rules");

FLAG(bool,
audit_allow_process_events,
true,
"Allow the audit publisher to install process-related rules");

FLAG(bool,
audit_allow_user_events,
true,
"Allow the audit publisher to install user-related rules");

FLAG(bool,
audit_allow_fim_events,
false,
"Allow the audit publisher to install filesystem-related rules");

} // namespace osquery
97 changes: 92 additions & 5 deletions osquery/events/darwin/openbsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
*/

#include <bsm/libbsm.h>
#include <security/audit/audit_ioctl.h>
#include <sys/ioctl.h>

#include <osquery/flags.h>
#include <osquery/logger.h>
Expand All @@ -16,20 +18,105 @@

namespace osquery {

const int kQLimit = 512;

DECLARE_bool(disable_audit);
DECLARE_bool(audit_allow_config);
DECLARE_bool(audit_allow_process_events);
DECLARE_bool(audit_allow_sockets);
DECLARE_bool(audit_allow_user_events);
DECLARE_bool(audit_allow_fim_events);

REGISTER(OpenBSMEventPublisher, "event_publisher", "openbsm");

Status OpenBSMEventPublisher::configureAuditPipe() {
auto au_pipe = audit_pipe_;
auto au_fd = fileno(au_pipe);
int pr_sel_mode = AUDITPIPE_PRESELECT_MODE_LOCAL;

audit_pipe_ = nullptr;

if (ioctl(au_fd, AUDITPIPE_SET_PRESELECT_MODE, &pr_sel_mode) == -1) {
LOG(WARNING) << "The auditpipe:ioctl AUDITPIPE_SET_PRESELECT_MODE failed";
fclose(au_pipe);
return Status::failure("Failed to set AUDITPIPE_SET_PRESELECT_MODE");
}

if (ioctl(au_fd, AUDITPIPE_SET_QLIMIT, &kQLimit) == -1) {
LOG(INFO) << "The auditpipe:ioctl AUDITPIPE_SET_QLIMIT failed";
}

au_mask_t pr_flags = {0, 0};
std::vector<std::string> ev_classes;

if (true == FLAGS_audit_allow_process_events) {
// capture process events
ev_classes.push_back("pc");
}

if (true == FLAGS_audit_allow_sockets) {
// capture network events
ev_classes.push_back("nt");
}

if (true == FLAGS_audit_allow_user_events) {
// capture user (login, autherization etc...) events
ev_classes.push_back("lo");
ev_classes.push_back("aa");
ev_classes.push_back("ad");
}

if (true == FLAGS_audit_allow_fim_events) {
// capture file events
ev_classes.push_back("fc");
ev_classes.push_back("fd");
ev_classes.push_back("fw");
ev_classes.push_back("fr");
ev_classes.push_back("fa");
ev_classes.push_back("fm");
}

struct au_class_ent* ace = nullptr;
while ((ace = getauclassent()) != nullptr) {
for (auto& cl : ev_classes) {
if (cl == ace->ac_name) {
ADD_TO_MASK(&pr_flags, ace->ac_class, AU_PRS_BOTH);
break;
}
}
}
endauclass();

au_mask_t na_pr_flags = pr_flags;

if (ioctl(au_fd, AUDITPIPE_SET_PRESELECT_FLAGS, &pr_flags) == -1) {
LOG(WARNING) << "The auditpipe:ioctl AUDITPIPE_SET_PRESELECT_FLAGS failed";
fclose(au_pipe);
return Status::failure("Failed to set AUDITPIPE_SET_PRESELECT_FLAGS");
}

if (ioctl(au_fd, AUDITPIPE_SET_PRESELECT_NAFLAGS, &na_pr_flags) == -1) {
LOG(WARNING)
<< "The auditpipe:ioctl AUDITPIPE_SET_PRESELECT_NAFLAGS failed";
fclose(au_pipe);
return Status::failure("Failed to set AUDITPIPE_SET_PRESELECT_NAFLAGS");
}

audit_pipe_ = au_pipe;
return Status::success();
}

Status OpenBSMEventPublisher::setUp() {
if (FLAGS_disable_audit) {
return Status(1, "Publisher disabled via configuration");
return Status::failure("Publisher disabled via configuration");
}
audit_pipe_ = fopen("/dev/auditpipe", "r");
if (audit_pipe_ == nullptr) {
LOG(WARNING) << "The auditpipe couldn't be opened.";
return Status(1, "Could not open OpenBSM pipe");
return Status::failure("Could not open OpenBSM pipe");
}
return Status(0);

return FLAGS_audit_allow_config ? configureAuditPipe() : Status::success();
}

void OpenBSMEventPublisher::configure() {}
Expand All @@ -43,7 +130,7 @@ void OpenBSMEventPublisher::tearDown() {

Status OpenBSMEventPublisher::run() {
if (audit_pipe_ == nullptr) {
return Status(1, "No open audit_pipe");
return Status::failure("No open audit_pipe");
}
tokenstr_t tok;
auto reclen = 0;
Expand Down Expand Up @@ -88,7 +175,7 @@ Status OpenBSMEventPublisher::run() {
tokens.clear();
event_id = 0;
}
return Status(0);
return Status::success();
}

bool OpenBSMEventPublisher::shouldFire(const OpenBSMSubscriptionContextRef& mc,
Expand Down
2 changes: 2 additions & 0 deletions osquery/events/darwin/openbsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,7 @@ class OpenBSMEventPublisher
/// Apply normal subscription to event matching logic.
bool shouldFire(const OpenBSMSubscriptionContextRef& mc,
const OpenBSMEventContextRef& ec) const override;

Status configureAuditPipe();
};
} // namespace osquery
7 changes: 1 addition & 6 deletions osquery/events/linux/auditdnetlink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ FLAG(bool, audit_persist, true, "Attempt to retain control of audit");
/// Audit debugger helper
HIDDEN_FLAG(bool, audit_debug, false, "Debug Linux audit messages");

/// Control the audit subsystem by allowing subscriptions to apply rules.
FLAG(bool,
audit_allow_config,
false,
"Allow the audit publisher to change auditing configuration");

/// Always uninstall all the audit rules that osquery uses when exiting
FLAG(bool,
audit_force_unconfigure,
Expand All @@ -60,6 +54,7 @@ FLAG(int32, audit_backlog_wait_time, 0, "The audit backlog wait time");
FLAG(int32, audit_backlog_limit, 4096, "The audit backlog limit");

// External flags; they are used to determine which rules need to be installed
DECLARE_bool(audit_allow_config);
DECLARE_bool(audit_allow_fim_events);
DECLARE_bool(audit_allow_process_events);
DECLARE_bool(audit_allow_fork_process_events);
Expand Down
5 changes: 1 addition & 4 deletions osquery/tables/events/linux/process_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ const std::unordered_map<int, std::string> kSyscallNameMap = {
{__NR_clone, "clone"}};
}

FLAG(bool,
audit_allow_process_events,
true,
"Allow the audit publisher to install process event monitoring rules");
DECLARE_bool(audit_allow_process_events);

FLAG(bool,
audit_allow_fork_process_events,
Expand Down
5 changes: 1 addition & 4 deletions osquery/tables/events/linux/process_file_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ namespace boostfs = boost::filesystem;
namespace osquery {

// Recommended configuration is just --audit_allow_fim_events=true
FLAG(bool,
audit_allow_fim_events,
false,
"Allow the audit publisher to install file event monitoring rules");
DECLARE_bool(audit_allow_fim_events);

HIDDEN_FLAG(bool,
audit_show_partial_fim_events,
Expand Down
5 changes: 1 addition & 4 deletions osquery/tables/events/linux/user_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@

namespace osquery {

FLAG(bool,
audit_allow_user_events,
true,
"Allow the audit publisher to install user events-related rules");
DECLARE_bool(audit_allow_user_events);

class UserEventSubscriber final : public EventSubscriber<AuditEventPublisher> {
public:
Expand Down

0 comments on commit 6c75b04

Please sign in to comment.