mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-07 01:55:20 +00:00
first pass at ssh_config table (#4380)
This commit is contained in:
parent
257bcfa546
commit
19843b8253
99
osquery/tables/system/posix/ssh_configs.cpp
Normal file
99
osquery/tables/system/posix/ssh_configs.cpp
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under both the Apache 2.0 license (found in the
|
||||||
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||||
|
* in the COPYING file in the root directory of this source tree).
|
||||||
|
* You may select, at your option, one of the above-listed licenses.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/algorithm/string/trim.hpp>
|
||||||
|
|
||||||
|
#include <osquery/core.h>
|
||||||
|
#include <osquery/filesystem.h>
|
||||||
|
#include <osquery/logger.h>
|
||||||
|
#include <osquery/posix/system.h>
|
||||||
|
#include <osquery/tables.h>
|
||||||
|
|
||||||
|
#include "osquery/core/conversions.h"
|
||||||
|
#include "osquery/tables/system/system_utils.h"
|
||||||
|
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
namespace osquery {
|
||||||
|
namespace tables {
|
||||||
|
|
||||||
|
const std::string kUserSshConfig = ".ssh/config";
|
||||||
|
const std::string kSystemwideSshConfig = "/etc/ssh/ssh_config";
|
||||||
|
|
||||||
|
void genSshConfig(const std::string& uid,
|
||||||
|
const std::string& gid,
|
||||||
|
const fs::path& filepath,
|
||||||
|
QueryData& results) {
|
||||||
|
std::string ssh_config_content;
|
||||||
|
if (!forensicReadFile(filepath, ssh_config_content).ok()) {
|
||||||
|
VLOG(1) << "Cannot read ssh_config file " << filepath;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// the ssh_config file consists of a number of host or match
|
||||||
|
// blocks containing newline-separated options for each
|
||||||
|
// block; a block is defined as everything following a
|
||||||
|
// host or match keyword, until the next host or match
|
||||||
|
// keyword, else EOF
|
||||||
|
std::string block;
|
||||||
|
for (auto& line : split(ssh_config_content, "\n")) {
|
||||||
|
boost::trim(line);
|
||||||
|
boost::to_lower(line);
|
||||||
|
if (line.empty() || line[0] == '#') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (boost::starts_with(line, "host ") ||
|
||||||
|
boost::starts_with(line, "match ")) {
|
||||||
|
block = line;
|
||||||
|
} else {
|
||||||
|
Row r = {{"uid", uid},
|
||||||
|
{"block", block},
|
||||||
|
{"option", line},
|
||||||
|
{"ssh_config_file", filepath.string()}};
|
||||||
|
results.push_back(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void genSshConfigForUser(const std::string& uid,
|
||||||
|
const std::string& gid,
|
||||||
|
const std::string& directory,
|
||||||
|
QueryData& results) {
|
||||||
|
auto dropper = DropPrivileges::get();
|
||||||
|
if (!dropper->dropTo(uid, gid)) {
|
||||||
|
VLOG(1) << "Cannot drop privileges to UID " << uid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::filesystem::path ssh_config_file = directory;
|
||||||
|
ssh_config_file /= kUserSshConfig;
|
||||||
|
|
||||||
|
genSshConfig(uid, gid, ssh_config_file, results);
|
||||||
|
}
|
||||||
|
QueryData getSshConfigs(QueryContext& context) {
|
||||||
|
QueryData results;
|
||||||
|
|
||||||
|
// Iterate over each user
|
||||||
|
QueryData users = usersFromContext(context);
|
||||||
|
for (const auto& row : users) {
|
||||||
|
auto uid = row.find("uid");
|
||||||
|
auto gid = row.find("gid");
|
||||||
|
auto directory = row.find("directory");
|
||||||
|
if (uid != row.end() && gid != row.end() && directory != row.end()) {
|
||||||
|
genSshConfigForUser(uid->second, gid->second, directory->second, results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genSshConfig("0", "0", kSystemwideSshConfig, results);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
} // namespace tables
|
||||||
|
} // namespace osquery
|
19
specs/posix/ssh_configs.table
Normal file
19
specs/posix/ssh_configs.table
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
table_name("ssh_configs")
|
||||||
|
description("A table of parsed ssh_configs.")
|
||||||
|
schema([
|
||||||
|
Column("uid", BIGINT, "The local owner of the ssh_config file",
|
||||||
|
additional=True),
|
||||||
|
Column("block",TEXT,"The host or match block"),
|
||||||
|
Column("option", TEXT, "The option and value", index=True),
|
||||||
|
Column("ssh_config_file", TEXT, "Path to the ssh_config file", index=True),
|
||||||
|
ForeignKey(column="uid", table="users"),
|
||||||
|
])
|
||||||
|
attributes(user_data=True, no_pkey=True)
|
||||||
|
implementation("ssh_configs@getSshConfigs")
|
||||||
|
examples([
|
||||||
|
"select * from users join ssh_configs using (uid)",
|
||||||
|
])
|
||||||
|
fuzz_paths([
|
||||||
|
"/home",
|
||||||
|
"/Users",
|
||||||
|
])
|
Loading…
Reference in New Issue
Block a user