一种简单的bash审计方法
在高交互蜜罐环境中,ssh服务允许攻击者成功由ssh登录并获取到一个可进行各种操作的真实shell,同时需要记录shell中所有操作。严谨的方案是在bash源码及内核模块中做审计记录。这里给出另一种娱乐性质的方案,简单而tricky的方式达成该目标的基本功能,当然这种方案在了解的人面前很容易被绕过。
本文参考环境为Ubuntu 18.01
这里记录shell执行命令的核心是bash内建的trap命令,trap可以看作bash的信号处理,同时有一些虚拟信号,这里要使用的是DEBUG信号。trap arg DEBUG
执行后,arg命令将在每一个命令执行前被执行,同时可以从变量BASH_COMMAND中读取到将要执行的命令。参考man trap
,man bash
。
交互式bash记录命令
先看一下例子,log_command
中可以替换为其他脚本,将记录到的命令发送到远程服务器并保存。这里仅简单保存日志文件。
function log_command()
{
echo -e "\e[33m$(date +"%Y-%m-%d %H:%M:%S")\e[0m" ["\e[01;35m`whoami`\e[0m""@""\e[01;36m$(who am i | awk "{print \$2\"\"\$5}")\e[0m":"\e[01;32m`pwd`\e[0m"]# $BASH_COMMAND >> /var/log/history.log
}
unset PROMPT_COMMAND
trap 'log_command' DEBUG
试验一下
[root@GuangZhou:sbin]# source /usr/local/sbin/cli.sh
[root@GuangZhou:sbin]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Apr04 ? 00:12:43 /sbin/init
root 2 0 0 Apr04 ? 00:00:00 [kthreadd]
root 4 2 0 Apr04 ? 00:00:00 [kworker/0:0H]
root 6 2 0 Apr04 ? 00:00:00 [mm_percpu_wq]
root 7 2 0 Apr04 ? 00:01:51 [ksoftirqd/0]
root 8 2 0 Apr04 ? 00:01:57 [rcu_sched
看看输出
[root@GuangZhou:sbin]# tail -n2 /var/log/history.log
2021-05-10 17:16:27 [root@pts/0(192.168.21.254):/usr/local/sbin]# ps -ef
2021-05-10 17:16:59 [root@pts/0(192.168.21.254):/usr/local/sbin]# tail -n2 /var/log/history.log
为了让每个bash都能生效,在/etc/bashrc
文件末尾增加一行. /etc/bash_logger.sh
,这样在默认配置下每一个交互式bash都会加载新增的文件(除非通过参数指定bash不加载配置文件)。
非交互式bash记录命令
上一个例子里可以记录到交互式bash中调用的命令,那么再试一下通过bash执行的脚本文件是否可以记录到脚本文件内调用的命令,结果是无法记录。因为trap只能影响到当前bash,通过bash SCRIPT_NAME
和bash -c COMMAND
会启动一个子进程,执行非交互式bash,不会加载之前准备的配置文件。
之前说过非交互式bash会检查环境变量BASH_ENV
并尝试加载其指定的文件。因此在配置文件中再增加BASH_ENV
环境变量。
function log_command()
{
echo -e "\e[33m$(date +"%Y-%m-%d %H:%M:%S")\e[0m" ["\e[01;35m`whoami`\e[0m""@""\e[01;36m$(who am i | awk "{print \$2\"\"\$5}")\e[0m":"\e[01;32m`pwd`\e[0m"]# $BASH_COMMAND >> /var/log/history.log
}
unset PROMPT_COMMAND
export BASH_ENV=/usr/local/sbin/cli.sh
trap 'log_command' DEBUG
重启一个bash,验证一下
[root@GuangZhou:~]# cat test.sh
echo 1
echo 2
[root@GuangZhou:~]# bash test.sh
1
2
[root@GuangZhou:~]#
看看日志
2021-05-10 17:20:14 [root@pts/0(192.168.21.254):/root]# bash test.sh
2021-05-10 17:20:14 [root@pts/0(192.168.21.254):/root]# echo 1
2021-05-10 17:20:14 [root@pts/0(192.168.21.254):/root]# echo 2
2021-05-10 17:20:36 [root@pts/0(192.168.21.254):/root]# cat /var/log/history.log
可以看到没有函数内部的调用记录。想要这部分记录也很简单,在配置文件中增加一行set -o functrace
,参考man set
,man bash
白名单
经过上面的步骤,已经可以记录bash和sh调用的所有命令了,但是由于linux中大量使用shell做一些辅助工作,因此很多时候会有大量冗余的调用记录。比如执行一下man bash
,就会在日志文件中看到数十行调用记录,这里可以通过增加白名单的方式把明显无害的调用排除出记录范围。
转载请注明来源