用户行为监控:bash history logging 攻防

Bash堪称*nix世界使用最广泛的shell,其特性之一是历史命令(history)机制。此机制主要用于为用户提供方便--少敲几下键盘, 提高工作效率。然而,被广泛讨论的是bash_history可以用作logging机制以此来监控用户的活动。此文将对上述问题进行讨论并解释为啥 logging机制在少数人面前会失效。我们将见到各种用于保护history文件的防御措施是如何不费吹灰之力或稍微费点力就被突破的。随着讨论的跟 进,突破的限制也将变得更严,但这并不代表突破起来就更困难,与之相反大部分方法都是可以不费脑子的。最后,我们将修改bash的源码来实现”无 敌”logging机制,也将看到”无敌”并不是真正的无敌。

加固bash_history

假设你所管理的系统提供shell登录功能,你的用户当中有个别及其讨人厌的家伙,于是你想监控他的活动,因为你非常怀疑他半夜三更使用你所负责保 护的CPU和系统资源作恶意行为(或是其他的,例如下毛片等)。我们暂且叫他二哥(此处原文为Bob,Bob一名在国外经常用来指代坏蛋)。

因为所有用户都是使用bash作为默认shell,你开始着手修改bash的配置文件:

第1步:使bash历史记录文件和相关文件无法被删除或修改。

二哥所做的第一件事应该是建立history到/dev/null的链接。

bob$ rm ~/.bash_history
bob$ ln -s /dev/null  ~/.bash_history

这可以通过修改历史记录文件为只能被追加来进行阻止,执行以下命令来改变其属性:

# chattr +a /home/bob/.bash_history

这是使用文件系统附加属性来指定文件只能被追加,大多数文件系统支持此功能(例如ext2/3,XFS,JFS)。在FreeBSD上可以执行:

# sappnd /home/bob/.bash_history

你还应修改shell启动相关的其他文件的这个属性:

# chattr +a /home/bob/.bash_profile
# chattr +a /home/bob/.bash_login
# chattr +a /home/bob/.profile
# chattr +a /home/bob/.bash_logout
# chattr +a /home/bob/.bashrc

前三个文件在交互式bash shell(或非交互式sehll使用–login选项)调用时被读取(在读完全局配置文件/etc/profile后)。.bashrc文件只在当 non-login交互式shell调用时被读取。这意味着当二哥已登进系统后,用以下方法自己调用一个新shell时:

bob$ bash

此时只有.bashrc文件被读取,而上面所列的前三个配置文件不会再次被读取了。

做了以上属性的修改后再来做更进一步的”加固”,一个所谓的保护措施。

第2步:配置 .bash*配置文件

所有的配置将针对.bashrc文件,因为其他三个配置文件本身会调用.bashrc,也就是说.bashrc无论如何都会被读取 (不管用户是否刚登录或是登录后手工调用bash shell)。

所以,所有修改都针对.bashrc的好处是可以防止二哥登录后手工调用新的bash shell来跳过仅在.bash_profile,.bash_login,.profile三个配置文件中生效的配置选项,另一好处是这三个文件本身都 会调用.bashrc,所以在首次登录系统时.bashrc当中的配置也会生效。

# cat >> /home/bob/.bashrc << EOF
> shopt -s histappend
> readonly PROMPT_COMMAND=”history -a”
> EOF

此处histappend选项的作用是让bash附加上最后一行$HISTSIZE给$HISTFILE文件(一般 是~/.bash_history文件),不管交互式shell何时退出。默认的,bash每次均会覆盖$HISTFILE以保证只有一个session 被保存以此来节约空间。

环境变量PROMPT_COMMAND会保存一条将被优先执行的命令,意思是说”history -a”命令将在用户执行命令前被优先执行,这将保证不管当前命令前一条是执行的什么,它将立即被追加进$HISTFILE,而不用等待整个会话结束再将历 史命令从内存记录至硬盘。

此处的readonly作用是使变量不可修改以防止被二哥覆盖掉或是直接屏蔽掉。

最后要完成的步骤是使所有与bash_history相关的环境变量都变为readonly:

readonly HISTFILE
readonly HISTFILESIZE
readonly HISTSIZE
readonly HISTCMD
readonly HISTCONTROL
readonly HISTIGNORE

第3步:禁掉系统中所有其他shell,一般包括csh,tcsh,ksh。

# chmod 750 csh
# chmod 750 tcsh
# chmod 750 ksh

这将阻止二哥把bash shell切换成其他shell。

现在,机敏点的管理员会抱怨上面的都是shit!

还有一个shell逃出了我们的掌控!在你看完以上叙述跳入浮想联翩之前,让我们来搞清一些事情。

