IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> falco 敏感信息检测 -> 正文阅读

[系统运维]falco 敏感信息检测

falco 检测不受信任程序读取敏感文件。

?

运行方式:

./userspace/falco/falco -c ../falco.yaml -r ../rules/falco_rules.yaml

测试命令: sudo cat /etc/shadow

日志

06:07:23.678922444: Warning Sensitive file opened for reading by non-trusted program (user=<NA> user_loginuid=1000 program=cat command=cat /etc/shadow file=/etc/shadow parent=sudo gparent=bash ggparent=sshd gggparent=sshd container_id=host image=<NA>)

对应的规则在 ../rules/falco_rules.yaml

- rule: Read sensitive file untrusted
  desc: >
    an attempt to read any sensitive file (e.g. files containing user/password/authentication
    information). Exceptions are made for known trusted programs.
  condition: >
    sensitive_files and open_read
    and proc_name_exists
    and not proc.name in (user_mgmt_binaries, userexec_binaries, package_mgmt_binaries,
     cron_binaries, read_sensitive_file_binaries, shell_binaries, hids_binaries,
     vpn_binaries, mail_config_binaries, nomachine_binaries, sshkit_script_binaries,
     in.proftpd, mandb, salt-minion, postgres_mgmt_binaries,
     google_oslogin_
     )
    and not cmp_cp_by_passwd
    and not ansible_running_python
    and not run_by_qualys
    and not run_by_chef
    and not run_by_google_accounts_daemon
    and not user_read_sensitive_file_conditions
    and not mandb_postinst
    and not perl_running_plesk
    and not perl_running_updmap
    and not veritas_driver_script
    and not perl_running_centrifydc
    and not runuser_reading_pam
    and not linux_bench_reading_etc_shadow
    and not user_known_read_sensitive_files_activities
    and not user_read_sensitive_file_containers
  output: >
    Sensitive file opened for reading by non-trusted program (user=%user.name user_loginuid=%user.loginuid program=%proc.name
    command=%proc.cmdline file=%fd.name parent=%proc.pname gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)
  priority: WARNING
  tags: [filesystem, mitre_credential_access, mitre_discovery]

这个对应上面的日志:

首先是:

priority: WARNING

