diff --git a/osquery/tables/CMakeLists.txt b/osquery/tables/CMakeLists.txt index bd3141c6..4d886c30 100644 --- a/osquery/tables/CMakeLists.txt +++ b/osquery/tables/CMakeLists.txt @@ -48,6 +48,7 @@ ADD_OSQUERY_LIBRARY(osquery_tables networking/utils.cpp networking/etc_hosts.cpp utility/time.cpp + utility/crontab.cpp system/last.cpp system/bash_history.cpp base.h diff --git a/osquery/tables/specs/x/crontab.table b/osquery/tables/specs/x/crontab.table new file mode 100644 index 00000000..6d39625d --- /dev/null +++ b/osquery/tables/specs/x/crontab.table @@ -0,0 +1,12 @@ +table_name("crontab") + +schema([ + Column(name="minute", type="std::string"), + Column(name="hour", type="std::string"), + Column(name="day_of_month", type="std::string"), + Column(name="month", type="std::string"), + Column(name="day_of_week", type="std::string"), + Column(name="command", type="std::string"), +]) + +implementation("crontab@genCronTab") \ No newline at end of file diff --git a/osquery/tables/utility/crontab.cpp b/osquery/tables/utility/crontab.cpp new file mode 100644 index 00000000..c00f61a6 --- /dev/null +++ b/osquery/tables/utility/crontab.cpp @@ -0,0 +1,108 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#include +#include +#include +#include +#include "osquery/database.h" +#include + +using namespace std; +using namespace boost; + +using std::string; +using boost::lexical_cast; + + +namespace osquery { +namespace tables { + +const char* COL_COMMAND = "command"; +const char* COL_DAY_OF_WEEK = "day_of_week"; +const char* COL_MONTH = "month"; +const char* COL_DAY_OF_MONTH = "day_of_month"; +const char* COL_HOUR = "hour"; +const char* COL_MINUTE = "minute"; + + +std::vector getCmdOutput(const std::string& mStr) +{ + std::vector lines; + std::string result, line, chunk; + FILE* pipe{popen(mStr.c_str(), "r")}; + if (pipe == nullptr) { + return lines; + } + + // currently works only for lines shorter than 1024 characters + char buffer[1024]; + while(fgets(buffer, sizeof(buffer), pipe) != NULL) + { + chunk = buffer; + lines.push_back(chunk.substr(0, chunk.size() - 1)); + } + + pclose(pipe); + return lines; +} + + +QueryData genCronTab() { + QueryData results; + + std::vector lines = getCmdOutput("crontab -l"); + + for(std::vector::iterator itL = lines.begin(); + itL < lines.end(); ++itL) { + + Row r; + + std::vector columns; + boost::split(columns, *itL, boost::is_any_of(" \t")); + + r[COL_MINUTE] = ""; + r[COL_HOUR] = ""; + r[COL_DAY_OF_MONTH] = ""; + r[COL_MONTH] = ""; + r[COL_DAY_OF_WEEK] = ""; + r[COL_COMMAND] = ""; + + int index = 0; + for(std::vector::iterator itC = columns.begin(); + itC < columns.end(); ++itC) { + switch(index) { + case 0: + r[COL_MINUTE] = *itC; + break; + case 1: + r[COL_HOUR] = *itC; + break; + case 2: + r[COL_DAY_OF_MONTH] = *itC; + break; + case 3: + r[COL_MONTH] = *itC; + break; + case 4: + r[COL_DAY_OF_WEEK] = *itC; + break; + case 5: + r[COL_COMMAND] = *itC; + break; + default: + r[COL_COMMAND] += (' ' + *itC); + } + index++; + } + + results.push_back(r); + } + + return results; +} + +} +} + + +