很久很久以前… (你懂的),原本只有一个Bourne shell 或者叫sh,现如今,/bin/sh实际上是/bin/bash的一个链接。Bash在被调用时检查它是以哪个名字被调用的并以此来判断是不是调用sh, 它试图模仿历史版本的sh的行为并和POSIX标准保持一致。

如果以交互式login shell或非交互式shell带上–login选项启动,它才读取/etc/profile和~/.profile来初始化配置。如果以交互式 shell被调用,则试图解释$ENV变量,当$ENV非空则使用它的值当作默认配置并执行。我们将在本文的下一节讨论如何利用这点来秒杀bash的所有 设置。

三:攻破logging机制

现在是时候站在二哥的角度来看下所有问题了。我们将验证上面的防御是如何一步步被攻破的。在实践中的可能性是无穷进的。

以下所提及的突破bash_history logging机制的技巧只是九牛一毛。

方法1:使用Bourne shell –/bin/sh逃脱术

$ /bin/sh

调用sh会导致bash模仿如前所述的历史版本sh而不会读取与bash直接相关的任何配置文件。因此,二哥现在能够避开$HISTFILE变量了,

因为它已不再是readonly。

$ unset HISTFILE

这会使得logging机制在当前会话中直接萎掉,因为此变量控制的历史命令记录文件将会是空的。

注:也可以通过调用/bin/rbash(如果系统里存在的话)来实现相同效果,它会模仿受限版本的bash,和sh一样也是一个bash的链接,但是使用起来确实有些让人蛋疼。

方法2:让bash不加载.bashrc配置文件

可以通过以下方法实现:

$ /bin/bash –norc

这样即可禁止bash读取.bashrc从而被设置成readonly的变量变成了writeable,然后像下面这样做:

$ HISTFILE=

会清空$HISTFILE变量—>无历史记录。

四:Hacking bash-使用syslog日志接口

从以上我们很清楚地得出结论--传统的加固bash_history的方法实际上都是扯淡。然而我们却可以更向前一步的hack bash本身来减少logging机制的脆弱性并提高其隐秘性。需要注意的是即便如此也是可以被攻破的。由于bash与内核的差距导致它并不是足够的健壮 来作为一个logging设备,即便是hack了它的核心。

现在的想法是修改bash源码使用户键入的所有指令全部发送给syslog,由syslog将日志记录到/var/log目录下。我们将提供一个快速而且很黄很暴力的方法来实现这一目标--这里,哪个用户键入的哪条指令将没有差别的被对待,而这也是可以被实现的。

我们的接口的最佳放置点是parse.y文件,它由bash的yacc语法组成。当一条指令在shell中被下达时bash解释器将迅速被调用。因 此,将syslog钩子放置在解释器刚好完成它的工作前一点点,貌似是个好办法。需要修改的仅仅是增加两行代码:包含进syslog.h和设置 syslog调用。我们使用了bash-3.2的源码:

