Linux执行命令监控详细实现原理和使用教程,以及相关工具的使用。
0x00 背景介绍
Linux上的HIDS需要实时对执行的命令进行监控,分析异常或入侵行为,有助于安全事件的发现和预防。为了获取执行命令,大致有如下方法:
- 遍历/proc目录,无法捕获瞬间结束的进程。
- Linux kprobes调试技术,并非所有Linux都有此特性,需要编译内核时配置。
- 修改glic库中的execve函数,但是可通过int0x80绕过glic库,这个之前360 A-TEAM一篇文章有写到过。
- 修改sys_call_table,通过LKM(loadable kernel module)实时安装和卸载监控模块,但是内核模块需要适配内核版本。
确定了Hook点之后,就可以选择Hook方案了,这时有几个选择:
在应用层:
1、在ring3通过/etc/ld.so.preload劫持系统调用
2、二次开发glibc加入监控代码(据说某产品就是这么做监控的)
3、基于调试器思想通过ptrace()主动注入
在应用层做Hook的好处是不受内核版本影响,通用性较好,而且技术难度相对较低,但是缺点更明显,因为ring3层的Hook都是针对glibc库做的监控,只要直接陷入0x80中断,就可以绕过glibc库直接调用系统调用,比如近期分析的某挖矿木马:
既然应用层的监控行不通,那就看看内核层的监控手段:
1、API Inline Hook
2、sys_call_table Hook
3、IDT Hook
4、利用LSM(Linux Security Module)
API Inline Hook以及IDT Hook操作难度较大,而且兼容性较差,利用LSM监控API虽然性能最好,但是必须编译进内核才能使用,不可以实时安装卸载,而sys_call_table的Hook相对易于操作,作为防御者也可以直接从” /boot/System.map-uname -r
”中直接获取sys_call_table地址,也可以利用LKM(loadable kernel module)技术实现实时安装卸载,所以最后选择在内核层Hook sys_call_table实现监控。
综合上面方案的优缺点,我们选择修改sys_call_table中的execve系统调用,虽然要适配内核版本,但是能100%监控执行的命令。
Linux执行命令监控是一种安全机制,它允许系统管理员跟踪和记录用户在系统上执行的所有命令。这种监控对于确保系统安全、防止滥用和进行事后分析非常重要。以下是Linux执行命令监控的详细实现原理和使用教程。
实现原理
Linux执行命令监控的实现原理主要基于以下几个方面:
-
审计系统:
Linux的审计系统(auditd)是一个强大的工具,它可以记录系统调用和关键文件的更改。通过配置审计规则,管理员可以监控特定用户的命令执行情况。 -
命令历史记录:
Linux的history
命令可以记录用户在终端会话中执行的所有命令。这个功能默认启用,并且可以通过.bash_history
文件来查看。 -
进程监控:
使用如ps
、top
、htop
等工具,可以实时监控系统上运行的进程。结合其他工具,如awk
和grep
,可以过滤出特定用户的进程。 -
日志文件:
Linux系统会生成多种日志文件,如/var/log/auth.log
记录了用户的登录和注销信息,而/var/log/secure
(在某些发行版中)记录了认证相关的事件。 -
系统调用跟踪:
通过使用如strace
这样的工具,可以监控和记录进程执行的系统调用。这对于理解命令执行的底层行为非常有用。 -
文件系统监控:
使用inotify
工具可以监控文件系统事件,如文件的创建、修改和删除。这对于跟踪命令对文件系统的影响很有帮助。
使用教程
以下是如何在Linux系统中设置和使用命令监控的教程:
1. 使用auditd监控命令执行
-
安装auditd:
sudo apt-get install auditd audispd-plugins # Debian/Ubuntu sudo yum install auditd audispd-plugins # CentOS/RedHat
-
配置审计规则:
使用auditctl
命令添加规则,例如,监控所有用户的sudo
命令:sudo auditctl -w /usr/bin/sudo -p x -k sudo_rule
这里
-w
指定要监控的文件或目录,-p x
表示监控所有执行权限,-k
用于为规则命名。 -
查看审计日志:
审计日志通常存储在/var/log/audit/audit.log
。可以使用ausearch
工具来搜索和分析日志:sudo ausearch -k sudo_rule
2. 查看命令历史记录
-
查看历史命令:
history
或者查看历史记录文件:
cat ~/.bash_history
-
配置历史记录:
可以编辑用户的.bashrc
或.bash_profile
文件来更改历史记录的行为,例如,增加历史记录的大小或自动记录命令。
3. 监控进程
-
实时监控进程:
top
或者使用
htop
,如果已安装:htop
-
过滤特定用户的进程:
ps -u username
4. 分析日志文件
- 查看认证日志:
或者使用cat /var/log/auth.log
less
或tail
进行分页查看。
5. 使用strace跟踪系统调用
- 监控特定进程:
其中strace -p pid
pid
是要监控的进程ID。
6. 监控文件系统事件
- 监控特定目录:
inotifywait -m -r /path/to/directory
-m
表示监控模式,-r
表示递归监控。
Linux执行命令监控是一个涉及多个工具和机制的复杂过程。通过合理配置和使用这些工具,系统管理员可以有效地监控和记录用户的行为,从而提高系统的安全性和可审计性。需要注意的是,监控活动应当遵守相关的隐私和法律规定,确保在合法和道德的框架内进行。
0x01 总体架构
首先sys_execve监控模块,需要替换原有的execve系统调用。在执行命令时,首先会进入监控函数,将日志通过NetLink发送到用户态分析程序(如想在此处进行命令拦截,修改代码后也是可以实现的),然后继续执行系统原生的execve函数。
0x02 获取sys_call_table地址
获取sys_call_table的数组地址,可以通过/boot目录下的System.map文件中查找。
命令如下:
cat /boot/System.map-
uname-r| grep sys_call_table
这种方式比较麻烦,在每次insmod内核模块的时候,需要将获取到的地址通过内核模块传参的方式传入。而且System.map并不是每个系统都有的,删除System.map对于系统运行无影响。
我们通过假设加偏移的方法获取到sys_call_table地址,首先假设sys_call_tale地址为sys_close,然后判断sys_call_table[__NR_close]是否等于sys_close,如果不等于则将刚才的sys_call_table偏移sizeof(void *)这么多字节,直到满足之前的判断条件,则说明找到正确的sys_call_table的地址了。
代码如下:
unsigned long **find_sys_call_table(void) {
unsigned long ptr;
unsigned long *p;
pr_err("Start foundsys_call_table.\n");
for (ptr = (unsignedlong)sys_close;
ptr < (unsignedlong)&loops_per_jiffy;
ptr += sizeof(void*)) {
p = (unsigned long*)ptr;
if (p[__NR_close] ==(unsigned long)sys_close) {
pr_err("Foundthe sys_call_table!!! __NR_close[%d] sys_close[%lx]\n"
"__NR_execve[%d] sct[__NR_execve][0x%lx]\n",
__NR_close,
(unsigned long)sys_close,
__NR_execve,
p[__NR_execve]);
return (unsignedlong **)p;
}
}
return NULL;
}
0x03 修改__NR_execve地址
即使获取到了sys_call_table也无法修改其中的值,因为sys_call_table是一个const类型,在修改时会报错。因此需要将寄存器cr0中的写保护位关掉,wp写保护的对应的bit位为0x00010000。
代码如下:
unsigned long original_cr0;
original_cr0 = read_cr0();
write_cr0(original_cr0 & ~0x00010000); #解除写保护
orig_stub_execve = (void *)(sys_call_table_ptr[__NR_execve]);
sys_call_table_ptr[__NR_execve]= (void *)monitor_stub_execve_hook;
write_cr0(original_cr0); #加上写保护
在修改sys_call_hook[__NR_execve]中的地址时,不只是保存原始的execve的地址,同时把所有原始的系统调用全部保存下载。
void *orig_sys_call_table [NR_syscalls];
for(i = 0; i < NR_syscalls - 1; i ++) {
orig_sys_call_table[i] =sys_call_table_ptr[i];
}
0x04 Execve进行栈平衡
除了execve之外的其他系统调用,基本只要自定义函数例如:my_sys_write函数,在此函数中预先执行我们的逻辑,然后再执行orig_sys_write函数,参数原模原样传入即可。但是execve不能模仿上面的写法,用以上的方法可能会导致Kernel Panic。
需要进行一下栈平衡,操作如下:
- 定义替换原始execve函数的函数monitor_stub_execve_hook
.text
.global monitor_stub_execve_hook
monitor_stub_execve_hook:
- 在执行execve监控函数之前,将原始的寄存器进行入栈操作:
pushq %rbx
pushq %rdi
pushq %rsi
pushq %rdx
pushq %rcx
pushq %rax
pushq %r8
pushq %r9
pushq %r10
pushq %r11
-
执行监控函数并Netlink上报操作:
call monitor_execve_hook
-
入栈的寄存器值进行出栈操作
pop %r11
pop %r10
pop %r9
pop %r8
pop %rax
pop %rcx
pop %rdx
pop %rsi
pop %rdi
pushq %rbx
- 执行系统的execve函数
jmp *orig_sys_call_table(, %rax, 8)
0x05 执行命令信息获取
监控执行命令,如果用户态使用的是相对路径执行,此模块也需要获取出全路径。通过getname()函数获取执行文件名,通过open_exec()和d_path()获取出执行文件全路径。通过current结构体变量获取进程pid,父进程名,ppid等信息。同时也获取运行时的环境变量中PWD,LOGIN相关的值。
最终将获取到的数据组装成字符串,用ascii码值为0x1作为分隔符,通过netlink_broadcast()发送到到用户态分析程序处理。
0x06 监控效果
在加载内核模块,在用户态执行netlink消息接收程序。然后使用相对路径执行命令./t my name is xxxx,然后查看用户态测试程序获取的数据。
0x07 版本支持及代码
支持内核版本:2.6.32, >=3.10.0
源代码路径:https://github.com/ysrc/yulong-hids/tree/master/syscall_hook
在Linux系统中,有多种工具可以用来监控执行命令,这些工具可以帮助系统管理员跟踪用户行为、审计系统操作或进行安全分析。以下是20个用于监控Linux执行命令的工具,以及它们的访问链接:
-
auditd - Linux审计守护进程
- 访问链接: https://www.linux-audit.com/
-
syslog-ng - 灵活的日志管理工具
- 访问链接: https://www.syslog-ng.com/
-
rsyslog - 用于日志处理的系统服务
- 访问链接: http://www.rsyslog.com/
-
logrotate - 管理日志文件的轮换、压缩和删除
- 访问链接: https://github.com/logrotate/logrotate
-
logwatch - 监视系统日志并生成报告
- 访问链接: https://sourceforge.net/projects/logwatch/
-
Swatch - 监视系统日志文件的变化
- 访问链接: http://swatch.sourceforge.net/
-
Glog - C++日志库,支持日志监控
- 访问链接: https://github.com/google/glog
-
Logstash - 收集、解析和丰富日志数据
- 访问链接: https://www.elastic.co/de/products/logstash
-
Filebeat - 轻量级日志文件收集器
- 访问链接: https://www.elastic.co/de/products/beats/filebeat
-
GoAccess - 实时日志分析器和交云式查看器
- 访问链接: https://goaccess.io/
-
Graylog - 强大的日志管理平台
- 访问链接: https://www.graylog.org/
-
Fluentd - 开源数据收集器
- 访问链接: https://www.fluentd.org/
-
Prometheus - 监控系统和应用程序的时间序列数据库
- 访问链接: https://prometheus.io/
-
Netdata - 性能监控和可视化工具
- 访问链接: https://www.netdata.cloud/
-
Zabbix - 企业级监控解决方案
- 访问链接: https://www.zabbix.com/
-
Nagios - 监控系统、网络和基础设施
- 访问链接: https://www.nagios.org/
-
Icinga - 监控系统,Nagios的分支
- 访问链接: https://www.icinga.com/
-
Puppet - 配置管理平台,可以用于监控配置变更
- 访问链接: https://puppet.com/
-
Chef - 自动化平台,用于管理服务器和应用程序
- 访问链接: https://www.chef.io/
-
Ansible - 自动化工具,可以用于监控和执行任务
- 访问链接: https://www.ansible.com/
请注意,上述工具的使用应遵守法律法规,并在获得授权的情况下进行。这些工具主要用于教育和安全研究目的,以提高系统的安全性。在使用这些工具时,应确保不侵犯他人的隐私和权益。