然后是

 output: >
    Sensitive file opened for reading by non-trusted program (user=%user.name user_loginuid=%user.loginuid program=%proc.name
    command=%proc.cmdline file=%fd.name parent=%proc.pname gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%

规则比较长。首先是rule : 规则名,desc:规则描述,condition:匹配条件,output:满足条件时的输出信息,priority:优先级,tags:具体含义还没搞懂。

规则对应数据结构为:

	/*!
		\brief Represents infos about a rule 
	*/
	struct rule_info
	{
		context ctx;
		size_t index;
		size_t visibility;
		std::string name;
		std::string cond;
		std::string source;
		std::string desc;
		std::string output;
		std::set<std::string> tags;
		std::vector<rule_exception_info> exceptions;
		falco_common::priority_type priority;
		bool enabled;
		bool warn_evttypes;
		bool skip_if_unknown_filter;
	};

如果在../falco.yaml中的priority配置比WARNING小,则这条日志不会打印出来。因为,其表示系统的最低优先级,比如Error。

具体定义如下:

static vector<string> priority_names = {
	"Emergency",
	"Alert",
	"Critical",
	"Error",
	"Warning",
	"Notice",
	"Informational",
	"Debug"
};

优先级配置代码分析:


void falco_configuration::init(string conf_filename, const vector<string> &cmdline_options)
{
	string m_config_file = conf_filename;
	m_config = new yaml_configuration();
	try
	{
		m_config->load_from_file(m_config_file);//解析../falco.yaml文件
	}
	catch(const std::exception& e)
	{
		std::cerr << "Cannot read config file (" + m_config_file + "): " + e.what() + "\n";
		throw e;
	}


......

	string priority = m_config->get_scalar<string>("priority", "debug");//优先级默认值
	if (!falco_common::parse_priority(priority, m_min_priority))//优先级配置解析,结果保存在m_min_priority属性中
	{
		throw logic_error("Unknown priority \"" + priority + "\"--must be one of emergency, alert, critical, error, warning, notice, informational, debug");
	}

......
}

我们可以做个实验,比如在配置文件中写入错误优先级:

priority: debug1

运行报错:

?可以看到提示错误与上面的配置吻合(部分日志是我加的调试)。

接着加载规则,

application::load_rules_files=>falco_engine::load_rules_file=>falco_engine::load_rules=>rule_reader::load=>read_item


static void read_item(
		rule_loader::configuration& cfg,
		rule_loader& loader,
		const YAML::Node& item,
		const rule_loader::context& ctx)
{
......
	else if(item["rule"].IsDefined())//是否是规则
	{
		rule_loader::rule_info v;
		v.ctx = ctx;
		bool append = false;
		v.enabled = true;
		v.warn_evttypes = true;
		v.skip_if_unknown_filter = false;
		THROW(!decode_val(item["rule"], v.name) || v.name.empty(),
			"Rule name is empty");
		if(decode_val(item["append"], append) && append)
		{
			decode_val(item["condition"], v.cond);
			if (item["exceptions"].IsDefined())
			{
				read_rule_exceptions(item["exceptions"], v);
			}
			loader.append(cfg, v);
		}
		else
		{
			string priority;//优先级处理
			bool has_enabled = decode_val(item["enabled"], v.enabled);
			bool has_defs = decode_val(item["condition"], v.cond)
					&& decode_val(item["output"], v.output)
					&& decode_val(item["desc"], v.desc)
					&& decode_val(item["priority"], priority);
			if (!has_defs)//检查规则的合法性,规则必须存在'condition', 'output', 'desc', and 'priority'
			{
				THROW(!has_enabled, "Rule must have properties 'condition', 'output', 'desc', and 'priority'");
				loader.enable(cfg, v);
			}
			else//规则合法
			{
				v.output = trim(v.output);
				v.source = falco_common::syscall_source;
				THROW(!falco_common::parse_priority(priority, v.priority),
					"Invalid priority");//和之前一样,解析规则的优先级
				decode_val(item["source"], v.source);
				decode_val(item["warn_evttypes"], v.warn_evttypes);
				decode_val(item["skip-if-unknown-filter"], v.skip_if_unknown_filter);
				decode_seq(item["tags"], v.tags);
				if (item["exceptions"].IsDefined())
				{
					read_rule_exceptions(item["exceptions"], v);
				}
				loader.define(cfg, v);//处理规则,下面接着看
			}
		}
	}
	else
	{
		cfg.warnings.push_back("Unknown top level object");
	}
}

application::load_rules_files=>falco_engine::load_rules_file=>falco_engine::load_rules=>rule_reader::load=>read_item=>rule_loader::define

void rule_loader::define(configuration& cfg, rule_info& info)
{
	if (!cfg.engine->is_source_valid(info.source))
	{
		cfg.warnings.push_back("Rule " + info.name
			+ ": warning (unknown-source): unknown source "
			+ info.source + ", skipping");
		return;
	}

	auto prev = m_macro_infos.at(info.name);
	THROW(prev && prev->source != info.source,
		"Rule " + info.name + " has been re-defined with a different source");

	for (auto &ex : info.exceptions)
	{
		THROW(!ex.fields.is_valid(), "Rule exception item "
			+ ex.name + ": must have fields property with a list of fields");
		validate_exception_info(cfg, ex, info.source);
	}

	define_info(m_rule_infos, info, m_cur_index++);//将规则对象保存在m_rule_infos数组中
}

解析完之后,我们要去编译规则。规则的优先级检查就在此处进行。继续看代码:

application::load_rules_files=>falco_engine::load_rules_file=>falco_engine::load_rules=>rule_loader::compile

bool rule_loader::compile(configuration& cfg, indexed_vector<falco_rule>& out)
{
	indexed_vector<list_info> lists;
	indexed_vector<macro_info> macros;

	// expand all lists, macros, and rules
	try
	{
		compile_list_infos(cfg, lists);
		compile_macros_infos(cfg, lists, macros);
		compile_rule_infos(cfg, lists, macros, out);
	}
	catch (exception& e)
	{
		cfg.errors.push_back(e.what());
		return false;
	}

	// print info on any dangling lists or macros that were not used anywhere
	for (auto &m : macros)
	{
		if (!m.used)
		{
			cfg.warnings.push_back("macro " + m.name
				+ " not referred to by any rule/macro");
		}
	}
	for (auto &l : lists)
	{
		if (!l.used)
		{
			cfg.warnings.push_back("list " + l.name
				+ " not referred to by any rule/macro/list");
		}
	}
	return true;
}

application::load_rules_files=>falco_engine::load_rules_file=>falco_engine::load_rules=>rule_loader::compile=>?rule_loader::compile_rule_infos

void rule_loader::compile_rule_infos(
	configuration& cfg,
	indexed_vector<list_info>& lists,
	indexed_vector<macro_info>& macros,
	indexed_vector<falco_rule>& out)
{
	string err, condition;
	set<string> warn_codes;
	filter_warning_resolver warn_resolver;
	for (auto &r : m_rule_infos)//遍历之前加载的规则数组
	{
		try
		{
			// skip the rule if below the minimum priority
			if (r.priority > cfg.min_priority)//优先级检查
			{
				continue;
			}
        ......
	}
}

很明显cfg.min_priority不是之前解析的配置文件的那个那个字段,那是在哪里传递过来的呢?继续往下看:

application::load_rules_files=>falco_engine::load_rules_file=>falco_engine::load_rules

void falco_engine::load_rules(const string &rules_content, bool verbose, bool all_events, uint64_t &required_engine_version)
{
	rule_loader::configuration cfg(rules_content);
	cfg.engine = this;
	cfg.min_priority = m_min_priority;//此处赋值的
	cfg.output_extra = m_extra;
	cfg.replace_output_container_info = m_replace_container_info;
......
}

还是对不上之前的那个地方是falco_configuration::m_min_priority,这里是falco_engine::m_min_priority。这是怎么关联的呢?在application::init_falco_engine函数的最后将该值传递给了falco_engine::m_min_priority

application::run_result application::init_falco_engine()
{
......
	m_state->engine->set_min_priority(m_state->config->m_min_priority);

	return ret;

application::init_falco_engine=>falco_engine::set_min_priority

void falco_engine::set_min_priority(falco_common::priority_type priority)
{
	m_min_priority = priority;
}

这样就对应上了。通过了优先级检查的规则会保存在falco_engine::m_rules中。

如果我们想看是否真的符合前面的预期,可以做如下操作。

运行时加上如下参数?-l 'Read sensitive file untrusted',表示打印某条规则的描述信息。

不存在,并且程序挂了。Falco查询某条规则时,未做判空。

void falco_engine::describe_rule(string *rule)
{
	static const char* rule_fmt = "%-50s %s\n";
	fprintf(stdout, rule_fmt, "Rule", "Description");
	fprintf(stdout, rule_fmt, "----",  "-----------");
	if (!rule)
	{
		for (auto &r : m_rules)
		{
			auto str = falco::utils::wrap_text(r.description, 51, 110) + "\n";
			fprintf(stdout, rule_fmt, r.name.c_str(), str.c_str());
		}
	}
	else
	{
		auto r = m_rules.at(*rule);//此处可能会返回为空,
		auto str = falco::utils::wrap_text(r->description, 51, 110) + "\n";//这里没有检查r是否为空直接操作。导致程序挂了
		fprintf(stdout, rule_fmt, r->name.c_str(), str.c_str());
	}

}

?我们改成

priority: debug

继续执行:

?查询到了该规则的信息。

具体代码在application::load_rules_files函数的最后几行。

。。。。。。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-07 11:29:31  更:2022-05-07 11:30:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 17:32:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码