[[email protected]]$diff -E -b -c ~/bash-3.2/parse.y ~/hacked_bash/parse.y
*** ../../bash-3.2/bash-3.2/parse.y     Tue Sep 19 13:37:21 2006
— parse.y     Sat Jul 12 18:32:26 2008
***************
*** 19,24 ****
— 19,25 —-
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
%{
+ #include  #include “config.h” #include “bashtypes.h” *************** *** 1979,1984 **** — 1980,1986 —- shell_input_line_len = i;             /* == strlen (shell_input_line) */ set_line_mbstate (); +         syslog(LOG_LOCAL0 | LOG_CRIT, “%s”, shell_input_line); #if defined (HISTORY) if (remember_on_history && shell_input_line && shell_input_line[0])

上面的调用产生了一条日志消息,此消息将被syslog根据LOG_CRIT级别送到local0的设备上。要让这个东东生效则还必须要在/etc/syslog.conf配置文件中加入一条:

local0.crit                /var/log/hist.log

至此用户下达的每条指令都将躺在/var/log/hist.log里,这个日志文件一般情况下日有root用户有读权限。

要注意的是上面所提到的hack并不区分是否为不同用户的输入。要实现的话还有更多的事情需要做的。由于所有的命令都被记录下来,那么由shell脚本执行或启动bash时的配置文件执行所产生的垃圾信息也是会被记录下来的。

现在唯一剩下的问题是”上面的hack要怎样才能被攻破?”其实这相当滴简单:

—->编译或上传一个你自己的干净的bash或其他shell即可搞定。

由于上面的hack是在特定版本的基础上的所以你编译或上传的干净bash可能在他的系统上会运行失败。

五:总结

Bash 只是一个shell,并不是一个logging设备,而bash_history只是用来为用户提供点方便少敲几下键盘而已。毫不装逼的说一句所有使用它 来当监控设备的做法都是白搭。如果你是个较真的系统管理员且确实需要监控用户的活动,那就写个内核模块记录所有用户的键盘记录,并根据uid或其他参数进 行过滤。这个方法将会非常管用并且很难被攻破(只是很难不是没那可能)。

现在已经有Linux包括FreeBSD下的审计框架可供选择。在FreeBSD平台,由Robert Watson和TrustedBSD项目开发的审计框架是选择之一。

时间: 2024-10-14 21:29:26

用户行为监控:bash history logging 攻防的相关文章

系统进程管理及用户登陆监控

1.图形中如何查看进程gnome-system-monitor2.如何用命令查看进程ps        进程查看工具             -a    shell中运行的进程             -x    不在shell重运行的进程         -u    查看进程用户             -l    显示进程的详细信息             -f    完全信息full的缩写             -e    显示进程的依赖关系                  -o %c

OneAPM NI 基于旁路镜像数据的真实用户体验监控

在这个应用无处不在的时代,一次网络购物,一次网络银行交易,一次网络保险的购买,一次春运车票的购买,一次重要工作邮件的收发中出现的延时,卡顿对企业都可能意味着用户忠诚度下降,真金白银的损失. 因而感知真实用户体验(Real User Experience),将用户访问量,每个页面访问量的变化,应用的错误率,平均响应时间等指标作为网站运营的基本KPI已经是势在必行.利用真实用户体验工具对应用.网站进行性能检测和业务分析已经成为运营一个对外提供服务的应用的基础要求.真实用户体验监测(Real User

用户态监控网络接口up、down事件

网上搜索(https://blog.csdn.net/qq123386926/article/details/50695725)可以直接使用netlink现成的接口实现: #include <sys/types.h> #include <sys/socket.h> #include <asm/types.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> #include <

Linux History安全问题【保存记录防止删除】+完善Linux/UNIX审计 将每个shell命令记入日志

2011-09-27 22:11:51|  分类: rhel5_033|举报|字号 订阅 Linux利用PROMPT_COMMAND实现审计功能 这个系统审计,记录什么用户,在什么时间,做了什么操作. 然后将查到的信息记录到一个文件里. 一. 配置 1. 在/etc/profile 文件的最后,添加如下2行代码: export HISTORY_FILE=/var/log/`date ‘+%Y%m’`.log export PROMPT_COMMAND=’{ date “+%Y-%m-%d %T

编译bash实现history的syslog日志记录

摘要: 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://koumm.blog.51cto.com/703525/1763145 一.编译BASH实现bash的syslog日志记录功能 1. 本文将通过bash软件实现history记录到syslog日志的功能,并通过该方式可以实现实时的传送到了远端的日志集中服务器上,可以实现操作目志的审计功能. 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明

用日志记录Linux用户执行的每一条命令(history)

工作中,需要把用户执行的每一个命令都记录下来,并发送到日志服务器的需求,为此我做了一个简单的解决方案.这个方案会在每个用户退出登录 时把用户所执行的每一个命令都发送给日志守护进程rsyslogd,你也可通过配置“/etc/rsyslog.conf”进一步将日志发送给日志服务器 第一种方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # vi /etc/profile #设置history格式 export HISTTIMEFORMAT="[%Y-%m-%d %H:%M:%S

《学习bash》笔记--定制用户环境

1. .bash_profile..bash_logout和.bashrc文件 当用户和退出一个新的shell时,文件.bash_profile..bash_logout和.bashrc文件被bash所读取.在用户每次登陆到系统时, .bash_profile文件被读取,可以对.bash_profile文件进行编辑,但是知道退出并在此登录后,该文件才会被重新读取,你编辑 的新内容才会生效,或者使用source命令: source ./bash_profile bash允许有.bash_profi

解决CentOS 7 history命令不显示操作记录的时间和用户身份问题

centos6 中history命令显示操作命令的时间和用户身份 [[email protected] ~]# history   294  2017-01-06 16:46:48  root clear   295  2017-01-06 16:46:50  root ll   296  2017-01-06 16:46:52  root cat hostname.sh    297  2017-01-06 16:46:56  root cat nginxlog_cut.sh    298  

bash中for循环添加10个用户和删除10个用户

1. 循环添加10个用户: #!/bin/bash# for i in {1..10}; do    if id user$i &> /dev/null; then        echo "user$i exists."    else        useradd user$i        echo user$i | passwd --stdin user$i &> /dev/null        echo "add user user$i